From: gmungoc Date: Thu, 5 Mar 2015 13:50:58 +0000 (+0000) Subject: Merge branch 'develop' into features/JAL-845splitPaneMergeDevelop X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=286715d8408510556366a454a748daf8f60444f1;hp=1718e104b60584336348531e51c8121d69ff6416;p=jalview.git Merge branch 'develop' into features/JAL-845splitPaneMergeDevelop Conflicts: src/jalview/datamodel/SequenceGroup.java --- diff --git a/.classpath b/.classpath index c110217..c3e70c0 100644 --- a/.classpath +++ b/.classpath @@ -51,10 +51,11 @@ - + + diff --git a/help/html/features/multipleViews.html b/help/html/features/multipleViews.html index b1ccf4b..725f9d0 100644 --- a/help/html/features/multipleViews.html +++ b/help/html/features/multipleViews.html @@ -47,8 +47,8 @@ something more meaningful.

as tabs within a single alignment window. They can be viewed simultanously by pressing X (or via "View→Expand") to expand each view into its own linked alignment window. Expanded views -are gathered back into into a single tabbed alignment window by pressing -G, or by selecting "View→Gather"). +are gathered back into a single tabbed alignment window by pressing +G, or by selecting "View→Gather".

Hidden Sequence Representatives and Multiple Views

diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 2e37e06..b12d163 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -216,6 +216,7 @@ label.none = None label.above_identity_threshold = Above Identity Threshold label.show_sequence_features = Show Sequence Features label.nucleotide = Nucleotide +label.protein = Protein label.to_new_alignment = To New Alignment label.to_this_alignment = Add To This Alignment label.apply_colour_to_all_groups = Apply Colour To All Groups @@ -233,9 +234,13 @@ label.all_columns = All Columns label.all_sequences = All Sequences label.selected_columns = Selected Columns label.selected_sequences = Selected Sequences +label.except_selected_sequences = All except selected sequences label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H) label.selected_region = Selected Region label.all_sequences_columns = All Sequences and Columns +label.hide_insertions = Hide columns gapped for selection +label.hide_selected_annotations = Hide selected annotations +label.show_selected_annotations = Show selected annotations label.group_consensus = Group Consensus label.group_conservation = Group Conservation label.show_consensus_histogram = Show Consensus Histogram @@ -382,6 +387,7 @@ label.automatically_associate_pdb_files_with_sequences_same_name = Do you want t label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name label.ignore_unmatched_dropped_files_info = Do you want to ignore the {0} files whose names did not match any sequence IDs ? label.ignore_unmatched_dropped_files = Ignore unmatched dropped files? +label.view_name_original = Original label.enter_view_name = Enter View Name label.enter_label = Enter label label.enter_label_for_the_structure = Enter a label for the structure? @@ -480,8 +486,6 @@ label.load_associated_tree = Load Associated Tree ... label.load_features_annotations = Load Features/Annotations ... label.export_features = Export Features ... label.export_annotations = Export Annotations ... -label.jalview_copy = Copy (Jalview Only) -label.jalview_cut = Cut (Jalview Only) label.to_upper_case = To Upper Case label.to_lower_case = To Lower Case label.toggle_case = Toggle Case @@ -576,7 +580,8 @@ label.database_references = Database References label.share_selection_across_views = Share selection across views label.scroll_highlighted_regions = Scroll to highlighted regions label.gap_symbol = Gap Symbol -label.alignment_colour = Alignment Colour +label.prot_alignment_colour = Protein Alignment Colour +label.nuc_alignment_colour = Nucleotide Alignment Colour label.address = Address label.port = Port label.default_browser_unix = Default Browser (Unix) @@ -689,12 +694,15 @@ label.save_png_image = Save As PNG Image label.load_tree_for_sequence_set = Load a tree for this sequence set label.export_image = Export Image label.vamsas_store = VAMSAS store -label.translate_cDNA = Translate cDNA +label.translate_cDNA = Translate as cDNA +label.linked_view_title = Linked cDNA and protein view +label.align = Align label.extract_scores = Extract Scores label.get_cross_refs = Get Cross References label.sort_alignment_new_tree = Sort Alignment With New Tree label.add_sequences = Add Sequences label.new_window = New Window +label.split_window = Split Window label.refresh_available_sources = Refresh Available Sources label.use_registry = Use Registry label.add_local_source = Add Local Source @@ -734,6 +742,7 @@ label.paste_new_window = Paste To New Window label.settings_for_param = Settings for {0} label.view_params = View {0} label.select_all_views = Select all views +label.all_views = All Views label.align_sequences_to_existing_alignment = Align sequences to an existing alignment label.realign_with_params = Realign with {0} label.calcname_with_default_settings = {0} with Defaults @@ -1178,6 +1187,13 @@ label.show_logo = Show Logo label.normalise_logo = Normalise Logo label.no_colour_selection_in_scheme = Please, make a colour selection before to apply colour scheme label.no_colour_selection_warn = Error saving colour scheme +label.open_split_window? = Would you like to open as a split window, with cDNA and protein linked? +label.open_split_window = Open split window +label.no_mappings = No mappings found +label.mapping_failed = No sequence mapping could be made between the alignments.
A mapping requires sequence names to match, and equivalent sequence lengths. +action.no = No +action.yes = Yes +label.for = for label.select_by_annotation = Select By Annotation action.select_by_annotation = Select by Annotation... label.threshold_filter = Threshold Filter @@ -1192,3 +1208,4 @@ label.search_filter = Search Filter label.display_name = Display Label label.description = Description label.include_description= Include Description +label.start_jalview = Start Jalview diff --git a/schemas/jalview.xsd b/schemas/jalview.xsd index 27f952d..047353c 100755 --- a/schemas/jalview.xsd +++ b/schemas/jalview.xsd @@ -359,12 +359,11 @@ type="xs:boolean" use="optional" default="true" /> - + - - + @@ -388,6 +387,14 @@ + + + + The viewport id of this viewport's (cdna/protein) coding complement, if any + + + atoms) { if (!seqColoursReady) { return; } - - if (highlightRes != null && highlightRes.contains((atomIndex - 1) + "")) + for (AtomSpec atom : atoms) { - return; + int atomIndex = atom.getAtomIndex(); + + if (highlightRes != null + && highlightRes.contains((atomIndex - 1) + "")) + { + continue; + } + + highlightAtom(atomIndex); } + redrawneeded = true; + repaint(); + } + + /** + * @param atomIndex + */ + protected void highlightAtom(int atomIndex) + { int index = -1; Bond tmpBond; for (index = 0; index < mainchain.bonds.size(); index++) @@ -1178,9 +1218,6 @@ public class AppletPDBCanvas extends Panel implements MouseListener, break; } } - - redrawneeded = true; - repaint(); } public Color getColour(int atomIndex, int pdbResNum, String chain, diff --git a/src/MCview/Atom.java b/src/MCview/Atom.java index 9254fd8..fdca7c2 100755 --- a/src/MCview/Atom.java +++ b/src/MCview/Atom.java @@ -20,7 +20,7 @@ */ package MCview; -import java.awt.*; +import java.awt.Color; public class Atom { @@ -77,16 +77,16 @@ public class Atom chain = str.substring(21, 22); resNumber = Integer.parseInt(str.substring(22, 26).trim()); - resNumIns = str.substring(22, 27); + resNumIns = str.substring(22, 27).trim(); insCode = str.substring(26, 27).charAt(0); - this.x = (float) (new Float(str.substring(30, 38).trim()).floatValue()); - this.y = (float) (new Float(str.substring(38, 46).trim()).floatValue()); - this.z = (float) (new Float(str.substring(47, 55).trim()).floatValue()); + this.x = (new Float(str.substring(30, 38).trim()).floatValue()); + this.y = (new Float(str.substring(38, 46).trim()).floatValue()); + this.z = (new Float(str.substring(47, 55).trim()).floatValue()); // optional entries - see JAL-730 String tm = str.substring(54, 60).trim(); if (tm.length() > 0) { - occupancy = (float) (new Float(tm)).floatValue(); + occupancy = (new Float(tm)).floatValue(); } else { @@ -96,7 +96,7 @@ public class Atom tm = str.substring(60, 66).trim(); if (tm.length() > 0) { - tfactor = (float) (new Float(tm).floatValue()); + tfactor = (new Float(tm).floatValue()); } else { diff --git a/src/MCview/PDBCanvas.java b/src/MCview/PDBCanvas.java index 4fd7a35..f189f0a 100644 --- a/src/MCview/PDBCanvas.java +++ b/src/MCview/PDBCanvas.java @@ -20,18 +20,37 @@ */ package MCview; -import java.io.*; -import java.util.*; - +import jalview.analysis.AlignSeq; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignmentPanel; +import jalview.gui.FeatureRenderer; +import jalview.gui.SequenceRenderer; +import jalview.structure.AtomSpec; +import jalview.structure.StructureListener; +import jalview.structure.StructureMapping; +import jalview.structure.StructureSelectionManager; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import jalview.analysis.*; -import jalview.datamodel.*; -import jalview.gui.*; -import jalview.structure.*; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.io.PrintStream; +import java.util.List; +import java.util.Vector; + +import javax.swing.JPanel; +import javax.swing.ToolTipManager; public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListener, StructureListener @@ -134,7 +153,9 @@ public class PDBCanvas extends JPanel implements MouseListener, pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol); if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE)) + { pdbentry.setFile("INLINE" + pdb.id); + } } catch (Exception ex) { @@ -167,17 +188,17 @@ public class PDBCanvas extends JPanel implements MouseListener, { mappingDetails.append("\n\nPDB Sequence is :\nSequence = " - + ((PDBChain) pdb.chains.elementAt(i)).sequence + + pdb.chains.elementAt(i).sequence .getSequenceAsString()); mappingDetails.append("\nNo of residues = " - + ((PDBChain) pdb.chains.elementAt(i)).residues.size() + + pdb.chains.elementAt(i).residues.size() + "\n\n"); // Now lets compare the sequences to get // the start and end points. // Align the sequence to the pdb AlignSeq as = new AlignSeq(sequence, - ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep"); + pdb.chains.elementAt(i).sequence, "pep"); as.calcScoreMatrix(); as.traceAlignment(); PrintStream ps = new PrintStream(System.out) @@ -210,7 +231,7 @@ public class PDBCanvas extends JPanel implements MouseListener, mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend); } - mainchain = (PDBChain) pdb.chains.elementAt(maxchain); + mainchain = pdb.chains.elementAt(maxchain); mainchain.pdbstart = pdbstart; mainchain.pdbend = pdbend; @@ -254,9 +275,9 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) + if (pdb.chains.elementAt(ii).isVisible) { - Vector tmp = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector tmp = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < tmp.size(); i++) { @@ -286,9 +307,9 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) + if (pdb.chains.elementAt(ii).isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -362,9 +383,9 @@ public class PDBCanvas extends JPanel implements MouseListener, * System.out.println("zmax " + max[2] + " min " + min[2]); */ - width[0] = (float) Math.abs(max[0] - min[0]); - width[1] = (float) Math.abs(max[1] - min[1]); - width[2] = (float) Math.abs(max[2] - min[2]); + width[0] = Math.abs(max[0] - min[0]); + width[1] = Math.abs(max[1] - min[1]); + width[2] = Math.abs(max[2] - min[2]); maxwidth = width[0]; @@ -421,9 +442,9 @@ public class PDBCanvas extends JPanel implements MouseListener, // Find centre coordinate for (int ii = 0; ii < pdb.chains.size(); ii++) { - if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) + if (pdb.chains.elementAt(ii).isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; bsize += bonds.size(); @@ -537,7 +558,7 @@ public class PDBCanvas extends JPanel implements MouseListener, { for (int ii = 0; ii < pdb.chains.size(); ii++) { - chain = (PDBChain) pdb.chains.elementAt(ii); + chain = pdb.chains.elementAt(ii); for (int i = 0; i < chain.bonds.size(); i++) { @@ -751,7 +772,7 @@ public class PDBCanvas extends JPanel implements MouseListener, repaint(); if (foundchain != -1) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain); + PDBChain chain = pdb.chains.elementAt(foundchain); if (chain == mainchain) { if (fatom.alignmentMapping != -1) @@ -797,7 +818,7 @@ public class PDBCanvas extends JPanel implements MouseListener, PDBChain chain = null; if (foundchain != -1) { - chain = (PDBChain) pdb.chains.elementAt(foundchain); + chain = pdb.chains.elementAt(foundchain); if (chain == mainchain) { mouseOverStructure(fatom.resNumber, chain.id); @@ -840,18 +861,18 @@ public class PDBCanvas extends JPanel implements MouseListener, if ((evt.getModifiers() & Event.META_MASK) != 0) { - objmat.rotatez((float) ((mx - omx))); + objmat.rotatez(((mx - omx))); } else { - objmat.rotatex((float) ((my - omy))); - objmat.rotatey((float) ((omx - mx))); + objmat.rotatex(((my - omy))); + objmat.rotatey(((omx - mx))); } // Alter the bonds for (int ii = 0; ii < pdb.chains.size(); ii++) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -892,11 +913,11 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(ii); + PDBChain chain = pdb.chains.elementAt(ii); if (chain.isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -948,13 +969,13 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(ii); + PDBChain chain = pdb.chains.elementAt(ii); int truex; Bond tmpBond = null; if (chain.isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -995,7 +1016,7 @@ public class PDBCanvas extends JPanel implements MouseListener, if (fatom != null) // )&& chain.ds != null) { - chain = (PDBChain) pdb.chains.elementAt(foundchain); + chain = pdb.chains.elementAt(foundchain); } } @@ -1060,7 +1081,7 @@ public class PDBCanvas extends JPanel implements MouseListener, { for (int ii = 0; ii < pdb.chains.size(); ii++) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(ii); + PDBChain chain = pdb.chains.elementAt(ii); chain.isVisible = b; } mainchain.isVisible = true; @@ -1081,7 +1102,9 @@ public class PDBCanvas extends JPanel implements MouseListener, public void mouseOverStructure(int pdbResNum, String chain) { if (lastMessage == null || !lastMessage.equals(pdbResNum + chain)) + { ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile()); + } lastMessage = pdbResNum + chain; } @@ -1090,19 +1113,42 @@ public class PDBCanvas extends JPanel implements MouseListener, StringBuffer eval = new StringBuffer(); - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbfile) + /** + * Highlight the specified atoms in the structure. + * + * @param atoms + */ + @Override + public void highlightAtoms(List atoms) { if (!seqColoursReady) { return; } - if (highlightRes != null && highlightRes.contains((atomIndex - 1) + "")) + for (AtomSpec atom : atoms) { - return; + int atomIndex = atom.getAtomIndex(); + if (highlightRes != null + && highlightRes.contains((atomIndex - 1) + "")) + { + continue; + } + + highlightAtom(atomIndex); } + redrawneeded = true; + repaint(); + } + + /** + * Highlight the atom at the specified index. + * + * @param atomIndex + */ + protected void highlightAtom(int atomIndex) + { int index = -1; Bond tmpBond; for (index = 0; index < mainchain.bonds.size(); index++) @@ -1138,9 +1184,6 @@ public class PDBCanvas extends JPanel implements MouseListener, break; } } - - redrawneeded = true; - repaint(); } public Color getColour(int atomIndex, int pdbResNum, String chain, diff --git a/src/jalview/analysis/AAFrequency.java b/src/jalview/analysis/AAFrequency.java index 69d32cb..8dfda39 100755 --- a/src/jalview/analysis/AAFrequency.java +++ b/src/jalview/analysis/AAFrequency.java @@ -20,10 +20,13 @@ */ package jalview.analysis; -import java.util.*; - +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceI; import jalview.util.Format; -import jalview.datamodel.*; + +import java.util.Hashtable; +import java.util.List; /** * Takes in a vector or array of sequences and column start and column end and @@ -36,8 +39,8 @@ import jalview.datamodel.*; */ public class AAFrequency { - // No need to store 1000s of strings which are not - // visible to the user. + private static final int TO_UPPER_CASE = 'A' - 'a'; // -32 + public static final String MAXCOUNT = "C"; public static final String MAXRESIDUE = "R"; @@ -48,6 +51,19 @@ public class AAFrequency public static final String PROFILE = "P"; + /* + * Quick look-up of String value of char 'A' to 'Z' + */ + private static final String[] CHARS = new String['Z' - 'A' + 1]; + + static + { + for (char c = 'A'; c <= 'Z'; c++) + { + CHARS[c - 'A'] = String.valueOf(c); + } + } + public static final Hashtable[] calculate(List list, int start, int end) { @@ -83,16 +99,11 @@ public class AAFrequency } public static final void calculate(SequenceI[] sequences, int start, - int end, Hashtable[] result) - { - calculate(sequences, start, end, result, false); - } - - public static final void calculate(SequenceI[] sequences, int start, int end, Hashtable[] result, boolean profile) { Hashtable residueHash; - int maxCount, nongap, i, j, v, jSize = sequences.length; + int maxCount, nongap, i, j, v; + int jSize = sequences.length; String maxResidue; char c = '-'; float percentage; @@ -134,7 +145,7 @@ public class AAFrequency } else if ('a' <= c && c <= 'z') { - c -= 32; // ('a' - 'A'); + c += TO_UPPER_CASE; } nongap++; @@ -153,7 +164,7 @@ public class AAFrequency } else { - for (v = 'A'; v < 'Z'; v++) + for (v = 'A'; v <= 'Z'; v++) { if (values[v] < 2 || values[v] < maxCount) { @@ -162,11 +173,11 @@ public class AAFrequency if (values[v] > maxCount) { - maxResidue = String.valueOf((char) v); + maxResidue = CHARS[v - 'A']; } else if (values[v] == maxCount) { - maxResidue += String.valueOf((char) v); + maxResidue += CHARS[v - 'A']; } maxCount = values[v]; } @@ -218,9 +229,7 @@ public class AAFrequency { completeConsensus(consensus, hconsensus, iStart, width, ignoreGapsInConsensusCalculation, includeAllConsSymbols, null, - nseq); // new - // char[] - // { 'A', 'C', 'G', 'T', 'U' }); + nseq); } public static void completeConsensus(AlignmentAnnotation consensus, @@ -356,8 +365,10 @@ public class AAFrequency int[] rtnval = new int[64]; int[][] profile = (int[][]) hconsensus.get(AAFrequency.PROFILE); if (profile == null) + { return null; - Object[] ca = new Object[profile[0].length]; + } + char[][] ca = new char[profile[0].length][]; float[] vl = new float[profile[0].length]; for (int c = 0; c < ca.length; c++) { @@ -365,16 +376,15 @@ public class AAFrequency { (char) c }; vl[c] = profile[0][c]; } - ; jalview.util.QuickSort.sort(vl, ca); rtnval[0] = 2; rtnval[1] = 0; - for (int c = ca.length - 1; profile[0][((char[]) ca[c])[0]] > 0; c--) + for (int c = ca.length - 1; profile[0][ca[c][0]] > 0; c--) { - if (((char[]) ca[c])[0] != '-') + if (ca[c][0] != '-') { - rtnval[rtnval[0]++] = ((char[]) ca[c])[0]; - rtnval[rtnval[0]] = (int) (profile[0][((char[]) ca[c])[0]] * 100f / profile[1][ignoreGapsInConsensusCalculation ? 1 + rtnval[rtnval[0]++] = ca[c][0]; + rtnval[rtnval[0]] = (int) (profile[0][ca[c][0]] * 100f / profile[1][ignoreGapsInConsensusCalculation ? 1 : 0]); rtnval[1] += rtnval[rtnval[0]++]; } diff --git a/src/jalview/analysis/AlignSeq.java b/src/jalview/analysis/AlignSeq.java index 2ef1c76..cd548b3 100755 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@ -804,19 +804,23 @@ public class AlignSeq } /** - * DOCUMENT ME! + * Returns the given sequence with all of the given gap characters removed. * - * @param gapChar - * DOCUMENT ME! + * @param gapChars + * a string of characters to be treated as gaps * @param seq - * DOCUMENT ME! + * the input sequence * - * @return DOCUMENT ME! + * @return */ - public static String extractGaps(String gapChar, String seq) + public static String extractGaps(String gapChars, String seq) { - StringTokenizer str = new StringTokenizer(seq, gapChar); - StringBuffer newString = new StringBuffer(); + if (gapChars == null || seq == null) + { + return null; + } + StringTokenizer str = new StringTokenizer(seq, gapChars); + StringBuilder newString = new StringBuilder(seq.length()); while (str.hasMoreTokens()) { diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index b7cfbbd..44cde6e 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -20,10 +20,19 @@ */ package jalview.analysis; -import java.util.*; - -import jalview.datamodel.*; -import jalview.util.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentOrder; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceNode; +import jalview.util.Comparison; +import jalview.util.MessageManager; +import jalview.util.QuickSort; + +import java.util.ArrayList; +import java.util.List; /** * Routines for manipulating the order of a multiple sequence alignment TODO: @@ -120,7 +129,7 @@ public class AlignmentSorter seqs[i] = align.getSequenceAt(i); } - QuickSort.sort(scores, 0, scores.length - 1, seqs); + QuickSort.sort(scores, seqs); setReverseOrder(align, seqs); } @@ -169,7 +178,7 @@ public class AlignmentSorter * @param tmp * sequences as a vector */ - private static void setOrder(AlignmentI align, Vector tmp) + private static void setOrder(AlignmentI align, List tmp) { setOrder(align, vectorSubsetToArray(tmp, align.getSequences())); } @@ -285,7 +294,7 @@ public class AlignmentSorter { // MAINTAINS ORIGNAL SEQUENCE ORDER, // ORDERS BY GROUP SIZE - Vector groups = new Vector(); + List groups = new ArrayList(); if (groups.hashCode() != lastGroupHash) { @@ -303,11 +312,11 @@ public class AlignmentSorter { for (int j = 0; j < groups.size(); j++) { - SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j); + SequenceGroup sg2 = groups.get(j); if (sg.getSize() > sg2.getSize()) { - groups.insertElementAt(sg, j); + groups.add(j, sg); break; } @@ -315,22 +324,22 @@ public class AlignmentSorter if (!groups.contains(sg)) { - groups.addElement(sg); + groups.add(sg); } } // NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER // ///////////////////////////////////////////// - Vector seqs = new Vector(); + List seqs = new ArrayList(); for (int i = 0; i < groups.size(); i++) { - SequenceGroup sg = (SequenceGroup) groups.elementAt(i); + SequenceGroup sg = groups.get(i); SequenceI[] orderedseqs = sg.getSequencesInOrder(align); for (int j = 0; j < orderedseqs.length; j++) { - seqs.addElement(orderedseqs[j]); + seqs.add(orderedseqs[j]); } } @@ -346,28 +355,8 @@ public class AlignmentSorter } /** - * Converts Vector to array. java 1.18 does not have Vector.toArray() - * - * @param tmp - * Vector of SequenceI objects - * - * @return array of Sequence[] - */ - private static SequenceI[] vectorToArray(Vector tmp) - { - SequenceI[] seqs = new SequenceI[tmp.size()]; - - for (int i = 0; i < tmp.size(); i++) - { - seqs[i] = (SequenceI) tmp.elementAt(i); - } - - return seqs; - } - - /** * Select sequences in order from tmp that is present in mask, and any - * remaining seqeunces in mask not in tmp + * remaining sequences in mask not in tmp * * @param tmp * thread safe collection of sequences @@ -379,6 +368,10 @@ public class AlignmentSorter private static SequenceI[] vectorSubsetToArray(List tmp, List mask) { + // or? + // tmp2 = tmp.retainAll(mask); + // return tmp2.addAll(mask.removeAll(tmp2)) + ArrayList seqs = new ArrayList(); int i, idx; boolean[] tmask = new boolean[mask.size()]; @@ -421,7 +414,7 @@ public class AlignmentSorter public static void sortBy(AlignmentI align, AlignmentOrder order) { // Get an ordered vector of sequences which may also be present in align - Vector tmp = order.getOrder(); + List tmp = order.getOrder(); if (lastOrder == order) { @@ -452,11 +445,12 @@ public class AlignmentSorter * * @return DOCUMENT ME! */ - private static Vector getOrderByTree(AlignmentI align, NJTree tree) + private static List getOrderByTree(AlignmentI align, + NJTree tree) { int nSeq = align.getHeight(); - Vector tmp = new Vector(); + List tmp = new ArrayList(); tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences()); @@ -494,7 +488,7 @@ public class AlignmentSorter */ public static void sortByTree(AlignmentI align, NJTree tree) { - Vector tmp = getOrderByTree(align, tree); + List tmp = getOrderByTree(align, tree); // tmp should properly permute align with tree. if (lastTree != tree) @@ -522,22 +516,22 @@ public class AlignmentSorter * * @param align * DOCUMENT ME! - * @param seqs + * @param tmp * DOCUMENT ME! */ - private static void addStrays(AlignmentI align, Vector seqs) + private static void addStrays(AlignmentI align, List tmp) { int nSeq = align.getHeight(); for (int i = 0; i < nSeq; i++) { - if (!seqs.contains(align.getSequenceAt(i))) + if (!tmp.contains(align.getSequenceAt(i))) { - seqs.addElement(align.getSequenceAt(i)); + tmp.add(align.getSequenceAt(i)); } } - if (nSeq != seqs.size()) + if (nSeq != tmp.size()) { System.err .println("ERROR: Size still not right even after addStrays"); @@ -556,7 +550,8 @@ public class AlignmentSorter * * @return DOCUMENT ME! */ - private static Vector _sortByTree(SequenceNode node, Vector tmp, + private static List _sortByTree(SequenceNode node, + List tmp, List seqset) { if (node == null) @@ -577,7 +572,7 @@ public class AlignmentSorter // seqset.size()==0 || // seqset.contains(tmp))) { - tmp.addElement(node.element()); + tmp.add((SequenceI) node.element()); } } } diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index 6385fa7..6b7d18b 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -20,12 +20,27 @@ */ package jalview.analysis; +import jalview.datamodel.AlignedCodon; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.Mapping; +import jalview.datamodel.SearchResults; +import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; +import jalview.schemes.ResidueProperties; +import jalview.util.MapList; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; /** * grab bag of useful alignment manipulation operations Expect these to be @@ -38,6 +53,15 @@ public class AlignmentUtils { /** + * Represents the 3 possible results of trying to map one alignment to + * another. + */ + public enum MappingResult + { + Mapped, NotMapped, AlreadyMapped + } + + /** * given an existing alignment, create a new alignment including all, or up to * flankSize additional symbols from each sequence's dataset sequence * @@ -159,4 +183,723 @@ public class AlignmentUtils } return result; } + + /** + * Returns a map of lists of sequences in the alignment, keyed by sequence + * name. For use in mapping between different alignment views of the same + * sequences. + * + * @see jalview.datamodel.AlignmentI#getSequencesByName() + */ + public static Map> getSequencesByName( + AlignmentI al) + { + Map> theMap = new LinkedHashMap>(); + for (SequenceI seq : al.getSequences()) + { + String name = seq.getName(); + if (name != null) + { + List seqs = theMap.get(name); + if (seqs == null) + { + seqs = new ArrayList(); + theMap.put(name, seqs); + } + seqs.add(seq); + } + } + return theMap; + } + + /** + * Build mapping of protein to cDNA alignment. Mappings are made between + * sequences which have the same name and compatible lengths. Any new mappings + * are added to the protein alignment. Has a 3-valued result: either Mapped + * (at least one sequence mapping was created), AlreadyMapped (all possible + * sequence mappings already exist), or NotMapped (no possible sequence + * mappings exist). + * + * @param proteinAlignment + * @param cdnaAlignment + * @return + */ + public static MappingResult mapProteinToCdna( + final AlignmentI proteinAlignment, + final AlignmentI cdnaAlignment) + { + if (proteinAlignment == null || cdnaAlignment == null) + { + return MappingResult.NotMapped; + } + + boolean mappingPossible = false; + boolean mappingPerformed = false; + + List thisSeqs = proteinAlignment.getSequences(); + + /* + * Build a look-up of cDNA sequences by name, for matching purposes. + */ + Map> cdnaSeqs = cdnaAlignment + .getSequencesByName(); + + for (SequenceI aaSeq : thisSeqs) + { + AlignedCodonFrame acf = new AlignedCodonFrame(); + List candidates = cdnaSeqs.get(aaSeq.getName()); + if (candidates == null) + { + /* + * No cDNA sequence with matching name, so no mapping possible for this + * protein sequence + */ + continue; + } + mappingPossible = true; + for (SequenceI cdnaSeq : candidates) + { + if (!mappingExists(proteinAlignment.getCodonFrames(), + aaSeq.getDatasetSequence(), cdnaSeq.getDatasetSequence())) + { + MapList map = mapProteinToCdna(aaSeq, cdnaSeq); + if (map != null) + { + acf.addMap(cdnaSeq, aaSeq, map); + mappingPerformed = true; + } + } + } + proteinAlignment.addCodonFrame(acf); + } + + /* + * If at least one mapping was possible but none was done, then the + * alignments are already as mapped as they can be. + */ + if (mappingPossible && !mappingPerformed) + { + return MappingResult.AlreadyMapped; + } + else + { + return mappingPerformed ? MappingResult.Mapped + : MappingResult.NotMapped; + } + } + + /** + * Answers true if the mappings include one between the given (dataset) + * sequences. + */ + public static boolean mappingExists(Set set, + SequenceI aaSeq, SequenceI cdnaSeq) + { + if (set != null) + { + for (AlignedCodonFrame acf : set) + { + if (cdnaSeq == acf.getDnaForAaSeq(aaSeq)) + { + return true; + } + } + } + return false; + } + + /** + * Build a mapping (if possible) of a protein to a cDNA sequence. The cDNA + * must be three times the length of the protein, possibly after ignoring + * start and/or stop codons. Returns null if no mapping is determined. + * + * @param proteinSeqs + * @param cdnaSeq + * @return + */ + public static MapList mapProteinToCdna(SequenceI proteinSeq, + SequenceI cdnaSeq) + { + /* + * Here we handle either dataset sequence set (desktop) or absent (applet) + */ + final SequenceI proteinDataset = proteinSeq.getDatasetSequence(); + String aaSeqString = proteinDataset != null ? proteinDataset + .getSequenceAsString() : proteinSeq.getSequenceAsString(); + final SequenceI cdnaDataset = cdnaSeq.getDatasetSequence(); + String cdnaSeqString = cdnaDataset != null ? cdnaDataset + .getSequenceAsString() : cdnaSeq.getSequenceAsString(); + if (aaSeqString == null || cdnaSeqString == null) + { + return null; + } + + final int mappedLength = 3 * aaSeqString.length(); + int cdnaLength = cdnaSeqString.length(); + int cdnaStart = 1; + int cdnaEnd = cdnaLength; + final int proteinStart = 1; + final int proteinEnd = aaSeqString.length(); + + /* + * If lengths don't match, try ignoring stop codon. + */ + if (cdnaLength != mappedLength) + { + for (Object stop : ResidueProperties.STOP) + { + if (cdnaSeqString.toUpperCase().endsWith((String) stop)) + { + cdnaEnd -= 3; + cdnaLength -= 3; + break; + } + } + } + + /* + * If lengths still don't match, try ignoring start codon. + */ + if (cdnaLength != mappedLength + && cdnaSeqString.toUpperCase().startsWith( + ResidueProperties.START)) + { + cdnaStart += 3; + cdnaLength -= 3; + } + + if (cdnaLength == mappedLength) + { + MapList map = new MapList(new int[] + { cdnaStart, cdnaEnd }, new int[] + { proteinStart, proteinEnd }, 3, 1); + return map; + } + else + { + return null; + } + } + + /** + * Align sequence 'seq' to match the alignment of a mapped sequence. Note this + * currently assumes that we are aligning cDNA to match protein. + * + * @param seq + * the sequence to be realigned + * @param al + * the alignment whose sequence alignment is to be 'copied' + * @param gap + * character string represent a gap in the realigned sequence + * @param preserveUnmappedGaps + * @param preserveMappedGaps + * @return true if the sequence was realigned, false if it could not be + */ + public static boolean alignSequenceAs(SequenceI seq, AlignmentI al, + String gap, boolean preserveMappedGaps, + boolean preserveUnmappedGaps) + { + /* + * Get any mappings from the source alignment to the target (dataset) sequence. + */ + // TODO there may be one AlignedCodonFrame per dataset sequence, or one with + // all mappings. Would it help to constrain this? + List mappings = al.getCodonFrame(seq); + if (mappings == null || mappings.isEmpty()) + { + return false; + } + + /* + * Locate the aligned source sequence whose dataset sequence is mapped. We + * just take the first match here (as we can't align cDNA like more than one + * protein sequence). + */ + SequenceI alignFrom = null; + AlignedCodonFrame mapping = null; + for (AlignedCodonFrame mp : mappings) + { + alignFrom = mp.findAlignedSequence(seq.getDatasetSequence(), al); + if (alignFrom != null) + { + mapping = mp; + break; + } + } + + if (alignFrom == null) + { + return false; + } + alignSequenceAs(seq, alignFrom, mapping, gap, al.getGapCharacter(), + preserveMappedGaps, preserveUnmappedGaps); + return true; + } + + /** + * Align sequence 'alignTo' the same way as 'alignFrom', using the mapping to + * match residues and codons. Flags control whether existing gaps in unmapped + * (intron) and mapped (exon) regions are preserved or not. Gaps linking intro + * and exon are only retained if both flags are set. + * + * @param alignTo + * @param alignFrom + * @param mapping + * @param myGap + * @param sourceGap + * @param preserveUnmappedGaps + * @param preserveMappedGaps + */ + public static void alignSequenceAs(SequenceI alignTo, + SequenceI alignFrom, + AlignedCodonFrame mapping, String myGap, char sourceGap, + boolean preserveMappedGaps, boolean preserveUnmappedGaps) + { + // TODO generalise to work for Protein-Protein, dna-dna, dna-protein + final char[] thisSeq = alignTo.getSequence(); + final char[] thatAligned = alignFrom.getSequence(); + StringBuilder thisAligned = new StringBuilder(2 * thisSeq.length); + + // aligned and dataset sequence positions, all base zero + int thisSeqPos = 0; + int sourceDsPos = 0; + + int basesWritten = 0; + char myGapChar = myGap.charAt(0); + int ratio = myGap.length(); + + /* + * Traverse the aligned protein sequence. + */ + int sourceGapMappedLength = 0; + boolean inExon = false; + for (char sourceChar : thatAligned) + { + if (sourceChar == sourceGap) + { + sourceGapMappedLength += ratio; + continue; + } + + /* + * Found a residue. Locate its mapped codon (start) position. + */ + sourceDsPos++; + // Note mapping positions are base 1, our sequence positions base 0 + int[] mappedPos = mapping.getMappedRegion(alignTo, alignFrom, + sourceDsPos); + if (mappedPos == null) + { + /* + * Abort realignment if unmapped protein. Or could ignore it?? + */ + System.err.println("Can't align: no codon mapping to residue " + + sourceDsPos + "(" + sourceChar + ")"); + return; + } + + int mappedCodonStart = mappedPos[0]; // position (1...) of codon start + int mappedCodonEnd = mappedPos[mappedPos.length - 1]; // codon end pos + StringBuilder trailingCopiedGap = new StringBuilder(); + + /* + * Copy dna sequence up to and including this codon. Optionally, include + * gaps before the codon starts (in introns) and/or after the codon starts + * (in exons). + * + * Note this only works for 'linear' splicing, not reverse or interleaved. + * But then 'align dna as protein' doesn't make much sense otherwise. + */ + int intronLength = 0; + while (basesWritten < mappedCodonEnd && thisSeqPos < thisSeq.length) + { + final char c = thisSeq[thisSeqPos++]; + if (c != myGapChar) + { + basesWritten++; + + if (basesWritten < mappedCodonStart) + { + /* + * Found an unmapped (intron) base. First add in any preceding gaps + * (if wanted). + */ + if (preserveUnmappedGaps && trailingCopiedGap.length() > 0) + { + thisAligned.append(trailingCopiedGap.toString()); + intronLength += trailingCopiedGap.length(); + trailingCopiedGap = new StringBuilder(); + } + intronLength++; + inExon = false; + } + else + { + final boolean startOfCodon = basesWritten == mappedCodonStart; + int gapsToAdd = calculateGapsToInsert(preserveMappedGaps, + preserveUnmappedGaps, sourceGapMappedLength, inExon, + trailingCopiedGap.length(), intronLength, startOfCodon); + for (int i = 0; i < gapsToAdd; i++) + { + thisAligned.append(myGapChar); + } + sourceGapMappedLength = 0; + inExon = true; + } + thisAligned.append(c); + trailingCopiedGap = new StringBuilder(); + } + else + { + if (inExon && preserveMappedGaps) + { + trailingCopiedGap.append(myGapChar); + } + else if (!inExon && preserveUnmappedGaps) + { + trailingCopiedGap.append(myGapChar); + } + } + } + } + + /* + * At end of protein sequence. Copy any remaining dna sequence, optionally + * including (intron) gaps. We do not copy trailing gaps in protein. + */ + while (thisSeqPos < thisSeq.length) + { + final char c = thisSeq[thisSeqPos++]; + if (c != myGapChar || preserveUnmappedGaps) + { + thisAligned.append(c); + } + } + + /* + * All done aligning, set the aligned sequence. + */ + alignTo.setSequence(new String(thisAligned)); + } + + /** + * Helper method to work out how many gaps to insert when realigning. + * + * @param preserveMappedGaps + * @param preserveUnmappedGaps + * @param sourceGapMappedLength + * @param inExon + * @param trailingCopiedGap + * @param intronLength + * @param startOfCodon + * @return + */ + protected static int calculateGapsToInsert(boolean preserveMappedGaps, + boolean preserveUnmappedGaps, int sourceGapMappedLength, + boolean inExon, int trailingGapLength, + int intronLength, final boolean startOfCodon) + { + int gapsToAdd = 0; + if (startOfCodon) + { + /* + * Reached start of codon. Ignore trailing gaps in intron unless we are + * preserving gaps in both exon and intron. Ignore them anyway if the + * protein alignment introduces a gap at least as large as the intronic + * region. + */ + if (inExon && !preserveMappedGaps) + { + trailingGapLength = 0; + } + if (!inExon && !(preserveMappedGaps && preserveUnmappedGaps)) + { + trailingGapLength = 0; + } + if (inExon) + { + gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength); + } + else + { + if (intronLength + trailingGapLength <= sourceGapMappedLength) + { + gapsToAdd = sourceGapMappedLength - intronLength; + } + else + { + gapsToAdd = Math.min(intronLength + trailingGapLength + - sourceGapMappedLength, trailingGapLength); + } + } + } + else + { + /* + * second or third base of codon; check for any gaps in dna + */ + if (!preserveMappedGaps) + { + trailingGapLength = 0; + } + gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength); + } + return gapsToAdd; + } + + /** + * Returns a list of sequences mapped from the given sequences and aligned + * (gapped) in the same way. For example, the cDNA for aligned protein, where + * a single gap in protein generates three gaps in cDNA. + * + * @param sequences + * @param gapCharacter + * @param mappings + * @return + */ + public static List getAlignedTranslation( + List sequences, char gapCharacter, + Set mappings) + { + List alignedSeqs = new ArrayList(); + + for (SequenceI seq : sequences) + { + List mapped = getAlignedTranslation(seq, gapCharacter, + mappings); + alignedSeqs.addAll(mapped); + } + return alignedSeqs; + } + + /** + * Returns sequences aligned 'like' the source sequence, as mapped by the + * given mappings. Normally we expect zero or one 'mapped' sequences, but this + * will support 1-to-many as well. + * + * @param seq + * @param gapCharacter + * @param mappings + * @return + */ + protected static List getAlignedTranslation(SequenceI seq, + char gapCharacter, Set mappings) + { + List result = new ArrayList(); + for (AlignedCodonFrame mapping : mappings) + { + if (mapping.involvesSequence(seq)) + { + SequenceI mapped = getAlignedTranslation(seq, gapCharacter, mapping); + if (mapped != null) + { + result.add(mapped); + } + } + } + return result; + } + + /** + * Returns the translation of 'seq' (as held in the mapping) with + * corresponding alignment (gaps). + * + * @param seq + * @param gapCharacter + * @param mapping + * @return + */ + protected static SequenceI getAlignedTranslation(SequenceI seq, + char gapCharacter, AlignedCodonFrame mapping) + { + String gap = String.valueOf(gapCharacter); + boolean toDna = false; + int fromRatio = 1; + SequenceI mapTo = mapping.getDnaForAaSeq(seq); + if (mapTo != null) + { + // mapping is from protein to nucleotide + toDna = true; + // should ideally get gap count ratio from mapping + gap = String.valueOf(new char[] + { gapCharacter, gapCharacter, gapCharacter }); + } + else + { + // mapping is from nucleotide to protein + mapTo = mapping.getAaForDnaSeq(seq); + fromRatio = 3; + } + StringBuilder newseq = new StringBuilder(seq.getLength() + * (toDna ? 3 : 1)); + + int residueNo = 0; // in seq, base 1 + int[] phrase = new int[fromRatio]; + int phraseOffset = 0; + int gapWidth = 0; + boolean first = true; + final Sequence alignedSeq = new Sequence("", ""); + + for (char c : seq.getSequence()) + { + if (c == gapCharacter) + { + gapWidth++; + if (gapWidth >= fromRatio) + { + newseq.append(gap); + gapWidth = 0; + } + } + else + { + phrase[phraseOffset++] = residueNo + 1; + if (phraseOffset == fromRatio) + { + /* + * Have read a whole codon (or protein residue), now translate: map + * source phrase to positions in target sequence add characters at + * these positions to newseq Note mapping positions are base 1, our + * sequence positions base 0. + */ + SearchResults sr = new SearchResults(); + for (int pos : phrase) + { + mapping.markMappedRegion(seq, pos, sr); + } + newseq.append(sr.toString()); + if (first) + { + first = false; + // Hack: Copy sequence dataset, name and description from + // SearchResults.match[0].sequence + // TODO? carry over sequence names from original 'complement' + // alignment + SequenceI mappedTo = sr.getResultSequence(0); + alignedSeq.setName(mappedTo.getName()); + alignedSeq.setDescription(mappedTo.getDescription()); + alignedSeq.setDatasetSequence(mappedTo); + } + phraseOffset = 0; + } + residueNo++; + } + } + alignedSeq.setSequence(newseq.toString()); + return alignedSeq; + } + + /** + * Realigns the given protein to match the alignment of the dna, using codon + * mappings to translate aligned codon positions to protein residues. + * + * @param protein + * the alignment whose sequences are realigned by this method + * @param dna + * the dna alignment whose alignment we are 'copying' + * @return the number of sequences that were realigned + */ + public static int alignProteinAsDna(AlignmentI protein, AlignmentI dna) + { + Set mappings = protein.getCodonFrames(); + + /* + * Map will hold, for each aligned codon position e.g. [3, 5, 6], a map of + * {dnaSequence, {proteinSequence, codonProduct}} at that position. The + * comparator keeps the codon positions ordered. + */ + Map> alignedCodons = new TreeMap>( + new CodonComparator()); + for (SequenceI dnaSeq : dna.getSequences()) + { + for (AlignedCodonFrame mapping : mappings) + { + Mapping seqMap = mapping.getMappingForSequence(dnaSeq); + SequenceI prot = mapping.findAlignedSequence( + dnaSeq.getDatasetSequence(), protein); + if (prot != null) + { + addCodonPositions(dnaSeq, prot, protein.getGapCharacter(), + seqMap, alignedCodons); + } + } + } + return alignProteinAs(protein, alignedCodons); + } + + /** + * Update the aligned protein sequences to match the codon alignments given in + * the map. + * + * @param protein + * @param alignedCodons + * an ordered map of codon positions (columns), with sequence/peptide + * values present in each column + * @return + */ + protected static int alignProteinAs(AlignmentI protein, + Map> alignedCodons) + { + /* + * Prefill aligned sequences with gaps before inserting aligned protein + * residues. + */ + int alignedWidth = alignedCodons.size(); + char[] gaps = new char[alignedWidth]; + Arrays.fill(gaps, protein.getGapCharacter()); + String allGaps = String.valueOf(gaps); + for (SequenceI seq : protein.getSequences()) + { + seq.setSequence(allGaps); + } + + int column = 0; + for (AlignedCodon codon : alignedCodons.keySet()) + { + final Map columnResidues = alignedCodons.get(codon); + for (Entry entry : columnResidues + .entrySet()) + { + // place translated codon at its column position in sequence + entry.getKey().getSequence()[column] = entry.getValue().charAt(0); + } + column++; + } + return 0; + } + + /** + * Populate the map of aligned codons by traversing the given sequence + * mapping, locating the aligned positions of mapped codons, and adding those + * positions and their translation products to the map. + * + * @param dna + * the aligned sequence we are mapping from + * @param protein + * the sequence to be aligned to the codons + * @param gapChar + * the gap character in the dna sequence + * @param seqMap + * a mapping to a sequence translation + * @param alignedCodons + * the map we are building up + */ + static void addCodonPositions(SequenceI dna, SequenceI protein, + char gapChar, + Mapping seqMap, + Map> alignedCodons) + { + Iterator codons = seqMap.getCodonIterator(dna, gapChar); + while (codons.hasNext()) + { + AlignedCodon codon = codons.next(); + Map seqProduct = alignedCodons.get(codon); + if (seqProduct == null) + { + seqProduct = new HashMap(); + alignedCodons.put(codon, seqProduct); + } + seqProduct.put(protein, codon.product); + } + } } diff --git a/src/jalview/analysis/CodonComparator.java b/src/jalview/analysis/CodonComparator.java new file mode 100644 index 0000000..fc196de --- /dev/null +++ b/src/jalview/analysis/CodonComparator.java @@ -0,0 +1,91 @@ +package jalview.analysis; + +import jalview.datamodel.AlignedCodon; + +import java.util.Comparator; + +/** + * Implements rules for comparing two aligned codons, i.e. determining whether + * they should occupy the same position in a translated protein alignment, or + * one or the other should 'follow' (by preceded by a gap). + * + * @author gmcarstairs + * + */ +public final class CodonComparator implements Comparator +{ + + @Override + public int compare(AlignedCodon ac1, AlignedCodon ac2) + { + if (ac1 == null || ac2 == null || ac1.equals(ac2)) + { + return 0; + } + + /** + *
+     * Case 1: if one starts before the other, and doesn't end after it, then it
+     * precedes. We ignore the middle base position here.
+     * A--GT
+     * -CT-G
+     * 
+ */ + if (ac1.pos1 < ac2.pos1 && ac1.pos3 <= ac2.pos3) + { + return -1; + } + if (ac2.pos1 < ac1.pos1 && ac2.pos3 <= ac1.pos3) + { + return 1; + } + + /** + *
+     * Case 2: if one ends after the other, and doesn't start before it, then it
+     * follows. We ignore the middle base position here.
+     * -TG-A
+     * G-TC
+     * 
+ */ + if (ac1.pos3 > ac2.pos3 && ac1.pos1 >= ac2.pos1) + { + return 1; + } + if (ac2.pos3 > ac1.pos3 && ac2.pos1 >= ac1.pos1) + { + return -1; + } + + /* + * Case 3: if start and end match, compare middle base positions. + */ + if (ac1.pos1 == ac2.pos1 && ac1.pos3 == ac2.pos3) + { + return Integer.compare(ac1.pos2, ac2.pos2); + } + + /* + * That just leaves the 'enclosing' case - one codon starts after but ends + * before the other. If the middle bases don't match, use their comparison + * (majority vote). + */ + int compareMiddles = Integer.compare(ac1.pos2, ac2.pos2); + if (compareMiddles != 0) + { + return compareMiddles; + } + + /** + *
+     * Finally just leaves overlap with matching middle base, e.g. 
+     * -A-A-A
+     * G--GG 
+     * In this case the choice is arbitrary whether to compare based on
+     * first or last base position. We pick the first. Note this preserves
+     * symmetricality of the comparison.
+     * 
+ */ + return Integer.compare(ac1.pos1, ac2.pos1); + } +} diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java index fa0fe2f..435a477 100644 --- a/src/jalview/analysis/CrossRef.java +++ b/src/jalview/analysis/CrossRef.java @@ -20,21 +20,21 @@ */ package jalview.analysis; -import java.util.Enumeration; -import java.util.List; -import java.util.Vector; -import java.util.Hashtable; - import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; -import jalview.datamodel.DBRefSource; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.ws.SequenceFetcher; import jalview.ws.seqfetcher.ASequenceFetcher; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Vector; + /** * Functions for cross-referencing sequence databases. user must first specify * if cross-referencing from protein or dna (set dna==true) @@ -230,7 +230,7 @@ public class CrossRef { Vector rseqs = new Vector(); Alignment ral = null; - AlignedCodonFrame cf = new AlignedCodonFrame(0); // nominal width + AlignedCodonFrame cf = new AlignedCodonFrame(); // nominal width for (int s = 0; s < seqs.length; s++) { SequenceI dss = seqs[s]; @@ -258,7 +258,9 @@ public class CrossRef for (int r = 0; xrfs != null && r < xrfs.length; r++) { if (source != null && !source.equals(xrfs[r].getSource())) + { continue; + } if (xrfs[r].hasMap()) { if (xrfs[r].getMap().getTo() != null) @@ -291,7 +293,9 @@ public class CrossRef { found |= searchDataset(dss, xrfs[r], dataset, rseqs, cf); // ,false,!dna); if (found) + { xrfs[r] = null; // we've recovered seqs for this one. + } } } } @@ -328,7 +332,9 @@ public class CrossRef for (int r = 0; r < xrfs.length; r++) { if (xrfs[r] != null) + { t[l++] = xrfs[r]; + } } xrfs = t; try @@ -432,7 +438,9 @@ public class CrossRef { boolean found = false; if (lrfs == null) + { return false; + } for (int i = 0; i < lrfs.length; i++) { DBRefEntry xref = new DBRefEntry(lrfs[i]); @@ -484,7 +492,9 @@ public class CrossRef boolean found = false; SequenceI[] typer = new SequenceI[1]; if (dataset == null) + { return false; + } if (dataset.getSequences() == null) { System.err.println("Empty dataset sequence set - NO VECTOR"); @@ -494,6 +504,7 @@ public class CrossRef synchronized (ds = dataset.getSequences()) { for (SequenceI nxt : ds) + { if (nxt != null) { if (nxt.getDatasetSequence() != null) @@ -566,6 +577,7 @@ public class CrossRef } } + } } return found; } diff --git a/src/jalview/analysis/Dna.java b/src/jalview/analysis/Dna.java index 2e56e67..2ef63d4 100644 --- a/src/jalview/analysis/Dna.java +++ b/src/jalview/analysis/Dna.java @@ -20,120 +20,157 @@ */ package jalview.analysis; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Vector; - +import jalview.api.AlignViewportI; +import jalview.bin.Cache; +import jalview.datamodel.AlignedCodon; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; import jalview.datamodel.FeatureProperties; +import jalview.datamodel.GraphLine; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.schemes.ResidueProperties; +import jalview.util.Comparison; +import jalview.util.DBRefUtils; import jalview.util.MapList; import jalview.util.ShiftList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + public class Dna { - /** + private static final String STOP_X = "X"; + + private static final Comparator comparator = new CodonComparator(); + + /* + * 'final' variables describe the inputs to the translation, which should not + * be modified. + */ + final private List selection; + + final private String[] seqstring; + + final private int[] contigs; + + final private char gapChar; + + final private AlignmentAnnotation[] annotations; + + final private int dnaWidth; + + final private Alignment dataset; + + /* + * Working variables for the translation. * - * @param cdp1 - * @param cdp2 - * @return -1 if cdp1 aligns before cdp2, 0 if in the same column or cdp2 is - * null, +1 if after cdp2 + * The width of the translation-in-progress protein alignment. */ - private static int compare_codonpos(int[] cdp1, int[] cdp2) - { - if (cdp2 == null - || (cdp1[0] == cdp2[0] && cdp1[1] == cdp2[1] && cdp1[2] == cdp2[2])) - return 0; - if (cdp1[0] < cdp2[0] || cdp1[1] < cdp2[1] || cdp1[2] < cdp2[2]) - return -1; // one base in cdp1 precedes the corresponding base in the - // other codon - return 1; // one base in cdp1 appears after the corresponding base in the - // other codon. - } + private int aaWidth = 0; - /** - * DNA->mapped protein sequence alignment translation given set of sequences - * 1. id distinct coding regions within selected region for each sequence 2. - * generate peptides based on inframe (or given) translation or (optionally - * and where specified) out of frame translations (annotated appropriately) 3. - * align peptides based on codon alignment + /* + * This array will be built up so that position i holds the codon positions + * e.g. [7, 9, 10] that match column i (base 0) in the aligned translation. + * Note this implies a contract that if two codons do not align exactly, their + * translated products must occupy different column positions. */ + private AlignedCodon[] alignedCodons; + /** - * id potential products from dna 1. search for distinct products within - * selected region for each selected sequence 2. group by associated DB type. - * 3. return as form for input into above function + * Constructor given a viewport and the visible contigs. + * + * @param viewport + * @param visibleContigs */ + public Dna(AlignViewportI viewport, int[] visibleContigs) + { + this.selection = Arrays.asList(viewport.getSequenceSelection()); + this.seqstring = viewport.getViewAsString(true); + this.contigs = visibleContigs; + this.gapChar = viewport.getGapCharacter(); + this.annotations = viewport.getAlignment().getAlignmentAnnotation(); + this.dnaWidth = viewport.getAlignment().getWidth(); + this.dataset = viewport.getAlignment().getDataset(); + } + /** + * Test whether codon positions cdp1 should align before, with, or after cdp2. + * Returns zero if all positions match (or either argument is null). Returns + * -1 if any position in the first codon precedes the corresponding position + * in the second codon. Else returns +1 (some position in the second codon + * precedes the corresponding position in the first). + * + * Note this is not necessarily symmetric, for example: + *
    + *
  • compareCodonPos([2,5,6], [3,4,5]) returns -1
  • + *
  • compareCodonPos([3,4,5], [2,5,6]) also returns -1
  • + *
* + * @param ac1 + * @param ac2 + * @return */ + public static final int compareCodonPos(AlignedCodon ac1, AlignedCodon ac2) + { + return comparator.compare(ac1, ac2); + // return jalview_2_8_2compare(ac1, ac2); + } + /** - * create a new alignment of protein sequences by an inframe translation of - * the provided NA sequences + * Codon comparison up to Jalview 2.8.2. This rule is sequence order dependent + * - see http://issues.jalview.org/browse/JAL-1635 * - * @param selection - * @param seqstring - * @param viscontigs - * @param gapCharacter - * @param annotations - * @param aWidth - * @param dataset - * destination dataset for translated sequences and mappings + * @param ac1 + * @param ac2 * @return */ - public static AlignmentI CdnaTranslate(SequenceI[] selection, - String[] seqstring, int viscontigs[], char gapCharacter, - AlignmentAnnotation[] annotations, int aWidth, Alignment dataset) + private static int jalview_2_8_2compare(AlignedCodon ac1, AlignedCodon ac2) { - return CdnaTranslate(selection, seqstring, null, viscontigs, - gapCharacter, annotations, aWidth, dataset); + if (ac1 == null || ac2 == null || (ac1.equals(ac2))) + { + return 0; + } + if (ac1.pos1 < ac2.pos1 || ac1.pos2 < ac2.pos2 || ac1.pos3 < ac2.pos3) + { + // one base in cdp1 precedes the corresponding base in the other codon + return -1; + } + // one base in cdp1 appears after the corresponding base in the other codon. + return 1; } /** * - * @param selection - * @param seqstring - * @param product - * - array of DbRefEntry objects from which exon map in seqstring is - * derived - * @param viscontigs - * @param gapCharacter - * @param annotations - * @param aWidth - * @param dataset * @return */ - public static AlignmentI CdnaTranslate(SequenceI[] selection, - String[] seqstring, DBRefEntry[] product, int viscontigs[], - char gapCharacter, AlignmentAnnotation[] annotations, int aWidth, - Alignment dataset) + public AlignmentI translateCdna() { - AlignedCodonFrame codons = new AlignedCodonFrame(aWidth); // stores hash of - // subsequent - // positions for - // each codon - // start position - // in alignment - int s, sSize = selection.length; - Vector pepseqs = new Vector(); + AlignedCodonFrame acf = new AlignedCodonFrame(); + + alignedCodons = new AlignedCodon[dnaWidth]; + + int s; + int sSize = selection.size(); + List pepseqs = new ArrayList(); for (s = 0; s < sSize; s++) { - SequenceI newseq = translateCodingRegion(selection[s], seqstring[s], - viscontigs, codons, gapCharacter, - (product != null) ? product[s] : null, false); // possibly - // anonymous - // product + SequenceI newseq = translateCodingRegion(selection.get(s), + seqstring[s], acf, pepseqs); + if (newseq != null) { - pepseqs.addElement(newseq); + pepseqs.add(newseq); SequenceI ds = newseq; if (dataset != null) { @@ -145,15 +182,15 @@ public class Dna } } } - if (codons.aaWidth == 0) - return null; - SequenceI[] newseqs = new SequenceI[pepseqs.size()]; - pepseqs.copyInto(newseqs); + + SequenceI[] newseqs = pepseqs.toArray(new SequenceI[pepseqs.size()]); AlignmentI al = new Alignment(newseqs); - al.padGaps(); // ensure we look aligned. + // ensure we look aligned. + al.padGaps(); + // link the protein translation to the DNA dataset al.setDataset(dataset); - translateAlignedAnnotations(annotations, al, codons); - al.addCodonFrame(codons); + translateAlignedAnnotations(al, acf); + al.addCodonFrame(acf); return al; } @@ -172,14 +209,13 @@ public class Dna for (int gd = 0; gd < selection.length; gd++) { SequenceI dna = selection[gd]; - jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils + DBRefEntry[] dnarefs = DBRefUtils .selectRefs(dna.getDBRef(), jalview.datamodel.DBRefSource.DNACODINGDBS); if (dnarefs != null) { // intersect with pep - // intersect with pep - Vector mappedrefs = new Vector(); + List mappedrefs = new ArrayList(); DBRefEntry[] refs = dna.getDBRef(); for (int d = 0; d < refs.length; d++) { @@ -187,11 +223,10 @@ public class Dna && refs[d].getMap().getMap().getFromRatio() == 3 && refs[d].getMap().getMap().getToRatio() == 1) { - mappedrefs.addElement(refs[d]); // add translated protein maps + mappedrefs.add(refs[d]); // add translated protein maps } } - dnarefs = new DBRefEntry[mappedrefs.size()]; - mappedrefs.copyInto(dnarefs); + dnarefs = mappedrefs.toArray(new DBRefEntry[mappedrefs.size()]); for (int d = 0; d < dnarefs.length; d++) { Mapping mp = dnarefs[d].getMap(); @@ -214,176 +249,107 @@ public class Dna } /** - * generate a set of translated protein products from annotated sequenceI + * Translate nucleotide alignment annotations onto translated amino acid + * alignment using codon mapping codons * - * @param selection - * @param viscontigs - * @param gapCharacter - * @param dataset - * destination dataset for translated sequences - * @param annotations - * @param aWidth - * @return - */ - public static AlignmentI CdnaTranslate(SequenceI[] selection, - int viscontigs[], char gapCharacter, Alignment dataset) - { - int alwidth = 0; - Vector cdnasqs = new Vector(); - Vector cdnasqi = new Vector(); - Vector cdnaprod = new Vector(); - for (int gd = 0; gd < selection.length; gd++) - { - SequenceI dna = selection[gd]; - jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils - .selectRefs(dna.getDBRef(), - jalview.datamodel.DBRefSource.DNACODINGDBS); - if (dnarefs != null) - { - // intersect with pep - Vector mappedrefs = new Vector(); - DBRefEntry[] refs = dna.getDBRef(); - for (int d = 0; d < refs.length; d++) - { - if (refs[d].getMap() != null && refs[d].getMap().getMap() != null - && refs[d].getMap().getMap().getFromRatio() == 3 - && refs[d].getMap().getMap().getToRatio() == 1) - { - mappedrefs.addElement(refs[d]); // add translated protein maps - } - } - dnarefs = new DBRefEntry[mappedrefs.size()]; - mappedrefs.copyInto(dnarefs); - for (int d = 0; d < dnarefs.length; d++) - { - Mapping mp = dnarefs[d].getMap(); - StringBuffer sqstr = new StringBuffer(); - if (mp != null) - { - Mapping intersect = mp.intersectVisContigs(viscontigs); - // generate seqstring for this sequence based on mapping - - if (sqstr.length() > alwidth) - alwidth = sqstr.length(); - cdnasqs.addElement(sqstr.toString()); - cdnasqi.addElement(dna); - cdnaprod.addElement(intersect); - } - } - } - SequenceI[] cdna = new SequenceI[cdnasqs.size()]; - DBRefEntry[] prods = new DBRefEntry[cdnaprod.size()]; - String[] xons = new String[cdnasqs.size()]; - cdnasqs.copyInto(xons); - cdnaprod.copyInto(prods); - cdnasqi.copyInto(cdna); - return CdnaTranslate(cdna, xons, prods, viscontigs, gapCharacter, - null, alwidth, dataset); - } - return null; - } - - /** - * translate na alignment annotations onto translated amino acid alignment al - * using codon mapping codons - * - * @param annotations * @param al - * @param codons + * the translated protein alignment */ - public static void translateAlignedAnnotations( - AlignmentAnnotation[] annotations, AlignmentI al, - AlignedCodonFrame codons) + protected void translateAlignedAnnotations(AlignmentI al, + AlignedCodonFrame acf) { - // ////////////////////////////// - // Copy annotations across - // // Can only do this for columns with consecutive codons, or where // annotation is sequence associated. - int pos, a, aSize; if (annotations != null) { - for (int i = 0; i < annotations.length; i++) + for (AlignmentAnnotation annotation : annotations) { - // Skip any autogenerated annotation - if (annotations[i].autoCalculated) + /* + * Skip hidden or autogenerated annotation. Also (for now), RNA + * secondary structure annotation. If we want to show this against + * protein we need a smarter way to 'translate' without generating + * invalid (unbalanced) structure annotation. + */ + if (annotation.autoCalculated || !annotation.visible + || annotation.isRNA()) { continue; } - aSize = codons.getaaWidth(); // aa alignment width. - jalview.datamodel.Annotation[] anots = (annotations[i].annotations == null) ? null - : new jalview.datamodel.Annotation[aSize]; + int aSize = aaWidth; + Annotation[] anots = (annotation.annotations == null) ? null + : new Annotation[aSize]; if (anots != null) { - for (a = 0; a < aSize; a++) + for (int a = 0; a < aSize; a++) { // process through codon map. - if (codons.codons[a] != null - && codons.codons[a][0] == (codons.codons[a][2] - 2)) + if (a < alignedCodons.length && alignedCodons[a] != null + && alignedCodons[a].pos1 == (alignedCodons[a].pos3 - 2)) { - anots[a] = getCodonAnnotation(codons.codons[a], - annotations[i].annotations); + anots[a] = getCodonAnnotation(alignedCodons[a], + annotation.annotations); } } } - jalview.datamodel.AlignmentAnnotation aa = new jalview.datamodel.AlignmentAnnotation( - annotations[i].label, annotations[i].description, anots); - aa.graph = annotations[i].graph; - aa.graphGroup = annotations[i].graphGroup; - aa.graphHeight = annotations[i].graphHeight; - if (annotations[i].getThreshold() != null) + AlignmentAnnotation aa = new AlignmentAnnotation(annotation.label, + annotation.description, anots); + aa.graph = annotation.graph; + aa.graphGroup = annotation.graphGroup; + aa.graphHeight = annotation.graphHeight; + if (annotation.getThreshold() != null) { - aa.setThreshold(new jalview.datamodel.GraphLine(annotations[i] + aa.setThreshold(new GraphLine(annotation .getThreshold())); } - if (annotations[i].hasScore) + if (annotation.hasScore) { - aa.setScore(annotations[i].getScore()); + aa.setScore(annotation.getScore()); } - if (annotations[i].sequenceRef != null) + + final SequenceI seqRef = annotation.sequenceRef; + if (seqRef != null) { - SequenceI aaSeq = codons - .getAaForDnaSeq(annotations[i].sequenceRef); + SequenceI aaSeq = acf.getAaForDnaSeq(seqRef); if (aaSeq != null) { // aa.compactAnnotationArray(); // throw away alignment annotation // positioning aa.setSequenceRef(aaSeq); - aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true); // rebuild - // mapping + // rebuild mapping + aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true); aa.adjustForAlignment(); aaSeq.addAlignmentAnnotation(aa); } - } al.addAnnotation(aa); } } } - private static Annotation getCodonAnnotation(int[] is, + private static Annotation getCodonAnnotation(AlignedCodon is, Annotation[] annotations) { // Have a look at all the codon positions for annotation and put the first // one found into the translated annotation pos. int contrib = 0; Annotation annot = null; - for (int p = 0; p < 3; p++) + for (int p = 1; p <= 3; p++) { - if (annotations[is[p]] != null) + int dnaCol = is.getBaseColumn(p); + if (annotations[dnaCol] != null) { if (annot == null) { - annot = new Annotation(annotations[is[p]]); + annot = new Annotation(annotations[dnaCol]); contrib = 1; } else { // merge with last - Annotation cpy = new Annotation(annotations[is[p]]); + Annotation cpy = new Annotation(annotations[dnaCol]); if (annot.colour == null) { annot.colour = cpy.colour; @@ -407,7 +373,7 @@ public class Dna } if (contrib > 1) { - annot.value /= (float) contrib; + annot.value /= contrib; } return annot; } @@ -419,92 +385,72 @@ public class Dna * sequence displayed under viscontigs visible columns * @param seqstring * ORF read in some global alignment reference frame - * @param viscontigs - * mapping from global reference frame to visible seqstring ORF read - * @param codons - * Definition of global ORF alignment reference frame - * @param gapCharacter - * @return sequence ready to be added to alignment. - * @deprecated Use - * {@link #translateCodingRegion(SequenceI,String,int[],AlignedCodonFrame,char,DBRefEntry,boolean)} - * instead - */ - public static SequenceI translateCodingRegion(SequenceI selection, - String seqstring, int[] viscontigs, AlignedCodonFrame codons, - char gapCharacter, DBRefEntry product) - { - return translateCodingRegion(selection, seqstring, viscontigs, codons, - gapCharacter, product, false); - } - - /** - * Translate a na sequence - * - * @param selection - * sequence displayed under viscontigs visible columns - * @param seqstring - * ORF read in some global alignment reference frame - * @param viscontigs - * mapping from global reference frame to visible seqstring ORF read - * @param codons + * @param acf * Definition of global ORF alignment reference frame - * @param gapCharacter - * @param starForStop - * when true stop codons will translate as '*', otherwise as 'X' + * @param proteinSeqs * @return sequence ready to be added to alignment. */ - public static SequenceI translateCodingRegion(SequenceI selection, - String seqstring, int[] viscontigs, AlignedCodonFrame codons, - char gapCharacter, DBRefEntry product, final boolean starForStop) + protected SequenceI translateCodingRegion(SequenceI selection, + String seqstring, AlignedCodonFrame acf, + List proteinSeqs) { - java.util.List skip = new ArrayList(); + List skip = new ArrayList(); int skipint[] = null; ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring // intervals - int vc, scontigs[] = new int[viscontigs.length]; + int vc; + int[] scontigs = new int[contigs.length]; int npos = 0; - for (vc = 0; vc < viscontigs.length; vc += 2) + for (vc = 0; vc < contigs.length; vc += 2) { if (vc == 0) { - vismapping.addShift(npos, viscontigs[vc]); + vismapping.addShift(npos, contigs[vc]); } else { // hidden region - vismapping.addShift(npos, viscontigs[vc] - viscontigs[vc - 1] + 1); + vismapping.addShift(npos, contigs[vc] - contigs[vc - 1] + 1); } - scontigs[vc] = viscontigs[vc]; - scontigs[vc + 1] = viscontigs[vc + 1]; + scontigs[vc] = contigs[vc]; + scontigs[vc + 1] = contigs[vc + 1]; } - StringBuffer protein = new StringBuffer(); - String seq = seqstring.replace('U', 'T'); + // allocate a roughly sized buffer for the protein sequence + StringBuilder protein = new StringBuilder(seqstring.length() / 2); + String seq = seqstring.replace('U', 'T').replace('u', 'T'); char codon[] = new char[3]; - int cdp[] = new int[3], rf = 0, lastnpos = 0, nend; + int cdp[] = new int[3]; + int rf = 0; + int lastnpos = 0; + int nend; int aspos = 0; int resSize = 0; for (npos = 0, nend = seq.length(); npos < nend; npos++) { - if (!jalview.util.Comparison.isGap(seq.charAt(npos))) + if (!Comparison.isGap(seq.charAt(npos))) { cdp[rf] = npos; // store position codon[rf++] = seq.charAt(npos); // store base } - // filled an RF yet ? if (rf == 3) { + /* + * Filled up a reading frame... + */ + AlignedCodon alignedCodon = new AlignedCodon(cdp[0], cdp[1], cdp[2]); String aa = ResidueProperties.codonTranslate(new String(codon)); rf = 0; + final String gapString = String.valueOf(gapChar); if (aa == null) { - aa = String.valueOf(gapCharacter); + aa = gapString; if (skipint == null) { skipint = new int[] - { cdp[0], cdp[2] }; + { alignedCodon.pos1, alignedCodon.pos3 /* cdp[0], cdp[2] */}; } - skipint[1] = cdp[2]; + skipint[1] = alignedCodon.pos3; // cdp[2]; } else { @@ -599,52 +545,66 @@ public class Dna } if (aa.equals("STOP")) { - aa = starForStop ? "*" : "X"; + aa = STOP_X; } resSize++; } - // insert/delete gaps prior to this codon - if necessary boolean findpos = true; while (findpos) { - // first ensure that the codons array is long enough. - codons.checkCodonFrameWidth(aspos); - // now check to see if we place the aa at the current aspos in the - // protein alignment - switch (Dna.compare_codonpos(cdp, codons.codons[aspos])) + /* + * Compare this codon's base positions with those currently aligned to + * this column in the translation. + */ + final int compareCodonPos = compareCodonPos(alignedCodon, + alignedCodons[aspos]); + switch (compareCodonPos) { case -1: - codons.insertAAGap(aspos, gapCharacter); + + /* + * This codon should precede the mapped positions - need to insert a + * gap in all prior sequences. + */ + insertAAGap(aspos, proteinSeqs); findpos = false; break; + case +1: - // this aa appears after the aligned codons at aspos, so prefix it - // with a gap - aa = "" + gapCharacter + aa; + + /* + * This codon belongs after the aligned codons at aspos. Prefix it + * with a gap and try the next position. + */ + aa = gapString + aa; aspos++; - // if (aspos >= codons.aaWidth) - // codons.aaWidth = aspos + 1; - break; // check the next position for alignment + break; + case 0: - // codon aligns at aspos position. + + /* + * Exact match - codon 'belongs' at this translated position. + */ findpos = false; } } - // codon aligns with all other sequence residues found at aspos protein.append(aa); lastnpos = npos; - if (codons.codons[aspos] == null) + if (alignedCodons[aspos] == null) { // mark this column as aligning to this aligned reading frame - codons.codons[aspos] = new int[] - { cdp[0], cdp[1], cdp[2] }; + alignedCodons[aspos] = alignedCodon; + } + else if (!alignedCodons[aspos].equals(alignedCodon)) + { + throw new IllegalStateException("Tried to coalign " + + alignedCodons[aspos].toString() + " with " + + alignedCodon.toString()); } - if (aspos >= codons.aaWidth) + if (aspos >= aaWidth) { // update maximum alignment width - // (we can do this without calling checkCodonFrameWidth because it was - // already done above) - codons.setAaWidth(aspos); + aaWidth = aspos; } // ready for next translated reading frame alignment position (if any) aspos++; @@ -656,15 +616,14 @@ public class Dna protein.toString()); if (rf != 0) { - if (jalview.bin.Cache.log != null) + final String errMsg = "trimming contigs for incomplete terminal codon."; + if (Cache.log != null) { - jalview.bin.Cache.log - .debug("trimming contigs for incomplete terminal codon."); + Cache.log.debug(errMsg); } else { - System.err - .println("trimming contigs for incomplete terminal codon."); + System.err.println(errMsg); } // map and trim contigs to ORF region vc = scontigs.length - 1; @@ -694,7 +653,9 @@ public class Dna scontigs = t; } if (vc <= 0) + { scontigs = null; + } } if (scontigs != null) { @@ -705,7 +666,9 @@ public class Dna scontigs[vc] = selection.findPosition(scontigs[vc]); // not from 1! scontigs[vc + 1] = selection.findPosition(scontigs[vc + 1]); // exclusive if (scontigs[vc + 1] == selection.getEnd()) + { break; + } } // trim trailing empty intervals. if ((vc + 2) < scontigs.length) @@ -731,27 +694,19 @@ public class Dna MapList map = new MapList(scontigs, new int[] { 1, resSize }, 3, 1); - // update newseq as if it was generated as mapping from product - - if (product != null) - { - newseq.setName(product.getSource() + "|" - + product.getAccessionId()); - if (product.getMap() != null) - { - // Mapping mp = product.getMap(); - // newseq.setStart(mp.getPosition(scontigs[0])); - // newseq.setEnd(mp - // .getPosition(scontigs[scontigs.length - 1])); - } - } transferCodedFeatures(selection, newseq, map, null, null); - SequenceI rseq = newseq.deriveSequence(); // construct a dataset - // sequence for our new - // peptide, regardless. - // store a mapping (this actually stores a mapping between the dataset - // sequences for the two sequences - codons.addMap(selection, rseq, map); + + /* + * Construct a dataset sequence for our new peptide. + */ + SequenceI rseq = newseq.deriveSequence(); + + /* + * Store a mapping (between the dataset sequences for the two + * sequences). + */ + // SIDE-EFFECT: acf stores the aligned sequence reseq; to remove! + acf.addMap(selection, rseq, map); return rseq; } } @@ -761,6 +716,53 @@ public class Dna } /** + * Insert a gap into the aligned proteins and the codon mapping array. + * + * @param pos + * @param proteinSeqs + * @return + */ + protected void insertAAGap(int pos, + List proteinSeqs) + { + aaWidth++; + for (SequenceI seq : proteinSeqs) + { + seq.insertCharAt(pos, gapChar); + } + + checkCodonFrameWidth(); + if (pos < aaWidth) + { + aaWidth++; + + /* + * Shift from [pos] to the end one to the right, and null out [pos] + */ + System.arraycopy(alignedCodons, pos, alignedCodons, pos + 1, + alignedCodons.length - pos - 1); + alignedCodons[pos] = null; + } + } + + /** + * Check the codons array can accommodate a single insertion, if not resize + * it. + */ + protected void checkCodonFrameWidth() + { + if (alignedCodons[alignedCodons.length - 1] != null) + { + /* + * arraycopy insertion would bump a filled slot off the end, so expand. + */ + AlignedCodon[] c = new AlignedCodon[alignedCodons.length + 10]; + System.arraycopy(alignedCodons, 0, c, 0, alignedCodons.length); + alignedCodons = c; + } + } + + /** * Given a peptide newly translated from a dna sequence, copy over and set any * features on the peptide from the DNA. If featureTypes is null, all features * on the dna sequence are searched (rather than just the displayed ones), and @@ -770,20 +772,20 @@ public class Dna * @param pep * @param map * @param featureTypes - * hash who's keys are the displayed feature type strings + * hash whose keys are the displayed feature type strings * @param featureGroups * hash where keys are feature groups and values are Boolean objects * indicating if they are displayed. */ private static void transferCodedFeatures(SequenceI dna, SequenceI pep, - MapList map, Hashtable featureTypes, Hashtable featureGroups) + MapList map, Map featureTypes, + Map featureGroups) { - SequenceFeature[] sf = (dna.getDatasetSequence() != null ? dna + SequenceFeature[] sfs = (dna.getDatasetSequence() != null ? dna .getDatasetSequence() : dna).getSequenceFeatures(); Boolean fgstate; - jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils - .selectRefs(dna.getDBRef(), - jalview.datamodel.DBRefSource.DNACODINGDBS); + DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRef(), + DBRefSource.DNACODINGDBS); if (dnarefs != null) { // intersect with pep @@ -795,16 +797,16 @@ public class Dna } } } - if (sf != null) + if (sfs != null) { - for (int f = 0; f < sf.length; f++) + for (SequenceFeature sf : sfs) { - fgstate = (featureGroups == null) ? null : ((Boolean) featureGroups - .get(sf[f].featureGroup)); - if ((featureTypes == null || featureTypes.containsKey(sf[f] - .getType())) && (fgstate == null || fgstate.booleanValue())) + fgstate = (featureGroups == null) ? null : featureGroups + .get(sf.featureGroup); + if ((featureTypes == null || featureTypes.containsKey(sf.getType())) + && (fgstate == null || fgstate.booleanValue())) { - if (FeatureProperties.isCodingFeature(null, sf[f].getType())) + if (FeatureProperties.isCodingFeature(null, sf.getType())) { // if (map.intersectsFrom(sf[f].begin, sf[f].end)) { diff --git a/src/jalview/api/AlignViewportI.java b/src/jalview/api/AlignViewportI.java index 2dea15e..037f19e 100644 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@ -40,7 +40,7 @@ import java.util.Map; * @author jimp * */ -public interface AlignViewportI +public interface AlignViewportI extends ViewStyleI { int getCharWidth(); @@ -77,9 +77,7 @@ public interface AlignViewportI Hashtable[] getRnaStructureConsensusHash(); - boolean getIgnoreGapsConsensus(); - - boolean getCentreColumnLabels(); + boolean isIgnoreGapsConsensus(); boolean isCalculationInProgress(AlignmentAnnotation alignmentAnnotation); @@ -320,10 +318,9 @@ public interface AlignViewportI * first column (inclusive, from 0) * @param max * last column (exclusive) - * @return int[][] range of {start,end} visible positions TODO: change to list - * of int ranges + * @return int[][] range of {start,end} visible positions */ - int[][] getVisibleRegionBoundaries(int min, int max); + List getVisibleRegionBoundaries(int min, int max); /** * This method returns an array of new SequenceI objects derived from the @@ -354,4 +351,45 @@ public interface AlignViewportI boolean hasHiddenRows(); + /** + * + * @return a copy of this view's current display settings + */ + public ViewStyleI getViewStyle(); + + /** + * update the view's display settings with the given style set + * + * @param settingsForView + */ + public void setViewStyle(ViewStyleI settingsForView); + + /** + * Returns a viewport which holds the cDna for this (protein), or vice versa, + * or null if none is set. + * + * @return + */ + AlignViewportI getCodingComplement(); + + /** + * Sets the viewport which holds the cDna for this (protein), or vice versa. + * Implementation should guarantee that the reciprocal relationship is always + * set, i.e. each viewport is the complement of the other. + */ + void setCodingComplement(AlignViewportI sl); + + /** + * Answers true if viewport hosts DNA/RNA, else false. + * + * @return + */ + boolean isNucleotide(); + + /** + * Returns an id guaranteed to be unique for this viewport. + * + * @return + */ + String getViewId(); } diff --git a/src/jalview/api/AlignmentViewPanel.java b/src/jalview/api/AlignmentViewPanel.java index a68c1f6..ae9399d 100644 --- a/src/jalview/api/AlignmentViewPanel.java +++ b/src/jalview/api/AlignmentViewPanel.java @@ -32,6 +32,8 @@ import jalview.structure.StructureSelectionManager; public interface AlignmentViewPanel extends OOMHandlerI { + AlignViewportI getAlignViewport(); + AlignmentI getAlignment(); StructureSelectionManager getStructureSelectionManager(); diff --git a/src/jalview/api/SplitContainerI.java b/src/jalview/api/SplitContainerI.java new file mode 100644 index 0000000..b9c3121 --- /dev/null +++ b/src/jalview/api/SplitContainerI.java @@ -0,0 +1,38 @@ +package jalview.api; + +import jalview.datamodel.AlignmentI; + +/** + * Describes a visual container that can show two alignments. + * + * @author gmcarstairs + * + */ +public interface SplitContainerI +{ + + /** + * Set visibility of the specified split view component. + * + * @param alignFrame + * @param show + */ + // TODO need an interface for AlignFrame? + void setComplementVisible(Object alignFrame, boolean show); + + /** + * Returns the alignment that is complementary to the one in the given + * AlignFrame, or null. + */ + AlignmentI getComplement(Object af); + + /** + * Returns the frame title for the alignment that is complementary to the one + * in the given AlignFrame, or null. + * + * @param af + * @return + */ + String getComplementTitle(Object af); + +} diff --git a/src/jalview/api/ViewStyleI.java b/src/jalview/api/ViewStyleI.java new file mode 100644 index 0000000..8fa7f8f --- /dev/null +++ b/src/jalview/api/ViewStyleI.java @@ -0,0 +1,202 @@ +package jalview.api; + +import java.awt.Color; + +public interface ViewStyleI +{ + + void setColourAppliesToAllGroups(boolean b); + + boolean getColourAppliesToAllGroups(); + + boolean getAbovePIDThreshold(); + + void setIncrement(int inc); + + int getIncrement(); + + boolean getConservationSelected(); + + void setConservationSelected(boolean b); + + void setShowHiddenMarkers(boolean show); + + boolean getShowHiddenMarkers(); + + void setScaleRightWrapped(boolean b); + + void setScaleLeftWrapped(boolean b); + + void setScaleAboveWrapped(boolean b); + + boolean getScaleLeftWrapped(); + + boolean getScaleAboveWrapped(); + + boolean getScaleRightWrapped(); + + void setAbovePIDThreshold(boolean b); + + void setThreshold(int thresh); + + int getThreshold(); + + boolean getShowJVSuffix(); + + void setShowJVSuffix(boolean b); + + void setWrapAlignment(boolean state); + + void setShowText(boolean state); + + void setRenderGaps(boolean state); + + boolean getColourText(); + + void setColourText(boolean state); + + void setShowBoxes(boolean state); + + boolean getWrapAlignment(); + + boolean getShowText(); + + int getWrappedWidth(); + + void setWrappedWidth(int w); + + int getCharHeight(); + + void setCharHeight(int h); + + int getCharWidth(); + + void setCharWidth(int w); + + boolean getShowBoxes(); + + boolean getShowUnconserved(); + + void setShowUnconserved(boolean showunconserved); + + boolean isDisplayReferenceSeq(); + + void setDisplayReferenceSeq(boolean displayReferenceSeq); + + boolean isColourByReferenceSeq(); + + void setSeqNameItalics(boolean default1); + + void setShowSequenceFeatures(boolean b); + + boolean isShowSequenceFeatures(); + + boolean isRightAlignIds(); + + void setRightAlignIds(boolean rightAlignIds); + + boolean isShowAnnotation(); + + void setShowAnnotation(boolean b); + + void setShowSeqFeaturesHeight(boolean selected); + + boolean isShowSequenceFeaturesHeight(); + + void setColourByReferenceSeq(boolean colourByReferenceSeq); + + Color getTextColour(); + + Color getTextColour2(); + + int getThresholdTextColour(); + + boolean isConservationColourSelected(); + + boolean isRenderGaps(); + + boolean isShowColourText(); + + boolean isShowSeqFeaturesHeight(); + + void setConservationColourSelected(boolean conservationColourSelected); + + void setShowColourText(boolean showColourText); + + void setTextColour(Color textColour); + + void setThresholdTextColour(int thresholdTextColour); + + void setTextColour2(Color textColour2); + + boolean isSeqNameItalics(); + + void setUpperCasebold(boolean upperCasebold); + + boolean isUpperCasebold(); + + boolean sameStyle(ViewStyleI them); + + void setFontName(String name); + + void setFontStyle(int style); + + void setFontSize(int size); + + int getFontStyle(); + + String getFontName(); + + int getFontSize(); + + /** + * @return width of Sequence and Annotation ID margin. If less than zero, then + * width will be autocalculated + */ + int getIdWidth(); + + /** + * Set width if + * + * @param i + */ + + void setIdWidth(int i); + + /** + * centre columnar annotation labels in displayed alignment annotation + */ + boolean isCentreColumnLabels(); + + /** + * centre columnar annotation labels in displayed alignment annotation + */ + void setCentreColumnLabels(boolean centreColumnLabels); + + /** + * enable or disable the display of Database Cross References in the sequence + * ID tooltip + */ + void setShowDBRefs(boolean showdbrefs); + + /** + * + * @return true if Database References are to be displayed on tooltips. + */ + boolean isShowDBRefs(); + + /** + * + * @return true if Non-positional features are to be displayed on tooltips. + */ + boolean isShowNPFeats(); + + /** + * enable or disable the display of Non-Positional sequence features in the + * sequence ID tooltip + * + * @param show + */ + void setShowNPFeats(boolean shownpfeats); + +} diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java index c58fc5b..38a0f58 100644 --- a/src/jalview/appletgui/APopupMenu.java +++ b/src/jalview/appletgui/APopupMenu.java @@ -56,6 +56,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.util.List; import java.util.Vector; public class APopupMenu extends java.awt.PopupMenu implements @@ -113,10 +114,9 @@ public class APopupMenu extends java.awt.PopupMenu implements Menu editMenu = new Menu(MessageManager.getString("action.edit")); - MenuItem copy = new MenuItem( - MessageManager.getString("label.jalview_copy")); + MenuItem copy = new MenuItem(MessageManager.getString("action.copy")); - MenuItem cut = new MenuItem(MessageManager.getString("label.jalview_cut")); + MenuItem cut = new MenuItem(MessageManager.getString("action.cut")); MenuItem toUpper = new MenuItem( MessageManager.getString("label.to_upper_case")); @@ -619,10 +619,9 @@ public class APopupMenu extends java.awt.PopupMenu implements else if (source == toUpper || source == toLower || source == toggleCase) { SequenceGroup sg = ap.av.getSelectionGroup(); - Vector regions = new Vector(); if (sg != null) { - int[][] startEnd = ap.av.getVisibleRegionBoundaries( + List startEnd = ap.av.getVisibleRegionBoundaries( sg.getStartRes(), sg.getEndRes() + 1); String description; @@ -715,8 +714,7 @@ public class APopupMenu extends java.awt.PopupMenu implements // TODO consider using getSequenceSelection instead here cap.setText(new jalview.io.AppletFormatAdapter().formatSequences( - e.getActionCommand(), - ap.av.showJVSuffix, ap.av, true)); + e.getActionCommand(), ap.av.getShowJVSuffix(), ap.av, true)); } @@ -1024,7 +1022,7 @@ public class APopupMenu extends java.awt.PopupMenu implements int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup() .getName()); - sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus()); SliderPanel.showPIDSlider(); @@ -1032,7 +1030,7 @@ public class APopupMenu extends java.awt.PopupMenu implements else // remove PIDColouring { - sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } refresh(); diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index 1f32da0..447f5e3 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -23,6 +23,7 @@ package jalview.appletgui; import jalview.analysis.AlignmentSorter; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; +import jalview.api.AlignViewportI; import jalview.api.FeatureRenderer; import jalview.api.SequenceStructureBinding; import jalview.bin.JalviewLite; @@ -64,6 +65,7 @@ import jalview.schemes.TurnColourScheme; import jalview.schemes.ZappoColourScheme; import jalview.structure.StructureSelectionManager; import jalview.structures.models.AAStructureBindingModel; +import jalview.util.MappingUtils; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -92,6 +94,7 @@ import java.io.IOException; import java.net.URL; import java.net.URLEncoder; import java.util.Arrays; +import java.util.Deque; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -113,9 +116,33 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, String jalviewServletURL; - public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet, + /** + * Constructor that creates the frame and adds it to the display. + * + * @param al + * @param applet + * @param title + * @param embedded + */ + public AlignFrame(AlignmentI al, JalviewLite applet, String title, boolean embedded) { + this(al, applet, title, embedded, true); + } + + /** + * Constructor that optionally allows the frame to be displayed or only + * created. + * + * @param al + * @param applet + * @param title + * @param embedded + * @param addToDisplay + */ + public AlignFrame(AlignmentI al, JalviewLite applet, + String title, boolean embedded, boolean addToDisplay) + { if (applet != null) { jalviewServletURL = applet.getParameter("APPLICATION_URL"); @@ -157,7 +184,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, viewport.updateConservation(alignPanel); viewport.updateConsensus(alignPanel); - annotationPanelMenuItem.setState(viewport.showAnnotation); + annotationPanelMenuItem.setState(viewport.isShowAnnotation()); displayNonconservedMenuItem.setState(viewport.getShowUnconserved()); followMouseOverFlag.setState(viewport.getFollowHighlight()); showGroupConsensus.setState(viewport.isShowGroupConsensus()); @@ -167,7 +194,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, normSequenceLogo.setState(viewport.isNormaliseSequenceLogo()); applyToAllGroups.setState(viewport.getColourAppliesToAllGroups()); - seqLimits.setState(viewport.showJVSuffix); + seqLimits.setState(viewport.getShowJVSuffix()); if (applet != null) { @@ -233,8 +260,19 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, alignPanel.annotationPanelHolder.addKeyListener(this); alignPanel.annotationSpaceFillerHolder.addKeyListener(this); alignPanel.alabels.addKeyListener(this); - createAlignFrameWindow(embedded, title); + if (addToDisplay) + { + addToDisplay(embedded); + } + } + + /** + * @param embedded + */ + public void addToDisplay(boolean embedded) + { + createAlignFrameWindow(embedded); validate(); alignPanel.adjustAnnotationHeight(); alignPanel.paintAlignment(true); @@ -498,7 +536,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } case KeyEvent.VK_PAGE_UP: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(true); } @@ -510,7 +548,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, break; case KeyEvent.VK_PAGE_DOWN: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(false); } @@ -1181,11 +1219,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, Frame frame = new Frame(); frame.add(cap); jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage( - "label.alignment_output_command", new String[] + "label.alignment_output_command", new Object[] { e.getActionCommand() }), 600, 500); cap.setText(new AppletFormatAdapter().formatSequences( e.getActionCommand(), viewport.getAlignment(), - viewport.showJVSuffix)); + viewport.getShowJVSuffix())); } public void loadAnnotations() @@ -1398,12 +1436,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, void updateEditMenuBar() { - if (viewport.historyList.size() > 0) + if (viewport.getHistoryList().size() > 0) { undoMenuItem.setEnabled(true); - CommandI command = (CommandI) viewport.historyList.peek(); + CommandI command = viewport.getHistoryList().peek(); undoMenuItem.setLabel(MessageManager.formatMessage( - "label.undo_command", new String[] + "label.undo_command", new Object[] { command.getDescription() })); } else @@ -1412,13 +1450,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, undoMenuItem.setLabel(MessageManager.getString("action.undo")); } - if (viewport.redoList.size() > 0) + if (viewport.getRedoList().size() > 0) { redoMenuItem.setEnabled(true); - CommandI command = (CommandI) viewport.redoList.peek(); + CommandI command = viewport.getRedoList().peek(); redoMenuItem.setLabel(MessageManager.formatMessage( - "label.redo_command", new String[] + "label.redo_command", new Object[] { command.getDescription() })); } else @@ -1436,8 +1474,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { if (command.getSize() > 0) { - viewport.historyList.push(command); - viewport.redoList.removeAllElements(); + viewport.addToHistoryList(command); + viewport.clearRedoList(); updateEditMenuBar(); viewport.updateHiddenColumns(); } @@ -1451,13 +1489,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, */ protected void undoMenuItem_actionPerformed() { - if (viewport.historyList.size() < 1) + if (viewport.getHistoryList().isEmpty()) { return; } - CommandI command = (CommandI) viewport.historyList.pop(); - viewport.redoList.push(command); + CommandI command = viewport.getHistoryList().pop(); + viewport.addToRedoList(command); command.undoCommand(null); AlignViewport originalSource = getOriginatingSource(command); @@ -1483,13 +1521,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, */ protected void redoMenuItem_actionPerformed() { - if (viewport.redoList.size() < 1) + if (viewport.getRedoList().isEmpty()) { return; } - CommandI command = (CommandI) viewport.redoList.pop(); - viewport.historyList.push(command); + CommandI command = viewport.getRedoList().pop(); + viewport.addToHistoryList(command); command.doCommand(null); AlignViewport originalSource = getOriginatingSource(command); @@ -1549,6 +1587,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, return originalSource; } + /** + * Move the currently selected sequences up or down one position in the + * alignment + * + * @param up + */ public void moveSelectedSequences(boolean up) { SequenceGroup sg = viewport.getSelectionGroup(); @@ -1559,6 +1603,21 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, viewport.getAlignment().moveSelectedSequencesByOne(sg, up ? null : viewport.getHiddenRepSequences(), up); alignPanel.paintAlignment(true); + + /* + * Also move cDNA/protein complement sequences + */ + AlignViewportI complement = viewport.getCodingComplement(); + if (complement != null) + { + SequenceGroup mappedSelection = MappingUtils.mapSequenceGroup(sg, + viewport, complement); + complement.getAlignment().moveSelectedSequencesByOne(mappedSelection, + up ? null : complement.getHiddenRepSequences(), up); + // TODO need to trigger a repaint of the complementary panel - how? + // would prefer to handle in SplitFrame but it is not overriding key + // listener chiz + } } synchronized void slideSequences(boolean right, int size) @@ -1646,11 +1705,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } boolean appendHistoryItem = false; - if (viewport.historyList != null && viewport.historyList.size() > 0 - && viewport.historyList.peek() instanceof SlideSequencesCommand) + Deque historyList = viewport.getHistoryList(); + if (historyList != null && historyList.size() > 0 + && historyList.peek() instanceof SlideSequencesCommand) { appendHistoryItem = ssc - .appendSlideCommand((SlideSequencesCommand) viewport.historyList + .appendSlideCommand((SlideSequencesCommand) historyList .peek()); } @@ -1692,7 +1752,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, int hiddenOffset = viewport.getSelectionGroup().getStartRes(); for (int[] region : viewport.getColumnSelection().getHiddenColumns()) { - copiedHiddenColumns.addElement(new int[] { region[0] - hiddenOffset, region[1] - hiddenOffset }); } @@ -2256,8 +2315,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, newaf.setTitle(title.toString()); - newaf.viewport.historyList = viewport.historyList; - newaf.viewport.redoList = viewport.redoList; + newaf.viewport.setHistoryList(viewport.getHistoryList()); + newaf.viewport.setRedoList(viewport.getRedoList()); return newaf; } @@ -2349,7 +2408,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, protected void displayNonconservedMenuItem_actionPerformed() { - viewport.setShowunconserved(displayNonconservedMenuItem.getState()); + viewport.setShowUnconserved(displayNonconservedMenuItem.getState()); alignPanel.paintAlignment(true); } @@ -3516,46 +3575,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, * true to attach the view to the applet area on the page rather than * in a new window */ - public void createAlignFrameWindow(boolean reallyEmbedded, String title) + public void createAlignFrameWindow(boolean reallyEmbedded) { if (reallyEmbedded) { - // //// - // Explicly build the embedded menu panel for the on-page applet - // - // view cannot be closed if its actually on the page - fileMenu.remove(closeMenuItem); - fileMenu.remove(3); // Remove Seperator - embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, "Arial", - Font.PLAIN, 11, false); // use our own fonts. - // and actually add the components to the applet area - viewport.applet.setLayout(new BorderLayout()); - viewport.applet.add(embeddedMenu, BorderLayout.NORTH); - viewport.applet.add(statusBar, BorderLayout.SOUTH); - alignPanel.setSize(viewport.applet.getSize().width, - viewport.applet.getSize().height - embeddedMenu.HEIGHT - - statusBar.HEIGHT); - viewport.applet.add(alignPanel, BorderLayout.CENTER); - final AlignFrame me = this; - viewport.applet.addFocusListener(new FocusListener() - { - - @Override - public void focusLost(FocusEvent e) - { - if (me.viewport.applet.currentAlignFrame == me) - { - me.viewport.applet.currentAlignFrame = null; - } - } - - @Override - public void focusGained(FocusEvent e) - { - me.viewport.applet.currentAlignFrame = me; - } - }); - viewport.applet.validate(); + embedAlignFrameInApplet(viewport.applet); } else { @@ -3564,19 +3588,69 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, // if (embedMenuIfNeeded(alignPanel)) { - // adjust for status bar height too - alignPanel.setSize(getSize().width, getSize().height - - statusBar.HEIGHT); + /* + * adjust for status bar height too. ? pointless as overridden by layout + * manager + */ + alignPanel.setSize(getSize().width, + getSize().height - statusBar.getHeight()); } add(statusBar, BorderLayout.SOUTH); add(alignPanel, BorderLayout.CENTER); // and register with the applet so it can pass external API calls to us - jalview.bin.JalviewLite.addFrame(this, title, DEFAULT_WIDTH, + jalview.bin.JalviewLite.addFrame(this, this.getTitle(), + DEFAULT_WIDTH, DEFAULT_HEIGHT); } } /** + * Add the components of this AlignFrame to the applet container. + * + * @param theApplet + */ + public void embedAlignFrameInApplet(final JalviewLite theApplet) + { + // //// + // Explicitly build the embedded menu panel for the on-page applet + // + // view cannot be closed if its actually on the page + fileMenu.remove(closeMenuItem); + fileMenu.remove(3); // Remove Separator + // construct embedded menu, using default font + embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, false, false); + // and actually add the components to the applet area + theApplet.setLayout(new BorderLayout()); + theApplet.add(embeddedMenu, BorderLayout.NORTH); + theApplet.add(statusBar, BorderLayout.SOUTH); + // TODO should size be left to the layout manager? + alignPanel.setSize(theApplet.getSize().width, + theApplet.getSize().height - embeddedMenu.getHeight() + - statusBar.getHeight()); + theApplet.add(alignPanel, BorderLayout.CENTER); + final AlignFrame me = this; + theApplet.addFocusListener(new FocusListener() + { + + @Override + public void focusLost(FocusEvent e) + { + if (theApplet.currentAlignFrame == me) + { + theApplet.currentAlignFrame = null; + } + } + + @Override + public void focusGained(FocusEvent e) + { + theApplet.currentAlignFrame = me; + } + }); + theApplet.validate(); + } + + /** * create a new binding between structures in an existing jmol viewer instance * and an alignpanel with sequences that have existing PDBFile entries. Note, * this does not open a new Jmol window, or modify the display of the diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index 84a62ae..58b2644 100644 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -23,6 +23,7 @@ package jalview.appletgui; import jalview.analysis.NJTree; import jalview.api.AlignViewportI; import jalview.bin.JalviewLite; +import jalview.commands.CommandI; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.Sequence; @@ -30,15 +31,16 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.UserColourScheme; +import jalview.structure.CommandListener; import jalview.structure.SelectionSource; +import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; import jalview.viewmodel.AlignmentViewport; import java.awt.Font; -import java.util.Stack; public class AlignViewport extends AlignmentViewport implements - AlignViewportI, SelectionSource, VamsasSource + AlignViewportI, SelectionSource, VamsasSource, CommandListener { int startRes; @@ -50,54 +52,16 @@ public class AlignViewport extends AlignmentViewport implements boolean cursorMode = false; - boolean showJVSuffix = true; - - boolean showText = true; - - boolean showColourText = false; - - boolean showBoxes = true; - - boolean wrapAlignment = false; - - boolean renderGaps = true; - - boolean showAnnotation = true; - - boolean upperCasebold = false; - - int charHeight; - - int charWidth; - - int wrappedWidth; - Font font = new Font("SansSerif", Font.PLAIN, 10); boolean validCharWidth = true; - int threshold; - - int increment; - NJTree currentTree = null; - boolean scaleAboveWrapped = true; - - boolean scaleLeftWrapped = true; - - boolean scaleRightWrapped = true; - - boolean showHiddenMarkers = true; - public jalview.bin.JalviewLite applet; boolean MAC = false; - Stack historyList = new Stack(); - - Stack redoList = new Stack(); - private AnnotationColumnChooser annotationColumnSelectionState; public void finalize() @@ -110,9 +74,10 @@ public class AlignViewport extends AlignmentViewport implements public AlignViewport(AlignmentI al, JalviewLite applet) { + super(); calculator = new jalview.workers.AlignCalcManager(); this.applet = applet; - setAlignment(al); + alignment = al; // we always pad gaps this.setPadGaps(true); this.startRes = 0; @@ -175,10 +140,11 @@ public class AlignViewport extends AlignmentViewport implements if (applet != null) { - showJVSuffix = applet.getDefaultParameter("showFullId", showJVSuffix); + setShowJVSuffix(applet.getDefaultParameter("showFullId", + getShowJVSuffix())); - showAnnotation = applet.getDefaultParameter("showAnnotation", - showAnnotation); + setShowAnnotation(applet.getDefaultParameter("showAnnotation", + isShowAnnotation())); showConservation = applet.getDefaultParameter("showConservation", showConservation); @@ -188,15 +154,15 @@ public class AlignViewport extends AlignmentViewport implements showConsensus = applet.getDefaultParameter("showConsensus", showConsensus); - showUnconserved = applet.getDefaultParameter("showUnconserved", - showUnconserved); + setShowUnconserved(applet.getDefaultParameter("showUnconserved", + getShowUnconserved())); String param = applet.getParameter("upperCase"); if (param != null) { if (param.equalsIgnoreCase("bold")) { - upperCasebold = true; + setUpperCasebold(true); } } sortByTree = applet.getDefaultParameter("sortByTree", sortByTree); @@ -368,13 +334,13 @@ public class AlignViewport extends AlignmentViewport implements java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font); setCharHeight((int) (heightScale * fm.getHeight())); - charWidth = (int) (widthScale * fm.charWidth('M')); + setCharWidth((int) (widthScale * fm.charWidth('M'))); - if (upperCasebold) + if (isUpperCasebold()) { Font f2 = new Font(f.getName(), Font.BOLD, f.getSize()); fm = nullFrame.getGraphics().getFontMetrics(f2); - charWidth = (int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10)); + setCharWidth((int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10))); } } @@ -383,98 +349,6 @@ public class AlignViewport extends AlignmentViewport implements return font; } - public int getCharWidth() - { - return charWidth; - } - - public void setCharHeight(int h) - { - this.charHeight = h; - } - - public int getCharHeight() - { - return charHeight; - } - - public void setWrappedWidth(int w) - { - this.wrappedWidth = w; - } - - public int getwrappedWidth() - { - return wrappedWidth; - } - - public AlignmentI getAlignment() - { - return alignment; - } - - public void setAlignment(AlignmentI align) - { - this.alignment = align; - } - - public void setWrapAlignment(boolean state) - { - wrapAlignment = state; - } - - public void setShowText(boolean state) - { - showText = state; - } - - public void setRenderGaps(boolean state) - { - renderGaps = state; - } - - public boolean getColourText() - { - return showColourText; - } - - public void setColourText(boolean state) - { - showColourText = state; - } - - public void setShowBoxes(boolean state) - { - showBoxes = state; - } - - public boolean getWrapAlignment() - { - return wrapAlignment; - } - - public boolean getShowText() - { - return showText; - } - - public boolean getShowBoxes() - { - return showBoxes; - } - - public char getGapCharacter() - { - return getAlignment().getGapCharacter(); - } - - public void setGapCharacter(char gap) - { - if (getAlignment() != null) - { - getAlignment().setGapCharacter(gap); - } - } public void resetSeqLimits(int height) { @@ -491,77 +365,6 @@ public class AlignViewport extends AlignmentViewport implements return currentTree; } - public boolean getShowJVSuffix() - { - return showJVSuffix; - } - - public void setShowJVSuffix(boolean b) - { - showJVSuffix = b; - } - - public boolean getShowAnnotation() - { - return showAnnotation; - } - - public void setShowAnnotation(boolean b) - { - showAnnotation = b; - } - - public boolean getScaleAboveWrapped() - { - return scaleAboveWrapped; - } - - public boolean getScaleLeftWrapped() - { - return scaleLeftWrapped; - } - - public boolean getScaleRightWrapped() - { - return scaleRightWrapped; - } - - public void setScaleAboveWrapped(boolean b) - { - scaleAboveWrapped = b; - } - - public void setScaleLeftWrapped(boolean b) - { - scaleLeftWrapped = b; - } - - public void setScaleRightWrapped(boolean b) - { - scaleRightWrapped = b; - } - - public void setIgnoreGapsConsensus(boolean b) - { - ignoreGapsInConsensusCalculation = b; - updateConsensus(null); - if (globalColourScheme != null) - { - globalColourScheme.setThreshold(globalColourScheme.getThreshold(), - ignoreGapsInConsensusCalculation); - - } - } - - public boolean getShowHiddenMarkers() - { - return showHiddenMarkers; - } - - public void setShowHiddenMarkers(boolean show) - { - showHiddenMarkers = show; - } boolean centreColumnLabels; @@ -590,13 +393,25 @@ public class AlignViewport extends AlignmentViewport implements public void sendSelection() { - jalview.structure.StructureSelectionManager - .getStructureSelectionManager(applet).sendSelection( + getStructureSelectionManager().sendSelection( new SequenceGroup(getSelectionGroup()), new ColumnSelection(getColumnSelection()), this); } /** + * Returns an instance of the StructureSelectionManager scoped to this applet + * instance. + * + * @return + */ + @Override + public StructureSelectionManager getStructureSelectionManager() + { + return jalview.structure.StructureSelectionManager + .getStructureSelectionManager(applet); + } + + /** * synthesize a column selection if none exists so it covers the given * selection group. if wholewidth is false, no column selection is made if the * selection group covers the whole alignment width. @@ -659,4 +474,41 @@ public class AlignViewport extends AlignmentViewport implements this.annotationColumnSelectionState = annotationColumnSelectionState; } + @Override + public void mirrorCommand(CommandI command, boolean undo, + StructureSelectionManager ssm, VamsasSource source) + { + // TODO refactor so this can be pulled up to superclass or controller + /* + * Do nothing unless we are a 'complement' of the source. May replace this + * with direct calls not via SSM. + */ + if (source instanceof AlignViewportI + && ((AlignViewportI) source).getCodingComplement() == this) + { + // ok to continue; + } + else + { + return; + } + + CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(), + getGapCharacter()); + if (mappedCommand != null) + { + mappedCommand.doCommand(null); + firePropertyChange("alignment", null, getAlignment().getSequences()); + + // ap.scalePanelHolder.repaint(); + // ap.repaint(); + } + } + + @Override + public VamsasSource getVamsasSource() + { + return this; + } + } diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index 5308a42..6f843d0 100644 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -20,6 +20,7 @@ */ package jalview.appletgui; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.datamodel.AlignmentI; import jalview.datamodel.SearchResults; @@ -100,7 +101,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, sequenceHolderPanel.add(annotationPanelHolder, BorderLayout.SOUTH); alabels = new AnnotationLabels(this); - setAnnotationVisible(av.showAnnotation); + setAnnotationVisible(av.isShowAnnotation()); idPanelHolder.add(idPanel, BorderLayout.CENTER); idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER); @@ -153,6 +154,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, }); } + @Override + public AlignViewportI getAlignViewport() + { + return av; + } public SequenceRenderer getSequenceRenderer() { return seqPanel.seqCanvas.sr; @@ -190,8 +196,9 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, idPanel.idCanvas.image = null; FontMetrics fm = getFontMetrics(av.getFont()); - scalePanel.setSize(new Dimension(10, av.charHeight + fm.getDescent())); - idwidthAdjuster.setSize(new Dimension(10, av.charHeight + scalePanel.setSize(new Dimension(10, av.getCharHeight() + + fm.getDescent())); + idwidthAdjuster.setSize(new Dimension(10, av.getCharHeight() + fm.getDescent())); av.updateSequenceIdColours(); annotationPanel.image = null; @@ -375,7 +382,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { start = ostart; } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { /* * int spos=av.getStartRes(),sqpos=av.getStartSeq(); if ((startv = @@ -449,7 +456,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, public void setAnnotationVisible(boolean b) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { annotationSpaceFillerHolder.setVisible(b); annotationPanelHolder.setVisible(b); @@ -473,7 +480,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, // this is called after loading new annotation onto alignment if (alignFrame.getSize().height == 0) { - System.out.println("NEEDS FIXING"); + System.out + .println("adjustAnnotationHeight frame size zero NEEDS FIXING"); } fontChanged(); validateAnnotationDimensions(true); @@ -566,7 +574,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, annotationPanelHolder.setVisible(false); annotationSpaceFillerHolder.setVisible(false); } - else if (av.showAnnotation) + else if (av.isShowAnnotation()) { annotationPanelHolder.setVisible(true); annotationSpaceFillerHolder.setVisible(true); @@ -648,8 +656,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, } ; - hextent = seqPanel.seqCanvas.getSize().width / av.charWidth; - vextent = seqPanel.seqCanvas.getSize().height / av.charHeight; + hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth(); + vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight(); if (hextent > width) { @@ -694,7 +702,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, av.setEndSeq(endSeq); av.setStartRes(x); - av.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av.charWidth)) - 1); + av.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av + .getCharWidth())) - 1); hscroll.setValues(x, hextent, 0, width); vscroll.setValues(y, vextent, 0, height); @@ -776,7 +785,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, seqPanel.seqCanvas.fastPaint(scrollX, scrollY); scalePanel.repaint(); - if (av.getShowAnnotation()) + if (av.isShowAnnotation()) { annotationPanel.fastPaint(av.getStartRes() - oldX); } @@ -847,9 +856,9 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, seqPanel.seqCanvas.repaint(); idPanel.idCanvas.repaint(); - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { - if (av.showAnnotation) + if (av.isShowAnnotation()) { alabels.repaint(); annotationPanel.repaint(); diff --git a/src/jalview/appletgui/AnnotationLabels.java b/src/jalview/appletgui/AnnotationLabels.java index 6aaa033..fdbf1ff 100755 --- a/src/jalview/appletgui/AnnotationLabels.java +++ b/src/jalview/appletgui/AnnotationLabels.java @@ -311,8 +311,8 @@ public class AnnotationLabels extends Panel implements ActionListener, .getSize(), f = ap.seqPanelHolder.getSize(); int dif = evt.getY() - oldY; - dif /= ap.av.charHeight; - dif *= ap.av.charHeight; + dif /= ap.av.getCharHeight(); + dif *= ap.av.getCharHeight(); if ((d.height - dif) > 20 && (f.height + dif) > 20) { @@ -482,7 +482,7 @@ public class AnnotationLabels extends Panel implements ActionListener, MessageManager.getString("label.ignore_gaps_consensus"), (aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef .getIgnoreGapsConsensus() : ap.av - .getIgnoreGapsConsensus()); + .isIgnoreGapsConsensus()); final AlignmentAnnotation aaa = aa[selectedRow]; cbmi.addItemListener(new ItemListener() { @@ -495,7 +495,7 @@ public class AnnotationLabels extends Panel implements ActionListener, } else { - ap.av.setIgnoreGapsConsensus(cbmi.getState()); + ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap); } ap.paintAlignment(true); } @@ -813,7 +813,7 @@ public class AnnotationLabels extends Panel implements ActionListener, dragEvent.getY()); } - if (!av.wrapAlignment && ((aa == null) || (aa.length < 1))) + if (!av.getWrapAlignment() && ((aa == null) || (aa.length < 1))) { g.setColor(Color.black); g.drawString(MessageManager.getString("label.right_click"), 2, 8); diff --git a/src/jalview/appletgui/AnnotationPanel.java b/src/jalview/appletgui/AnnotationPanel.java index 22996f7..1b4c8c4 100755 --- a/src/jalview/appletgui/AnnotationPanel.java +++ b/src/jalview/appletgui/AnnotationPanel.java @@ -20,16 +20,30 @@ */ package jalview.appletgui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; - -import jalview.datamodel.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Annotation; import jalview.renderer.AnnotationRenderer; import jalview.renderer.AwtRenderPanelI; import jalview.util.MessageManager; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + public class AnnotationPanel extends Panel implements AwtRenderPanelI, AdjustmentListener, ActionListener, MouseListener, MouseMotionListener @@ -40,8 +54,6 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, int activeRow = -1; - Vector activeRes; - final String HELIX = "Helix"; final String SHEET = "Sheet"; @@ -140,7 +152,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, if (av.getColumnSelection() != null && av.getColumnSelection().size() > 0 && anot[av.getColumnSelection().getMin()] != null) + { label = anot[av.getColumnSelection().getMin()].displayCharacter; + } if (evt.getActionCommand().equals(REMOVE)) { @@ -168,7 +182,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, int index = av.getColumnSelection().columnAt(i); if (!av.getColumnSelection().isVisible(index)) + { continue; + } if (anot[index] == null) { @@ -190,7 +206,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, int index = av.getColumnSelection().columnAt(i); if (!av.getColumnSelection().isVisible(index)) + { continue; + } if (anot[index] == null) { @@ -249,14 +267,15 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, int index = av.getColumnSelection().columnAt(i); if (!av.getColumnSelection().isVisible(index)) + { continue; + } if (anot[index] == null) { anot[index] = new Annotation(label, "", type, 0); } - anot[index].secondaryStructure = type != 'S' ? type : label .length() == 0 ? ' ' : label.charAt(0); anot[index].displayCharacter = label; @@ -278,9 +297,13 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, ap.alignFrame, "Enter Label", 400, 200, true); if (dialog.accept) + { return dialog.getName(); + } else + { return null; + } } @Override @@ -363,11 +386,6 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, return; } - if (aa == null) - { - return; - } - ap.scalePanel.mousePressed(evt); } @@ -513,15 +531,6 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, } } } - - if (activeRes == null) - { - activeRes = new Vector(); - activeRes.addElement(String.valueOf(i)); - return; - } - - activeRes.addElement(String.valueOf(i)); } @Override @@ -574,13 +583,13 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, return; } - gg.copyArea(0, 0, imgWidth, getSize().height, -horizontal - * av.charWidth, 0); + gg.copyArea(0, 0, imgWidth, getSize().height, + -horizontal * av.getCharWidth(), 0); int sr = av.startRes, er = av.endRes + 1, transX = 0; if (horizontal > 0) // scrollbar pulled right, image to the left { - transX = (er - sr - horizontal) * av.charWidth; + transX = (er - sr - horizontal) * av.getCharWidth(); sr = er - horizontal; } else if (horizontal < 0) @@ -614,7 +623,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, g.setFont(ofont); g.setColor(Color.white); - g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getSize().height); + g.fillRect(0, 0, (endRes - startRes) * av.getCharWidth(), + getSize().height); if (fm == null) { @@ -683,6 +693,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI, return bounds; } else + { return null; + } } } diff --git a/src/jalview/appletgui/CutAndPasteTransfer.java b/src/jalview/appletgui/CutAndPasteTransfer.java index 0a9ca56..248153f 100644 --- a/src/jalview/appletgui/CutAndPasteTransfer.java +++ b/src/jalview/appletgui/CutAndPasteTransfer.java @@ -20,12 +20,17 @@ */ package jalview.appletgui; +import jalview.analysis.AlignmentUtils; +import jalview.analysis.AlignmentUtils.MappingResult; +import jalview.bin.JalviewLite; import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; import jalview.datamodel.Sequence; import jalview.io.AnnotationFile; import jalview.io.AppletFormatAdapter; import jalview.io.IdentifyFile; +import jalview.io.NewickFile; import jalview.io.TCoffeeScoreFile; import jalview.schemes.TCoffeeColourScheme; import jalview.util.MessageManager; @@ -35,6 +40,7 @@ import java.awt.Button; import java.awt.Dialog; import java.awt.Font; import java.awt.Frame; +import java.awt.Label; import java.awt.Panel; import java.awt.TextArea; import java.awt.event.ActionEvent; @@ -142,149 +148,261 @@ public class CutAndPasteTransfer extends Panel implements ActionListener, if (pdbImport) { - PDBEntry pdb = new PDBEntry(); - pdb.setFile(text); + openPdbViewer(text); - if (alignFrame.alignPanel.av.applet.jmolAvailable) - { - new jalview.appletgui.AppletJmol(pdb, new Sequence[] - { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE); - } - else + } + else if (treeImport) + { + if (!loadTree()) { - new MCview.AppletPDBViewer(pdb, new Sequence[] - { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE); + return; } + } + else if (annotationImport) + { + loadAnnotations(); + } + else if (alignFrame != null) + { + loadAlignment(text, newWindow); + } + // TODO: dialog should indicate if data was parsed correctly or not - see + // JAL-1102 + if (this.getParent() instanceof Frame) + { + ((Frame) this.getParent()).setVisible(false); } - else if (treeImport) + else { - try - { - jalview.io.NewickFile fin = new jalview.io.NewickFile( - textarea.getText(), "Paste"); + ((Dialog) this.getParent()).setVisible(false); + } + } - fin.parse(); - if (fin.getTree() != null) - { - alignFrame.loadTree(fin, "Pasted tree file"); - } + /** + * Parses text as Newick Tree format, and loads on to the alignment. Returns + * true if successful, else false. + */ + protected boolean loadTree() + { + try + { + NewickFile fin = new NewickFile(textarea.getText(), "Paste"); - } catch (Exception ex) + fin.parse(); + if (fin.getTree() != null) { - // TODO: JAL-1102 - should have a warning message in dialog, not simply - // overwrite the broken input data with the exception - textarea.setText(MessageManager.formatMessage( - "label.could_not_parse_newick_file", new String[] - { ex.getMessage() })); - return; + alignFrame.loadTree(fin, "Pasted tree file"); + return true; } + } catch (Exception ex) + { + // TODO: JAL-1102 - should have a warning message in dialog, not simply + // overwrite the broken input data with the exception + textarea.setText(MessageManager.formatMessage( + "label.could_not_parse_newick_file", new Object[] + { ex.getMessage() })); + return false; } - else if (annotationImport) + return false; + } + + /** + * Parse text as an alignment file and add to the current or a new window. + * + * @param text + * @param newWindow + */ + protected void loadAlignment(String text, boolean newWindow) + { + Alignment al = null; + + String format = new IdentifyFile().Identify(text, + AppletFormatAdapter.PASTE); + try + { + al = new AppletFormatAdapter().readFile(text, + AppletFormatAdapter.PASTE, format); + } catch (java.io.IOException ex) + { + ex.printStackTrace(); + } + + if (al != null) { - TCoffeeScoreFile tcf = null; - try + al.setDataset(null); // set dataset on alignment/sequences + if (openSplitFrame(al, format)) { - tcf = new TCoffeeScoreFile(textarea.getText(), - jalview.io.AppletFormatAdapter.PASTE); - if (tcf.isValid()) - { - if (tcf.annotateAlignment(alignFrame.viewport.getAlignment(), - true)) - { - alignFrame.tcoffeeColour.setEnabled(true); - alignFrame.alignPanel.fontChanged(); - alignFrame.changeColour(new TCoffeeColourScheme( - alignFrame.viewport.getAlignment())); - alignFrame.statusBar - .setText(MessageManager - .getString("label.successfully_pasted_tcoffee_scores_to_alignment")); - } - else - { - // file valid but didn't get added to alignment for some reason - alignFrame.statusBar.setText(MessageManager.formatMessage( - "label.failed_add_tcoffee_scores", - new String[] - { (tcf.getWarningMessage() != null ? tcf - .getWarningMessage() : "") })); - } - } - else - { - tcf = null; - } - } catch (Exception x) + return; + } + if (newWindow) { - tcf = null; + AlignFrame af = new AlignFrame(al, alignFrame.viewport.applet, + "Cut & Paste input - " + format, false); + af.statusBar + .setText(MessageManager + .getString("label.successfully_pasted_annotation_to_alignment")); } - if (tcf == null) + else { - if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport, - textarea.getText(), - jalview.io.AppletFormatAdapter.PASTE)) + alignFrame.addSequences(al.getSequencesArray()); + alignFrame.statusBar.setText(MessageManager + .getString("label.successfully_pasted_alignment_file")); + } + } + } + + /** + * Check whether the new alignment could be mapped to the current one as + * cDNA/protein, if so offer the option to open as split frame view. Returns + * true if a split frame view is opened, false if not. + * + * @param al + * @return + */ + protected boolean openSplitFrame(Alignment al, String format) + { + final AlignmentI thisAlignment = this.alignFrame.getAlignViewport().getAlignment(); + if (thisAlignment.isNucleotide() == al.isNucleotide()) + { + // both nucleotide or both protein + return false; + } + AlignmentI protein = thisAlignment.isNucleotide() ? al : thisAlignment; + AlignmentI dna = thisAlignment.isNucleotide() ? thisAlignment : al; + MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, dna); + if (mapped == MappingResult.NotMapped) + { + return false; + } + + /* + * A mapping is possible; ask user if they want a split frame. + */ + String title = MessageManager.getString("label.open_split_window"); + final JVDialog dialog = new JVDialog((Frame) this.getParent(), title, + true, 100, 400); + dialog.ok.setLabel(MessageManager.getString("action.yes")); + dialog.cancel.setLabel(MessageManager.getString("action.no")); + Panel question = new Panel(new BorderLayout()); + final String text = MessageManager + .getString("label.open_split_window?"); + question.add(new Label(text, Label.CENTER), BorderLayout.CENTER); + dialog.setMainPanel(question); + dialog.setVisible(true); + dialog.toFront(); + + if (!dialog.accept) + { + return false; + } + + /* + * Open SplitFrame with DNA above and protein below, including the alignment + * from textbox and a copy of the original. + */ + final JalviewLite applet = this.alignFrame.viewport.applet; + AlignFrame copyFrame = new AlignFrame( + this.alignFrame.viewport.getAlignment(), applet, + alignFrame.getTitle(), false, false); + AlignFrame newFrame = new AlignFrame(al, alignFrame.viewport.applet, + "Cut & Paste input - " + format, false, false); + AlignFrame dnaFrame = al.isNucleotide() ? newFrame : copyFrame; + AlignFrame proteinFrame = al.isNucleotide() ? copyFrame + : newFrame; + SplitFrame sf = new SplitFrame(dnaFrame, proteinFrame); + sf.addToDisplay(false, applet); + return true; + } + + /** + * Parse the text as a TCoffee score file, if successful add scores as + * alignment annotations. + */ + protected void loadAnnotations() + { + TCoffeeScoreFile tcf = null; + try + { + tcf = new TCoffeeScoreFile(textarea.getText(), + jalview.io.AppletFormatAdapter.PASTE); + if (tcf.isValid()) + { + if (tcf.annotateAlignment(alignFrame.viewport.getAlignment(), + true)) { + alignFrame.tcoffeeColour.setEnabled(true); alignFrame.alignPanel.fontChanged(); - alignFrame.alignPanel.setScrollValues(0, 0); + alignFrame.changeColour(new TCoffeeColourScheme( + alignFrame.viewport.getAlignment())); alignFrame.statusBar .setText(MessageManager - .getString("label.successfully_pasted_annotation_to_alignment")); - + .getString("label.successfully_pasted_tcoffee_scores_to_alignment")); } else { - if (!alignFrame.parseFeaturesFile(textarea.getText(), - jalview.io.AppletFormatAdapter.PASTE)) - { - alignFrame.statusBar - .setText(MessageManager - .getString("label.couldnt_parse_pasted_text_as_valid_annotation_feature_GFF_tcoffee_file")); - } + // file valid but didn't get added to alignment for some reason + alignFrame.statusBar.setText(MessageManager.formatMessage( + "label.failed_add_tcoffee_scores", + new Object[] + { (tcf.getWarningMessage() != null ? tcf + .getWarningMessage() : "") })); } } + else + { + tcf = null; + } + } catch (Exception x) + { + tcf = null; } - else if (alignFrame != null) + if (tcf == null) { - Alignment al = null; - - String format = new IdentifyFile().Identify(text, - AppletFormatAdapter.PASTE); - try + if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport, + textarea.getText(), + jalview.io.AppletFormatAdapter.PASTE)) { - al = new AppletFormatAdapter().readFile(text, - AppletFormatAdapter.PASTE, format); - } catch (java.io.IOException ex) - { - ex.printStackTrace(); - } + alignFrame.alignPanel.fontChanged(); + alignFrame.alignPanel.setScrollValues(0, 0); + alignFrame.statusBar + .setText(MessageManager + .getString("label.successfully_pasted_annotation_to_alignment")); - if (al != null) + } + else { - if (newWindow) + if (!alignFrame.parseFeaturesFile(textarea.getText(), + jalview.io.AppletFormatAdapter.PASTE)) { - AlignFrame af = new AlignFrame(al, alignFrame.viewport.applet, - "Cut & Paste input - " + format, false); - af.statusBar + alignFrame.statusBar .setText(MessageManager - .getString("label.successfully_pasted_annotation_to_alignment")); - } - else - { - alignFrame.addSequences(al.getSequencesArray()); - alignFrame.statusBar.setText(MessageManager - .getString("label.successfully_pasted_alignment_file")); + .getString("label.couldnt_parse_pasted_text_as_valid_annotation_feature_GFF_tcoffee_file")); } } } - // TODO: dialog should indicate if data was parsed correctly or not - see - // JAL-1102 - if (this.getParent() instanceof Frame) + } + + /** + * Open a Jmol viewer (if available), failing that the built-in PDB viewer, + * passing the input text as the PDB file data. + * + * @param text + */ + protected void openPdbViewer(String text) + { + PDBEntry pdb = new PDBEntry(); + pdb.setFile(text); + + if (alignFrame.alignPanel.av.applet.jmolAvailable) { - ((Frame) this.getParent()).setVisible(false); + new jalview.appletgui.AppletJmol(pdb, new Sequence[] + { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE); } else { - ((Dialog) this.getParent()).setVisible(false); + new MCview.AppletPDBViewer(pdb, new Sequence[] + { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE); } } diff --git a/src/jalview/appletgui/EmbmenuFrame.java b/src/jalview/appletgui/EmbmenuFrame.java index c527308..a4c1006 100644 --- a/src/jalview/appletgui/EmbmenuFrame.java +++ b/src/jalview/appletgui/EmbmenuFrame.java @@ -20,8 +20,6 @@ */ package jalview.appletgui; -import jalview.util.MessageManager; - import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; @@ -35,12 +33,12 @@ import java.awt.Panel; import java.awt.PopupMenu; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import java.util.Enumeration; -import java.util.Hashtable; +import java.util.HashMap; +import java.util.Map; /** - * This class implements a pattern form embedding toolbars as a panel with - * popups for situations where the system menu bar is either invisible or + * This class implements a pattern for embedding toolbars as a panel with popups + * for situations where the system menu bar is either invisible or * inappropriate. It was derived from the code for embedding the jalview applet * alignFrame as a component on the web-page, which requires the local * alignFrame menu to be attached to that panel rather than placed on the parent @@ -53,10 +51,15 @@ import java.util.Hashtable; */ public class EmbmenuFrame extends Frame implements MouseListener { + protected static final Font FONT_ARIAL_PLAIN_11 = new Font( + "Arial", Font.PLAIN, 11); + + public static final Font DEFAULT_MENU_FONT = FONT_ARIAL_PLAIN_11; + /** * map from labels to popup menus for the embedded menubar */ - protected Hashtable embeddedPopup; + protected Map embeddedPopup = new HashMap(); /** * the embedded menu is built on this and should be added to the frame at the @@ -94,77 +97,43 @@ public class EmbmenuFrame extends Frame implements MouseListener // DEBUG Hint: can test embedded menus by inserting true here. if (new jalview.util.Platform().isAMac()) { - // Build the embedded menu panel - embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, "Arial", Font.PLAIN, - 11, true); // try to pickup system font. + // Build the embedded menu panel, allowing override with system font + embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, true, false); setMenuBar(null); - // add the components to the TreePanel area. + // add the components to the Panel area. add(embeddedMenu, BorderLayout.NORTH); - tobeAdjusted.setSize(getSize().width, getSize().height - - embeddedMenu.HEIGHT); + tobeAdjusted.setSize(getSize().width, + getSize().height - embeddedMenu.getHeight()); return true; } return false; } /** - * move all menus on menuBar onto embeddedMenu. embeddedPopup is used to store - * the popups for each menu removed from the menuBar and added to the panel. - * NOTE: it is up to the caller to remove menuBar from the Frame if it is - * already attached. - * - * @param menuBar - * @param fn - * @param fstyle - * @param fsz - * @param overrideFonts - * true if we take the menuBar fonts in preference to the supplied - * defaults - * @return the embedded menu instance to be added to the frame. - */ - protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn, - int fstyle, int fsz, boolean overrideFonts) - { - return makeEmbeddedPopupMenu(menuBar, fn, fstyle, fsz, overrideFonts, - false); - } - - /** * Create or add elements to the embedded menu from menuBar. This removes all * menu from menuBar and it is up to the caller to remove the now useless * menuBar from the Frame if it is already attached. * * @param menuBar - * @param fn - * @param fstyle - * @param fsz * @param overrideFonts * @param append * true means existing menu will be emptied before adding new * elements * @return */ - protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn, - int fstyle, int fsz, boolean overrideFonts, boolean append) + protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, + boolean overrideFonts, boolean append) { if (!append) { - if (embeddedPopup != null) - { - embeddedPopup.clear(); // TODO: check if j1.1 - } + embeddedPopup.clear(); // TODO: check if j1.1 if (embeddedMenu != null) { embeddedMenu.removeAll(); } } - if (embeddedPopup == null) - { - embeddedPopup = new Hashtable(); - } - - embeddedMenu = makeEmbeddedPopupMenu(menuBar, fn, fstyle, fsz, - overrideFonts, embeddedPopup, new Panel(), this); + embeddedMenu = makeEmbeddedPopupMenu(menuBar, DEFAULT_MENU_FONT, + overrideFonts, new Panel(), this); return embeddedMenu; } @@ -177,12 +146,8 @@ public class EmbmenuFrame extends Frame implements MouseListener * * @param menuBar * must be non-null - * @param fn - * @param fstyle - * @param fsz + * @param font * @param overrideFonts - * @param embeddedPopup - * must be non-null * @param embeddedMenu * if null, a new panel will be created and returned * @param clickHandler @@ -190,27 +155,23 @@ public class EmbmenuFrame extends Frame implements MouseListener * embeddedPopup and embeddedMenu * @return the panel instance for convenience. */ - protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn, - int fstyle, int fsz, boolean overrideFonts, - Hashtable embeddedPopup, Panel embeddedMenu, + protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, Font font, + boolean overrideFonts, + Panel embeddedMenu, MouseListener clickHandler) { - if (embeddedPopup == null) - { - throw new Error(MessageManager.getString("error.implementation_error_embeddedpopup_not_null")); - } if (overrideFonts) { Font mbf = menuBar.getFont(); if (mbf != null) { - fn = mbf.getName(); - fstyle = mbf.getStyle(); - fsz = mbf.getSize(); + font = mbf; } } if (embeddedMenu == null) + { embeddedMenu = new Panel(); + } FlowLayout flowLayout1 = new FlowLayout(); embeddedMenu.setBackground(Color.lightGray); embeddedMenu.setLayout(flowLayout1); @@ -219,7 +180,7 @@ public class EmbmenuFrame extends Frame implements MouseListener { Menu mi = menuBar.getMenu(mbi); Label elab = new Label(mi.getLabel()); - elab.setFont(new java.awt.Font(fn, fstyle, fsz)); + elab.setFont(font); // add the menu entries PopupMenu popup = new PopupMenu(); int m, mSize = mi.getItemCount(); @@ -260,7 +221,7 @@ public class EmbmenuFrame extends Frame implements MouseListener */ PopupMenu getPopupMenu(Label source) { - return (PopupMenu) embeddedPopup.get(source); + return embeddedPopup.get(source); } public void mouseClicked(MouseEvent evt) @@ -287,10 +248,8 @@ public class EmbmenuFrame extends Frame implements MouseListener { if (embeddedPopup != null) { - Enumeration e = embeddedPopup.keys(); - while (e.hasMoreElements()) + for (Label lb : embeddedPopup.keySet()) { - Label lb = (Label) e.nextElement(); lb.removeMouseListener(this); } embeddedPopup.clear(); diff --git a/src/jalview/appletgui/FontChooser.java b/src/jalview/appletgui/FontChooser.java index 6bc67b5..b422cac 100644 --- a/src/jalview/appletgui/FontChooser.java +++ b/src/jalview/appletgui/FontChooser.java @@ -20,10 +20,24 @@ */ package jalview.appletgui; +import jalview.api.ViewStyleI; import jalview.util.MessageManager; -import java.awt.*; -import java.awt.event.*; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Choice; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; public class FontChooser extends Panel implements ActionListener, ItemListener @@ -34,6 +48,8 @@ public class FontChooser extends Panel implements ActionListener, Font oldFont; + int oldCharWidth = 0; + boolean init = true; Frame frame; @@ -65,6 +81,7 @@ public class FontChooser extends Panel implements ActionListener, this.ap = ap; oldFont = ap.av.getFont(); + oldCharWidth = ap.av.getViewStyle().getCharWidth(); init(); } @@ -144,6 +161,12 @@ public class FontChooser extends Panel implements ActionListener, if (ap != null) { ap.av.setFont(oldFont); + ViewStyleI style = ap.av.getViewStyle(); + if (style.getCharWidth() != oldCharWidth) + { + style.setCharWidth(oldCharWidth); + ap.av.setViewStyle(style); + } ap.paintAlignment(true); } else if (tp != null) diff --git a/src/jalview/appletgui/IdCanvas.java b/src/jalview/appletgui/IdCanvas.java index 0ac4e55..9e7373c 100755 --- a/src/jalview/appletgui/IdCanvas.java +++ b/src/jalview/appletgui/IdCanvas.java @@ -20,10 +20,14 @@ */ package jalview.appletgui; -import java.awt.*; -import java.util.List; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Panel; +import java.util.List; public class IdCanvas extends Panel { @@ -84,7 +88,7 @@ public class IdCanvas extends Panel ((i - starty) * charHeight) + ypos + charHeight - (charHeight / 5)); - if (av.hasHiddenRows() && av.showHiddenMarkers) + if (av.hasHiddenRows() && av.getShowHiddenMarkers()) { drawMarker(i, starty, ypos); } @@ -99,8 +103,8 @@ public class IdCanvas extends Panel return; } - gg.copyArea(0, 0, getSize().width, imgHeight, 0, -vertical - * av.charHeight); + gg.copyArea(0, 0, getSize().width, imgHeight, 0, + -vertical * av.getCharHeight()); int ss = av.startSeq, es = av.endSeq, transY = 0; if (vertical > 0) // scroll down @@ -112,7 +116,7 @@ public class IdCanvas extends Panel } else { - transY = imgHeight - vertical * av.charHeight; + transY = imgHeight - vertical * av.getCharHeight(); } } else if (vertical < 0) @@ -153,7 +157,7 @@ public class IdCanvas extends Panel } imgHeight = getSize().height; - imgHeight -= imgHeight % av.charHeight; + imgHeight -= imgHeight % av.getCharHeight(); if (imgHeight < 1) { @@ -178,10 +182,17 @@ public class IdCanvas extends Panel g.drawImage(image, 0, 0, this); } + /** + * local copy of av.getCharHeight set at top of drawIds + */ + private int avcharHeight; void drawIds(int starty, int endy) { + // hardwired italic IDs in applet currently Font italic = new Font(av.getFont().getName(), Font.ITALIC, av .getFont().getSize()); + // temp variable for speed + avcharHeight = av.getCharHeight(); gg.setFont(italic); @@ -201,20 +212,19 @@ public class IdCanvas extends Panel int annotationHeight = 0; AnnotationLabels labels = null; - if (av.showAnnotation) + if (av.isShowAnnotation()) { AnnotationPanel ap = new AnnotationPanel(av); annotationHeight = ap.adjustPanelHeight(); labels = new AnnotationLabels(av); } - - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = avcharHeight; + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += avcharHeight; } - int cHeight = alheight * av.charHeight + hgap + annotationHeight; + int cHeight = alheight * avcharHeight + hgap + annotationHeight; int rowSize = av.getEndRes() - av.getStartRes(); @@ -236,9 +246,9 @@ public class IdCanvas extends Panel if (labels != null) { - gg.translate(0, ypos + (alheight * av.charHeight)); + gg.translate(0, ypos + (alheight * avcharHeight)); labels.drawComponent(gg, getSize().width); - gg.translate(0, -ypos - (alheight * av.charHeight)); + gg.translate(0, -ypos - (alheight * avcharHeight)); } } @@ -284,15 +294,15 @@ public class IdCanvas extends Panel gg.setColor(currentColor); // TODO: isrep could be used to highlight the representative in a // different way - gg.fillRect(0, (i - starty) * av.charHeight, getSize().width, - av.charHeight); + gg.fillRect(0, (i - starty) * avcharHeight, getSize().width, + avcharHeight); gg.setColor(currentTextColor); gg.drawString(seq.getDisplayId(av.getShowJVSuffix()), 0, - (((i - starty) * av.charHeight) + av.charHeight) - - (av.charHeight / 5)); + (((i - starty) * avcharHeight) + avcharHeight) + - (avcharHeight / 5)); - if (av.hasHiddenRows() && av.showHiddenMarkers) + if (av.hasHiddenRows() && av.getShowHiddenMarkers()) { drawMarker(i, starty, 0); } @@ -343,20 +353,20 @@ public class IdCanvas extends Panel if (below) { gg.fillPolygon(new int[] - { getSize().width - av.charHeight, getSize().width - av.charHeight, + { getSize().width - avcharHeight, getSize().width - avcharHeight, getSize().width }, new int[] - { (i - starty) * av.charHeight + yoffset, - (i - starty) * av.charHeight + yoffset + av.charHeight / 4, - (i - starty) * av.charHeight + yoffset }, 3); + { (i - starty) * avcharHeight + yoffset, + (i - starty) * avcharHeight + yoffset + avcharHeight / 4, + (i - starty) * avcharHeight + yoffset }, 3); } if (above) { gg.fillPolygon(new int[] - { getSize().width - av.charHeight, getSize().width - av.charHeight, + { getSize().width - avcharHeight, getSize().width - avcharHeight, getSize().width }, new int[] - { (i - starty + 1) * av.charHeight + yoffset, - (i - starty + 1) * av.charHeight + yoffset - av.charHeight / 4, - (i - starty + 1) * av.charHeight + yoffset }, 3); + { (i - starty + 1) * avcharHeight + yoffset, + (i - starty + 1) * avcharHeight + yoffset - avcharHeight / 4, + (i - starty + 1) * avcharHeight + yoffset }, 3); } } diff --git a/src/jalview/appletgui/IdPanel.java b/src/jalview/appletgui/IdPanel.java index 7981634..958f49a 100755 --- a/src/jalview/appletgui/IdPanel.java +++ b/src/jalview/appletgui/IdPanel.java @@ -20,14 +20,21 @@ */ package jalview.appletgui; -import java.awt.*; -import java.awt.event.*; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.util.UrlLink; + +import java.awt.BorderLayout; +import java.awt.Panel; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; import java.util.List; import java.util.Vector; -import jalview.datamodel.*; -import jalview.util.UrlLink; - public class IdPanel extends Panel implements MouseListener, MouseMotionListener { @@ -303,7 +310,7 @@ public class IdPanel extends Panel implements MouseListener, int y = e.getY(); if (av.getWrapAlignment()) { - y -= 2 * av.charHeight; + y -= 2 * av.getCharHeight(); } int seq = alignPanel.seqPanel.findSeq(e); diff --git a/src/jalview/appletgui/RedundancyPanel.java b/src/jalview/appletgui/RedundancyPanel.java index 8e364f0..a81ffd4 100644 --- a/src/jalview/appletgui/RedundancyPanel.java +++ b/src/jalview/appletgui/RedundancyPanel.java @@ -233,9 +233,9 @@ public class RedundancyPanel extends SliderPanel implements Runnable, CommandI command = (CommandI) historyList.pop(); command.undoCommand(null); - if (ap.av.historyList.contains(command)) + if (ap.av.getHistoryList().contains(command)) { - ap.av.historyList.removeElement(command); + ap.av.getHistoryList().remove(command); ap.alignFrame.updateEditMenuBar(); ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences()); } diff --git a/src/jalview/appletgui/ScalePanel.java b/src/jalview/appletgui/ScalePanel.java index 2b6f37a..b5241a6 100755 --- a/src/jalview/appletgui/ScalePanel.java +++ b/src/jalview/appletgui/ScalePanel.java @@ -362,7 +362,6 @@ public class ScalePanel extends Panel implements MouseMotionListener, int height) { gg.setFont(av.getFont()); - // Fill in the background gg.setColor(Color.white); gg.fillRect(0, 0, width, height); @@ -371,7 +370,7 @@ public class ScalePanel extends Panel implements MouseMotionListener, // Fill the selected columns ColumnSelection cs = av.getColumnSelection(); gg.setColor(new Color(220, 0, 0)); - + int avcharWidth = av.getCharWidth(), avcharHeight = av.getCharHeight(); for (int i = 0; i < cs.size(); i++) { int sel = cs.columnAt(i); @@ -382,7 +381,7 @@ public class ScalePanel extends Panel implements MouseMotionListener, if ((sel >= startx) && (sel <= endx)) { - gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth, + gg.fillRect((sel - startx) * avcharWidth, 0, avcharWidth, getSize().height); } } @@ -393,7 +392,7 @@ public class ScalePanel extends Panel implements MouseMotionListener, int scalestartx = (startx / 10) * 10; FontMetrics fm = gg.getFontMetrics(av.getFont()); - int y = av.charHeight - fm.getDescent(); + int y = avcharHeight - fm.getDescent(); if ((scalestartx % 10) == 0) { @@ -409,25 +408,26 @@ public class ScalePanel extends Panel implements MouseMotionListener, { string = String.valueOf(av.getColumnSelection() .adjustForHiddenColumns(i)); - if ((i - startx - 1) * av.charWidth > maxX) + if ((i - startx - 1) * avcharWidth > maxX) { - gg.drawString(string, (i - startx - 1) * av.charWidth, y); - maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string); + gg.drawString(string, (i - startx - 1) * avcharWidth, y); + maxX = (i - startx + 1) * avcharWidth + fm.stringWidth(string); } gg.drawLine( - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), +((i - startx - 1) * avcharWidth) + (avcharWidth / 2), y + 2, - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + ((i - startx - 1) * avcharWidth) + (avcharWidth / 2), y + (fm.getDescent() * 2)); } else { gg.drawLine( - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), +((i - startx - 1) * avcharWidth) + (avcharWidth / 2), y + fm.getDescent(), - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + ((i - startx - 1) * avcharWidth) + + (avcharWidth / 2), y + (fm.getDescent() * 2)); } } @@ -451,10 +451,10 @@ public class ScalePanel extends Panel implements MouseMotionListener, } gg.fillPolygon(new int[] - { res * av.charWidth - av.charHeight / 4, - res * av.charWidth + av.charHeight / 4, res * av.charWidth }, + { res * avcharWidth - avcharHeight / 4, + res * avcharWidth + avcharHeight / 4, res * avcharWidth }, new int[] - { y - av.charHeight / 2, y - av.charHeight / 2, y + 8 }, + { y - avcharHeight / 2, y - avcharHeight / 2, y + 8 }, 3); } @@ -463,7 +463,7 @@ public class ScalePanel extends Panel implements MouseMotionListener, if (reveal != null && reveal[0] > startx && reveal[0] < endx) { gg.drawString(MessageManager.getString("label.reveal_columns"), - reveal[0] * av.charWidth, 0); + reveal[0] * avcharWidth, 0); } } diff --git a/src/jalview/appletgui/SeqCanvas.java b/src/jalview/appletgui/SeqCanvas.java index 3d1f7e2..4cf1996 100755 --- a/src/jalview/appletgui/SeqCanvas.java +++ b/src/jalview/appletgui/SeqCanvas.java @@ -61,6 +61,15 @@ public class SeqCanvas extends Panel fr = new FeatureRenderer(av); sr = new SequenceRenderer(av); PaintRefresher.Register(this, av.getSequenceSetId()); + updateViewport(); + } + + int avcharHeight = 0, avcharWidth = 0; + + private void updateViewport() + { + avcharHeight = av.getCharHeight(); + avcharWidth = av.getCharWidth(); } public AlignViewport getViewport() @@ -78,7 +87,7 @@ public class SeqCanvas extends Panel return sr; } - void drawNorthScale(Graphics g, int startx, int endx, int ypos) + private void drawNorthScale(Graphics g, int startx, int endx, int ypos) { int scalestartx = startx - startx % 10 + 10; @@ -93,20 +102,20 @@ public class SeqCanvas extends Panel value = av.getColumnSelection().adjustForHiddenColumns(value); } - g.drawString(String.valueOf(value), (i - startx - 1) * av.charWidth, - ypos - (av.charHeight / 2)); + g.drawString(String.valueOf(value), (i - startx - 1) * avcharWidth, + ypos - (avcharHeight / 2)); - g.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - (ypos + 2) - (av.charHeight / 2), - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + g.drawLine(((i - startx - 1) * avcharWidth) + (avcharWidth / 2), + (ypos + 2) - (avcharHeight / 2), + ((i - startx - 1) * avcharWidth) + (avcharWidth / 2), ypos - 2); } } - void drawWestScale(Graphics g, int startx, int endx, int ypos) + private void drawWestScale(Graphics g, int startx, int endx, int ypos) { FontMetrics fm = getFontMetrics(av.getFont()); - ypos += av.charHeight; + ypos += avcharHeight; if (av.hasHiddenColumns()) { startx = av.getColumnSelection().adjustForHiddenColumns(startx); @@ -143,16 +152,16 @@ public class SeqCanvas extends Panel if (value != -1) { int x = LABEL_WEST - fm.stringWidth(String.valueOf(value)) - - av.charWidth / 2; - g.drawString(value + "", x, (ypos + (i * av.charHeight)) - - (av.charHeight / 5)); + - avcharWidth / 2; + g.drawString(value + "", x, (ypos + (i * avcharHeight)) + - (avcharHeight / 5)); } } } - void drawEastScale(Graphics g, int startx, int endx, int ypos) + private void drawEastScale(Graphics g, int startx, int endx, int ypos) { - ypos += av.charHeight; + ypos += avcharHeight; if (av.hasHiddenColumns()) { @@ -183,8 +192,8 @@ public class SeqCanvas extends Panel if (value != -1) { - g.drawString(String.valueOf(value), 0, (ypos + (i * av.charHeight)) - - (av.charHeight / 5)); + g.drawString(String.valueOf(value), 0, (ypos + (i * avcharHeight)) + - (avcharHeight / 5)); } } } @@ -198,6 +207,8 @@ public class SeqCanvas extends Panel return; } + updateViewport(); + // Its possible on certain browsers that the call to fastpaint // is faster than it can paint, so this check here catches // this possibility @@ -209,16 +220,16 @@ public class SeqCanvas extends Panel lastsr = av.startRes; fastPaint = true; - gg.copyArea(horizontal * av.charWidth, vertical * av.charHeight, - imgWidth - horizontal * av.charWidth, imgHeight - vertical - * av.charHeight, -horizontal * av.charWidth, -vertical - * av.charHeight); + gg.copyArea(horizontal * avcharWidth, vertical * avcharHeight, imgWidth + - horizontal * avcharWidth, + imgHeight - vertical * avcharHeight, -horizontal * avcharWidth, + -vertical * avcharHeight); int sr = av.startRes, er = av.endRes, ss = av.startSeq, es = av.endSeq, transX = 0, transY = 0; if (horizontal > 0) // scrollbar pulled right, image to the left { - transX = (er - sr - horizontal) * av.charWidth; + transX = (er - sr - horizontal) * avcharWidth; sr = er - horizontal; } else if (horizontal < 0) @@ -235,7 +246,7 @@ public class SeqCanvas extends Panel } else { - transY = imgHeight - vertical * av.charHeight; + transY = imgHeight - vertical * avcharHeight; } } else if (vertical < 0) @@ -269,6 +280,7 @@ public class SeqCanvas extends Panel paint(g); } + @Override public void paint(Graphics g) { @@ -288,12 +300,13 @@ public class SeqCanvas extends Panel return; } + updateViewport(); // this draws the whole of the alignment imgWidth = this.getSize().width; imgHeight = this.getSize().height; - imgWidth -= imgWidth % av.charWidth; - imgHeight -= imgHeight % av.charHeight; + imgWidth -= imgWidth % avcharWidth; + imgHeight -= imgHeight % avcharHeight; if (imgWidth < 1 || imgHeight < 1) { @@ -328,24 +341,24 @@ public class SeqCanvas extends Panel public int getWrappedCanvasWidth(int cwidth) { - cwidth -= cwidth % av.charWidth; + cwidth -= cwidth % av.getCharWidth(); FontMetrics fm = getFontMetrics(av.getFont()); LABEL_EAST = 0; LABEL_WEST = 0; - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { LABEL_EAST = fm.stringWidth(getMask()); } - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { LABEL_WEST = fm.stringWidth(getMask()); } - return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth; + return (cwidth - LABEL_EAST - LABEL_WEST) / av.getCharWidth(); } /** @@ -375,31 +388,31 @@ public class SeqCanvas extends Panel return mask; } - public void drawWrappedPanel(Graphics g, int canvasWidth, + private void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight, int startRes) { AlignmentI al = av.getAlignment(); FontMetrics fm = getFontMetrics(av.getFont()); - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { LABEL_EAST = fm.stringWidth(getMask()); } - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { LABEL_WEST = fm.stringWidth(getMask()); } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = avcharHeight; + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += avcharHeight; } - int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth; - int cHeight = av.getAlignment().getHeight() * av.charHeight; + int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / avcharWidth; + int cHeight = av.getAlignment().getHeight() * avcharHeight; av.setWrappedWidth(cWidth); @@ -426,12 +439,12 @@ public class SeqCanvas extends Panel g.setColor(Color.black); - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { drawWestScale(g, startRes, endx, ypos); } - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { g.translate(canvasWidth - LABEL_EAST, 0); drawEastScale(g, startRes, endx, ypos); @@ -440,11 +453,11 @@ public class SeqCanvas extends Panel g.translate(LABEL_WEST, 0); - if (av.scaleAboveWrapped) + if (av.getScaleAboveWrapped()) { drawNorthScale(g, startRes, endx, ypos); } - if (av.hasHiddenColumns() && av.showHiddenMarkers) + if (av.hasHiddenColumns() && av.getShowHiddenMarkers()) { g.setColor(Color.blue); int res; @@ -460,24 +473,24 @@ public class SeqCanvas extends Panel } gg.fillPolygon(new int[] - { res * av.charWidth - av.charHeight / 4, - res * av.charWidth + av.charHeight / 4, res * av.charWidth }, + { res * avcharWidth - avcharHeight / 4, + res * avcharWidth + avcharHeight / 4, res * avcharWidth }, new int[] - { ypos - (av.charHeight / 2), ypos - (av.charHeight / 2), - ypos - (av.charHeight / 2) + 8 }, 3); + { ypos - (avcharHeight / 2), ypos - (avcharHeight / 2), + ypos - (avcharHeight / 2) + 8 }, 3); } } if (g.getClip() == null) { - g.setClip(0, 0, cWidth * av.charWidth, canvasHeight); + g.setClip(0, 0, cWidth * avcharWidth, canvasHeight); } drawPanel(g, startRes, endx, 0, al.getHeight(), ypos); g.setClip(null); - if (av.showAnnotation) + if (av.isShowAnnotation()) { g.translate(0, cHeight + ypos + 4); if (annotations == null) @@ -501,7 +514,7 @@ public class SeqCanvas extends Panel int getAnnotationHeight() { - if (!av.showAnnotation) + if (!av.isShowAnnotation()) { return 0; } @@ -514,7 +527,8 @@ public class SeqCanvas extends Panel return annotations.adjustPanelHeight(); } - void drawPanel(Graphics g1, int startRes, int endRes, int startSeq, + private void drawPanel(Graphics g1, int startRes, int endRes, + int startSeq, int endSeq, int offset) { @@ -545,20 +559,20 @@ public class SeqCanvas extends Panel blockEnd = hideStart - 1; - g1.translate(screenY * av.charWidth, 0); + g1.translate(screenY * avcharWidth, 0); draw(g1, blockStart, blockEnd, startSeq, endSeq, offset); if (av.getShowHiddenMarkers()) { g1.setColor(Color.blue); - g1.drawLine((blockEnd - blockStart + 1) * av.charWidth - 1, - 0 + offset, (blockEnd - blockStart + 1) * av.charWidth - - 1, (endSeq - startSeq) * av.charHeight + g1.drawLine((blockEnd - blockStart + 1) * avcharWidth - 1, + 0 + offset, (blockEnd - blockStart + 1) * avcharWidth + - 1, (endSeq - startSeq) * avcharHeight + offset); } - g1.translate(-screenY * av.charWidth, 0); + g1.translate(-screenY * avcharWidth, 0); screenY += blockEnd - blockStart + 1; blockStart = hideEnd + 1; } @@ -566,10 +580,10 @@ public class SeqCanvas extends Panel if (screenY <= (endRes - startRes)) { blockEnd = blockStart + (endRes - startRes) - screenY; - g1.translate(screenY * av.charWidth, 0); + g1.translate(screenY * avcharWidth, 0); draw(g1, blockStart, blockEnd, startSeq, endSeq, offset); - g1.translate(-screenY * av.charWidth, 0); + g1.translate(-screenY * avcharWidth, 0); } } @@ -581,8 +595,8 @@ public class SeqCanvas extends Panel int offset) { g.setFont(av.getFont()); - sr.prepare(g, av.renderGaps); - + sr.prepare(g, av.isRenderGaps()); + updateViewport(); SequenceI nextSeq; // / First draw the sequences @@ -597,12 +611,12 @@ public class SeqCanvas extends Panel } sr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq), - startRes, endRes, offset + ((i - startSeq) * av.charHeight)); + startRes, endRes, offset + ((i - startSeq) * avcharHeight)); if (av.isShowSequenceFeatures()) { fr.drawSequence(g, nextSeq, startRes, endRes, offset - + ((i - startSeq) * av.charHeight)); + + ((i - startSeq) * avcharHeight)); } // / Highlight search Results once all sequences have been drawn @@ -617,8 +631,8 @@ public class SeqCanvas extends Panel { sr.drawHighlightedText(nextSeq, visibleResults[r], visibleResults[r + 1], (visibleResults[r] - startRes) - * av.charWidth, offset - + ((i - startSeq) * av.charHeight)); + * avcharWidth, offset + + ((i - startSeq) * avcharHeight)); } } } @@ -626,9 +640,8 @@ public class SeqCanvas extends Panel if (av.cursorMode && cursorY == i && cursorX >= startRes && cursorX <= endRes) { - sr.drawCursor(nextSeq, cursorX, - (cursorX - startRes) * av.charWidth, offset - + ((i - startSeq) * av.charHeight)); + sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * avcharWidth, + offset + ((i - startSeq) * avcharHeight)); } } @@ -640,7 +653,7 @@ public class SeqCanvas extends Panel } - void drawGroupsBoundaries(Graphics g, int startRes, int endRes, + private void drawGroupsBoundaries(Graphics g, int startRes, int endRes, int startSeq, int endSeq, int offset) { // @@ -673,16 +686,16 @@ public class SeqCanvas extends Panel for (i = startSeq; i < endSeq; i++) { - sx = (group.getStartRes() - startRes) * av.charWidth; - sy = offset + ((i - startSeq) * av.charHeight); - ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) - 1; + sx = (group.getStartRes() - startRes) * avcharWidth; + sy = offset + ((i - startSeq) * avcharHeight); + ex = (((group.getEndRes() + 1) - group.getStartRes()) * avcharWidth) - 1; if (sx + ex < 0 || sx > imgWidth) { continue; } - if ((sx <= (endRes - startRes) * av.charWidth) + if ((sx <= (endRes - startRes) * avcharWidth) && group.getSequences(null).contains( av.getAlignment().getSequenceAt(i))) { @@ -691,7 +704,7 @@ public class SeqCanvas extends Panel .contains( av.getAlignment().getSequenceAt(i + 1)))) { - bottom = sy + av.charHeight; + bottom = sy + avcharHeight; } if (!inGroup) @@ -741,9 +754,9 @@ public class SeqCanvas extends Panel ex = imgWidth; } - else if (sx + ex >= (endRes - startRes + 1) * av.charWidth) + else if (sx + ex >= (endRes - startRes + 1) * avcharWidth) { - ex = (endRes - startRes + 1) * av.charWidth; + ex = (endRes - startRes + 1) * avcharWidth; } if (top != -1) @@ -765,7 +778,7 @@ public class SeqCanvas extends Panel if (inGroup) { - sy = offset + ((i - startSeq) * av.charHeight); + sy = offset + ((i - startSeq) * avcharHeight); if (sx >= 0 && sx < imgWidth) { g.drawLine(sx, oldY, sx, sy); @@ -786,9 +799,9 @@ public class SeqCanvas extends Panel { ex = imgWidth; } - else if (sx + ex >= (endRes - startRes + 1) * av.charWidth) + else if (sx + ex >= (endRes - startRes + 1) * avcharWidth) { - ex = (endRes - startRes + 1) * av.charWidth; + ex = (endRes - startRes + 1) * avcharWidth; } if (top != -1) diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java index a95dd27..090779e 100644 --- a/src/jalview/appletgui/SeqPanel.java +++ b/src/jalview/appletgui/SeqPanel.java @@ -20,18 +20,23 @@ */ package jalview.appletgui; +import jalview.api.AlignViewportI; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ResidueProperties; +import jalview.structure.SelectionListener; import jalview.structure.SelectionSource; import jalview.structure.SequenceListener; import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; +import jalview.util.MappingUtils; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -43,10 +48,11 @@ import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; +import java.util.List; import java.util.Vector; public class SeqPanel extends Panel implements MouseMotionListener, - MouseListener, SequenceListener + MouseListener, SequenceListener, SelectionListener { public SeqCanvas seqCanvas; @@ -109,6 +115,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, seqCanvas.addMouseListener(this); ssm = StructureSelectionManager.getStructureSelectionManager(av.applet); ssm.addStructureViewerListener(this); + ssm.addSelectionListener(this); seqCanvas.repaint(); } @@ -159,8 +166,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, void setCursorPosition() { - SequenceI sequence = av.getAlignment().getSequenceAt( - seqCanvas.cursorY); + SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY); seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1()) - 1; scrollToVisible(); @@ -212,7 +218,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, } endEditing(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { ap.scrollToWrappedVisible(seqCanvas.cursorX); } @@ -252,8 +258,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, void setSelectionAreaAtCursor(boolean topLeft) { - SequenceI sequence = av.getAlignment().getSequenceAt( - seqCanvas.cursorY); + SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY); if (av.getSelectionGroup() != null) { @@ -393,41 +398,107 @@ public class SeqPanel extends Panel implements MouseMotionListener, return 1; } + /** + * Set status message in alignment panel + * + * @param sequence + * aligned sequence object + * @param res + * alignment column + * @param seq + * index of sequence in alignment + * @return position of res in sequence + */ void setStatusMessage(SequenceI sequence, int res, int seq) { - StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " - + sequence.getName()); - - Object obj = null; + // TODO remove duplication of identical gui method + StringBuilder text = new StringBuilder(32); + String seqno = seq == -1 ? "" : " " + (seq + 1); + text.append("Sequence" + seqno + " ID: " + sequence.getName()); + + String residue = null; + /* + * Try to translate the display character to residue name (null for gap). + */ + final String displayChar = String.valueOf(sequence.getCharAt(res)); if (av.getAlignment().isNucleotide()) { - obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) - + ""); - if (obj != null) + residue = ResidueProperties.nucleotideName.get(displayChar); + if (residue != null) { - text.append(" Nucleotide: "); + text.append(" Nucleotide: ").append(residue); } } else { - obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + ""); - if (obj != null) - { - text.append(" Residue: "); - } - } + residue = "X".equalsIgnoreCase(displayChar) ? "X" + : ResidueProperties.aa2Triplet.get(displayChar); + if (residue != null) + { + text.append(" Residue: ").append(residue); + } + } + + int pos = -1; + if (residue != null) + { + pos = sequence.findPosition(res); + text.append(" (").append(Integer.toString(pos)).append(")"); + } + // Object obj = null; + // if (av.getAlignment().isNucleotide()) + // { + // obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) + // + ""); + // if (obj != null) + // { + // text.append(" Nucleotide: "); + // } + // } + // else + // { + // obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + ""); + // if (obj != null) + // { + // text.append(" Residue: "); + // } + // } + // + // if (obj != null) + // { + // + // if (obj != "") + // { + // text.append(obj + " (" + sequence.findPosition(res) + ")"); + // } + // } - if (obj != null) - { + ap.alignFrame.statusBar.setText(text.toString()); - if (obj != "") - { - text.append(obj + " (" + sequence.findPosition(res) + ")"); - } - } + } - ap.alignFrame.statusBar.setText(text.toString()); + /** + * Set the status bar message to highlight the first matched position in + * search results. + * + * @param results + */ + private void setStatusMessage(SearchResults results) + { + List matches = results.getResults(); + if (!matches.isEmpty()) + { + Match m = matches.get(0); + SequenceI seq = m.getSequence(); + int sequenceIndex = this.av.getAlignment().findIndex(seq); + /* + * Convert position in sequence (base 1) to sequence character array index + * (base 0) + */ + int start = m.getStart() - 1; + setStatusMessage(seq, start, sequenceIndex); + } } public void mousePressed(MouseEvent evt) @@ -538,16 +609,17 @@ public class SeqPanel extends Panel implements MouseMotionListener, int res = 0; int x = evt.getX(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); int y = evt.getY(); @@ -596,15 +668,16 @@ public class SeqPanel extends Panel implements MouseMotionListener, int seq = 0; int y = evt.getY(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); y -= hgap; @@ -676,10 +749,17 @@ public class SeqPanel extends Panel implements MouseMotionListener, ap.alignFrame.repaint(); } } + setStatusMessage(results); seqCanvas.highlightSearchResults(results); } + @Override + public VamsasSource getVamsasSource() + { + return this.ap == null ? null : this.ap.av; + } + public void updateColours(SequenceI seq, int index) { System.out.println("update the seqPanel colours"); @@ -716,39 +796,38 @@ public class SeqPanel extends Panel implements MouseMotionListener, mouseOverSequence(sequence, res, respos); } - StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " - + sequence.getName()); + StringBuilder text = new StringBuilder(); + text.append("Sequence ").append(Integer.toString(seq + 1)) + .append(" ID: ").append(sequence.getName()); - Object obj = null; + String obj = null; + final String ch = String.valueOf(sequence.getCharAt(res)); if (av.getAlignment().isNucleotide()) { - obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) - + ""); + obj = ResidueProperties.nucleotideName.get(ch); if (obj != null) { - text.append(" Nucleotide: "); + text.append(" Nucleotide: ").append(obj); } } else { - obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + ""); + obj = "X".equalsIgnoreCase(ch) ? "X" + : ResidueProperties.aa2Triplet.get(ch); if (obj != null) { - text.append(" Residue: "); + text.append(" Residue: ").append(obj); } } if (obj != null) { - if (obj != "") - { - text.append(obj + " (" + respos + ")"); - } + text.append(" (").append(Integer.toString(respos)).append(")"); } ap.alignFrame.statusBar.setText(text.toString()); - StringBuffer tooltipText = new StringBuffer(); + StringBuilder tooltipText = new StringBuilder(); SequenceGroup[] groups = av.getAlignment().findAllGroups(sequence); if (groups != null) { @@ -759,7 +838,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, if (!groups[g].getName().startsWith("JTreeGroup") && !groups[g].getName().startsWith("JGroup")) { - tooltipText.append(groups[g].getName() + " "); + tooltipText.append(groups[g].getName()).append(" "); } if (groups[g].getDescription() != null) { @@ -849,7 +928,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, { if (mouseWheelPressed) { - int oldWidth = av.charWidth; + int oldWidth = av.getCharWidth(); // Which is bigger, left-right or up-down? if (Math.abs(evt.getY() - lastMousePress.y) > Math.abs(evt.getX() @@ -857,7 +936,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, { int fontSize = av.font.getSize(); - if (evt.getY() < lastMousePress.y && av.charHeight > 1) + if (evt.getY() < lastMousePress.y && av.getCharHeight() > 1) { fontSize--; } @@ -872,29 +951,29 @@ public class SeqPanel extends Panel implements MouseMotionListener, } av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize)); - av.charWidth = oldWidth; + av.setCharWidth(oldWidth); } else { - if (evt.getX() < lastMousePress.x && av.charWidth > 1) + if (evt.getX() < lastMousePress.x && av.getCharWidth() > 1) { - av.charWidth--; + av.setCharWidth(av.getCharWidth() - 1); } else if (evt.getX() > lastMousePress.x) { - av.charWidth++; + av.setCharWidth(av.getCharWidth() + 1); } - if (av.charWidth < 1) + if (av.getCharWidth() < 1) { - av.charWidth = 1; + av.setCharWidth(1); } } ap.fontChanged(); FontMetrics fm = getFontMetrics(av.getFont()); - av.validCharWidth = fm.charWidth('M') <= av.charWidth; + av.validCharWidth = fm.charWidth('M') <= av.getCharWidth(); lastMousePress = evt.getPoint(); @@ -960,15 +1039,18 @@ public class SeqPanel extends Panel implements MouseMotionListener, StringBuffer message = new StringBuffer(); if (groupEditing) { - message.append(MessageManager.getString("action.edit_group")).append(":"); + message.append(MessageManager.getString("action.edit_group")).append( + ":"); if (editCommand == null) { - editCommand = new EditCommand(MessageManager.getString("action.edit_group")); + editCommand = new EditCommand( + MessageManager.getString("action.edit_group")); } } else { - message.append(MessageManager.getString("label.edit_sequence")).append(" " + seq.getName()); + message.append(MessageManager.getString("label.edit_sequence")) + .append(" " + seq.getName()); String label = seq.getName(); if (label.length() > 10) { @@ -976,7 +1058,9 @@ public class SeqPanel extends Panel implements MouseMotionListener, } if (editCommand == null) { - editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label})); + editCommand = new EditCommand(MessageManager.formatMessage( + "label.edit_params", new String[] + { label })); } } @@ -1178,8 +1262,8 @@ public class SeqPanel extends Panel implements MouseMotionListener, } else { - editCommand.appendEdit(Action.INSERT_GAP, groupSeqs, - startres, startres - lastres, av.getAlignment(), true); + editCommand.appendEdit(Action.INSERT_GAP, groupSeqs, startres, + startres - lastres, av.getAlignment(), true); } } else @@ -1194,8 +1278,8 @@ public class SeqPanel extends Panel implements MouseMotionListener, } else { - editCommand.appendEdit(Action.DELETE_GAP, groupSeqs, - startres, lastres - startres, av.getAlignment(), true); + editCommand.appendEdit(Action.DELETE_GAP, groupSeqs, startres, + lastres - startres, av.getAlignment(), true); } } @@ -1290,16 +1374,16 @@ public class SeqPanel extends Panel implements MouseMotionListener, editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1, av.getAlignment(), true); - editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1, - av.getAlignment(), true); + editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1, av.getAlignment(), + true); } void deleteChar(int j, SequenceI[] seq, int fixedColumn) { - editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1, - av.getAlignment(), true); + editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1, av.getAlignment(), + true); editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1, av.getAlignment(), true); @@ -1718,6 +1802,16 @@ public class SeqPanel extends Panel implements MouseMotionListener, { return; } + + /* + * Check for selection in a view of which this one is a dna/protein + * complement. + */ + if (selectionFromTranslation(seqsel, colsel, source)) + { + return; + } + // do we want to thread this ? (contention with seqsel and colsel locks, I // suspect) // rules are: colsel is copied if there is a real intersection between @@ -1835,4 +1929,46 @@ public class SeqPanel extends Panel implements MouseMotionListener, ap.scrollTo(column, column, ap.av.startSeq, true, true); } + /** + * If this panel is a cdna/protein translation view of the selection source, + * tries to map the source selection to a local one, and returns true. Else + * returns false. + * + * @param seqsel + * @param colsel + * @param source + */ + protected boolean selectionFromTranslation(SequenceGroup seqsel, + ColumnSelection colsel, SelectionSource source) + { + if (!(source instanceof AlignViewportI)) { + return false; + } + final AlignViewportI sourceAv = (AlignViewportI) source; + if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv) + { + return false; + } + + /* + * Map sequence selection + */ + SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av); + av.setSelectionGroup(sg); + av.isSelectionGroupChanged(true); + + /* + * Map column selection + */ + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv, + av); + av.setColumnSelection(cs); + av.isColSelChanged(true); + + ap.scalePanelHolder.repaint(); + ap.repaint(); + + return true; + } + } diff --git a/src/jalview/appletgui/SequenceRenderer.java b/src/jalview/appletgui/SequenceRenderer.java index 9badf43..19b038a 100755 --- a/src/jalview/appletgui/SequenceRenderer.java +++ b/src/jalview/appletgui/SequenceRenderer.java @@ -21,7 +21,6 @@ package jalview.appletgui; import jalview.api.FeatureRenderer; -import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeI; @@ -161,7 +160,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer int length = seq.getLength(); int curStart = -1; - int curWidth = av.charWidth; + int curWidth = av.getCharWidth(), avCharWidth = av.getCharWidth(), avCharHeight = av + .getCharHeight(); Color tempColour = null; while (i <= end) @@ -186,40 +186,41 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (tempColour != null) { - graphics.fillRect(av.charWidth * (curStart - start), y1, - curWidth, av.charHeight); + graphics.fillRect(avCharWidth * (curStart - start), y1, curWidth, + avCharHeight); } graphics.setColor(resBoxColour); curStart = i; - curWidth = av.charWidth; + curWidth = avCharWidth; tempColour = resBoxColour; } else { - curWidth += av.charWidth; + curWidth += avCharWidth; } i++; } - graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, - av.charHeight); + graphics.fillRect(avCharWidth * (curStart - start), y1, curWidth, + avCharHeight); } public void drawText(SequenceI seq, int start, int end, int y1) { + int avCharWidth = av.getCharWidth(), avCharHeight = av.getCharHeight(); Font boldFont = null; boolean bold = false; - if (av.upperCasebold) + if (av.isUpperCasebold()) { - boldFont = new Font(av.getFont().getName(), Font.BOLD, av.charHeight); + boldFont = new Font(av.getFont().getName(), Font.BOLD, avCharHeight); graphics.setFont(av.getFont()); } - y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady + y1 += avCharHeight - avCharHeight / 5; // height/5 replaces pady int charOffset = 0; @@ -286,7 +287,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } } - if (av.upperCasebold) + if (av.isUpperCasebold()) { fm = graphics.getFontMetrics(); if ('A' <= s && s <= 'Z') @@ -306,8 +307,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } - charOffset = (av.charWidth - fm.charWidth(s)) / 2; - graphics.drawString(String.valueOf(s), charOffset + av.charWidth + charOffset = (avCharWidth - fm.charWidth(s)) / 2; + graphics.drawString(String.valueOf(s), charOffset + avCharWidth * (i - start), y1); } @@ -350,11 +351,11 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1) { - int pady = av.charHeight / 5; + int avCharWidth = av.getCharWidth(), avCharHeight = av.getCharHeight(); + int pady = avCharHeight / 5; int charOffset = 0; graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), - av.charHeight); + graphics.fillRect(x1, y1, avCharWidth * (end - start + 1), avCharHeight); graphics.setColor(Color.white); char s = '~'; @@ -368,19 +369,19 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer s = seq.getCharAt(i); } - charOffset = (av.charWidth - fm.charWidth(s)) / 2; + charOffset = (avCharWidth - fm.charWidth(s)) / 2; graphics.drawString(String.valueOf(s), charOffset + x1 - + av.charWidth * (i - start), y1 + av.charHeight - pady); + + avCharWidth * (i - start), y1 + avCharHeight - pady); } } } public void drawCursor(SequenceI seq, int res, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.charWidth, av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); graphics.setColor(Color.white); graphics.setColor(Color.white); @@ -389,9 +390,9 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer if (av.validCharWidth) { - charOffset = (av.charWidth - fm.charWidth(s)) / 2; + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; graphics.drawString(String.valueOf(s), charOffset + x1, - (y1 + av.charHeight) - pady); + (y1 + av.getCharHeight()) - pady); } } diff --git a/src/jalview/appletgui/SliderPanel.java b/src/jalview/appletgui/SliderPanel.java index 220a7fb..3739b3c 100644 --- a/src/jalview/appletgui/SliderPanel.java +++ b/src/jalview/appletgui/SliderPanel.java @@ -20,15 +20,30 @@ */ package jalview.appletgui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; - -import jalview.datamodel.*; -import jalview.schemes.*; +import jalview.datamodel.SequenceGroup; +import jalview.schemes.ColourSchemeI; import jalview.util.MessageManager; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Scrollbar; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Iterator; + public class SliderPanel extends Panel implements ActionListener, AdjustmentListener, MouseListener { @@ -215,13 +230,15 @@ public class SliderPanel extends Panel implements ActionListener, } else { - toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus()); + toChange.setThreshold(i, ap.av.isIgnoreGapsConsensus()); } if (allGroups != null && allGroups.hasNext()) { while ((toChange = allGroups.next().cs) == null && allGroups.hasNext()) + { ; + } } else { diff --git a/src/jalview/appletgui/SplitFrame.java b/src/jalview/appletgui/SplitFrame.java new file mode 100644 index 0000000..fb11a5c --- /dev/null +++ b/src/jalview/appletgui/SplitFrame.java @@ -0,0 +1,166 @@ +package jalview.appletgui; + +import jalview.analysis.AlignmentUtils; +import jalview.analysis.AlignmentUtils.MappingResult; +import jalview.api.ViewStyleI; +import jalview.bin.JalviewLite; +import jalview.datamodel.AlignmentI; +import jalview.structure.StructureSelectionManager; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.GridLayout; +import java.awt.MouseInfo; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; + +public class SplitFrame extends EmbmenuFrame +{ + private static final long serialVersionUID = 1L; + + private AlignFrame topFrame; + + private AlignFrame bottomFrame; + + private Panel outermost; + + /** + * Constructor + */ + public SplitFrame(AlignFrame af1, AlignFrame af2) + { + topFrame = af1; + bottomFrame = af2; + init(); + } + + /** + * Creates a Panel containing two Panels, and adds the first and second + * AlignFrame's components to each. At this stage we have not yet committed to + * whether the enclosing panel will be added to this frame, for display as a + * separate frame, or added to the applet (embedded mode). + */ + public void init() + { + constructSplit(); + + /* + * Try to make and add dna/protein sequence mappings + */ + final AlignViewport topViewport = topFrame.viewport; + final AlignViewport bottomViewport = bottomFrame.viewport; + final AlignmentI topAlignment = topViewport.getAlignment(); + final AlignmentI bottomAlignment = bottomViewport.getAlignment(); + AlignViewport cdna = topAlignment.isNucleotide() ? topViewport + : (bottomAlignment.isNucleotide() ? bottomViewport : null); + AlignViewport protein = !topAlignment.isNucleotide() ? topViewport + : (!bottomAlignment.isNucleotide() ? bottomViewport : null); + + MappingResult mapped = AlignmentUtils.mapProteinToCdna( + protein.getAlignment(), cdna.getAlignment()); + if (mapped != MappingResult.NotMapped) + { + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(topViewport.applet); + ssm.addMappings(protein.getAlignment().getCodonFrames()); + topViewport.setCodingComplement(bottomViewport); + ssm.addCommandListener(cdna); + ssm.addCommandListener(protein); + } + + setCharacterWidth(protein, cdna); + } + + /** + * + */ + protected void constructSplit() + { + setMenuBar(null); + outermost = new Panel(new GridLayout(2, 1)); + + Panel topPanel = new Panel(); + Panel bottomPanel = new Panel(); + outermost.add(topPanel); + outermost.add(bottomPanel); + + addAlignFrameComponents(topFrame, topPanel); + addAlignFrameComponents(bottomFrame, bottomPanel); + } + + /** + * Expand protein to 3 times character width of dna + * + * @param protein + * @param cdna + */ + protected void setCharacterWidth(AlignViewport protein, AlignViewport cdna) + { + if (protein != null && cdna != null) + { + ViewStyleI vs = protein.getViewStyle(); + vs.setCharWidth(3 * vs.getCharWidth()); + protein.setViewStyle(vs); + } + } + + /** + * Add the menu bar, alignment panel and status bar from the AlignFrame to the + * panel. The menu bar is a panel 'reconstructed' from the AlignFrame's frame + * menu bar. This allows each half of the SplitFrame to have its own menu bar. + * + * @param af + * @param panel + */ + private void addAlignFrameComponents(AlignFrame af, Panel panel) + { + panel.setLayout(new BorderLayout()); + Panel menuPanel = af + .makeEmbeddedPopupMenu(af.getMenuBar(), true, false); + panel.add(menuPanel, BorderLayout.NORTH); + panel.add(af.statusBar, BorderLayout.SOUTH); + panel.add(af.alignPanel, BorderLayout.CENTER); + } + + /** + * Display the content panel either as a new frame or embedded in the applet. + * + * @param embedded + * @param applet + */ + public void addToDisplay(boolean embedded, JalviewLite applet) + { + createAlignFrameWindow(embedded, applet); + validate(); + topFrame.alignPanel.adjustAnnotationHeight(); + topFrame.alignPanel.paintAlignment(true); + bottomFrame.alignPanel.adjustAnnotationHeight(); + bottomFrame.alignPanel.paintAlignment(true); + } + + /** + * Either show the content panel in this frame as a new frame, or (if + * embed=true) add it to the applet container instead. + * + * @param embed + * @param applet + */ + public void createAlignFrameWindow(boolean embed, JalviewLite applet) + { + if (embed) + { + applet.add(outermost); + applet.validate(); + } + else + { + this.add(outermost); + int width = Math.max(topFrame.DEFAULT_WIDTH, + bottomFrame.DEFAULT_WIDTH); + int height = topFrame.DEFAULT_HEIGHT + bottomFrame.DEFAULT_HEIGHT; + jalview.bin.JalviewLite + .addFrame(this, this.getTitle(), width, height); + } + } +} diff --git a/src/jalview/appletgui/TreeCanvas.java b/src/jalview/appletgui/TreeCanvas.java index 745520b..6630d8e 100755 --- a/src/jalview/appletgui/TreeCanvas.java +++ b/src/jalview/appletgui/TreeCanvas.java @@ -20,15 +20,35 @@ */ package jalview.appletgui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; - -import jalview.analysis.*; -import jalview.datamodel.*; -import jalview.schemes.*; -import jalview.util.*; +import jalview.analysis.Conservation; +import jalview.analysis.NJTree; +import jalview.api.AlignViewportI; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceNode; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.ColourSchemeProperty; +import jalview.schemes.ResidueProperties; +import jalview.schemes.UserColourScheme; +import jalview.util.Format; +import jalview.util.MappingUtils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.ScrollPane; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; public class TreeCanvas extends Panel implements MouseListener, MouseMotionListener @@ -582,6 +602,13 @@ public class TreeCanvas extends Panel implements MouseListener, av.setSelectionGroup(null); av.getAlignment().deleteAllGroups(); av.clearSequenceColours(); + final AlignViewportI codingComplement = av.getCodingComplement(); + if (codingComplement != null) + { + codingComplement.setSelectionGroup(null); + codingComplement.getAlignment().deleteAllGroups(); + codingComplement.clearSequenceColours(); + } colourGroups(); @@ -639,7 +666,7 @@ public class TreeCanvas extends Panel implements MouseListener, if (cs != null) { cs.setThreshold(av.getGlobalColourScheme().getThreshold(), - av.getIgnoreGapsConsensus()); + av.isIgnoreGapsConsensus()); } } // TODO: cs used to be initialized with a sequence collection and @@ -666,9 +693,31 @@ public class TreeCanvas extends Panel implements MouseListener, av.getAlignment().addGroup(sg); + // TODO this is duplicated with gui TreeCanvas - refactor + av.getAlignment().addGroup(sg); + final AlignViewportI codingComplement = av.getCodingComplement(); + if (codingComplement != null) + { + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av, + codingComplement); + if (mappedGroup.getSequences().size() > 0) + { + codingComplement.getAlignment().addGroup(mappedGroup); + for (SequenceI seq : mappedGroup.getSequences()) + { + // TODO why does gui require col.brighter() here?? + codingComplement.setSequenceColour(seq, col); + } + } + } + } ap.updateAnnotation(); - + if (av.getCodingComplement() != null) + { + ((AlignViewport) av.getCodingComplement()).firePropertyChange( + "alignment", null, ap.av.getAlignment().getSequences()); + } } public void setShowDistances(boolean state) diff --git a/src/jalview/appletgui/UserDefinedColours.java b/src/jalview/appletgui/UserDefinedColours.java index afa6419..32f5729 100644 --- a/src/jalview/appletgui/UserDefinedColours.java +++ b/src/jalview/appletgui/UserDefinedColours.java @@ -427,7 +427,9 @@ public class UserDefinedColours extends Panel implements ActionListener, { applyButton_actionPerformed(); if (dialog != null) + { dialog.setVisible(false); + } frame.setVisible(false); } @@ -489,7 +491,7 @@ public class UserDefinedColours extends Panel implements ActionListener, UserColourScheme ucs = new UserColourScheme(newColours); if (ap != null) { - ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } if (ap != null) @@ -557,7 +559,9 @@ public class UserDefinedColours extends Panel implements ActionListener, } } if (dialog != null) + { dialog.setVisible(false); + } frame.setVisible(false); return; diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index eede62e..51d83fa 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -966,7 +966,7 @@ public class Jalview private static FeatureFetcher startFeatureFetching(final Vector dasSources) { FeatureFetcher ff = new FeatureFetcher(); - AlignFrame afs[] = Desktop.getAlignframes(); + AlignFrame afs[] = Desktop.getAlignFrames(); if (afs == null || afs.length == 0) { return null; diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java index e022c73..a004f24 100644 --- a/src/jalview/bin/JalviewLite.java +++ b/src/jalview/bin/JalviewLite.java @@ -25,6 +25,7 @@ import jalview.appletgui.AlignFrame; import jalview.appletgui.AlignViewport; import jalview.appletgui.EmbmenuFrame; import jalview.appletgui.FeatureSettings; +import jalview.appletgui.SplitFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; @@ -37,7 +38,9 @@ import jalview.io.AnnotationFile; import jalview.io.AppletFormatAdapter; import jalview.io.FileParse; import jalview.io.IdentifyFile; +import jalview.io.JPredFile; import jalview.io.JnetAnnotationMaker; +import jalview.io.NewickFile; import jalview.javascript.JSFunctionExec; import jalview.javascript.JalviewLiteJsApi; import jalview.javascript.JsCallBack; @@ -57,9 +60,12 @@ import java.awt.event.ActionEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.Hashtable; +import java.util.List; import java.util.StringTokenizer; import java.util.Vector; @@ -76,6 +82,10 @@ public class JalviewLite extends Applet implements StructureSelectionManagerProvider, JalviewLiteJsApi { + private static final String TRUE = "true"; + + private static final String FALSE = "false"; + public StructureSelectionManager getStructureSelectionManager() { return StructureSelectionManager.getStructureSelectionManager(this); @@ -447,12 +457,11 @@ public class JalviewLite extends Applet implements end = rs.findIndex(end); if (csel != null) { - Vector cs = csel.getSelected(); + List cs = csel.getSelected(); csel.clear(); - for (int csi = 0, csiS = cs.size(); csi < csiS; csi++) + for (Integer selectedCol : cs) { - csel.addElement(rs.findIndex(((Integer) cs.elementAt(csi)) - .intValue())); + csel.addElement(rs.findIndex(selectedCol)); } } } @@ -494,7 +503,7 @@ public class JalviewLite extends Applet implements { try { - boolean seqlimits = suffix.equalsIgnoreCase("true"); + boolean seqlimits = suffix.equalsIgnoreCase(TRUE); if (alf.viewport.getSelectionGroup() != null) { // JBPNote: getSelectionAsNewSequence behaviour has changed - this @@ -630,7 +639,7 @@ public class JalviewLite extends Applet implements final String _undoName = undoName; // TODO: deal with synchronization here: cannot raise any events until after // this has returned. - return alf.sortBy(aorder, _undoName) ? "true" : ""; + return alf.sortBy(aorder, _undoName) ? TRUE : ""; } /* @@ -640,7 +649,7 @@ public class JalviewLite extends Applet implements */ public String getAlignment(String format) { - return getAlignmentFrom(getDefaultTargetFrame(), format, "true"); + return getAlignmentFrom(getDefaultTargetFrame(), format, TRUE); } /* @@ -652,7 +661,7 @@ public class JalviewLite extends Applet implements */ public String getAlignmentFrom(AlignFrame alf, String format) { - return getAlignmentFrom(alf, format, "true"); + return getAlignmentFrom(alf, format, TRUE); } /* @@ -678,7 +687,7 @@ public class JalviewLite extends Applet implements { try { - boolean seqlimits = suffix.equalsIgnoreCase("true"); + boolean seqlimits = suffix.equalsIgnoreCase(TRUE); String reply = new AppletFormatAdapter().formatSequences(format, alf.viewport.getAlignment(), seqlimits); @@ -1233,7 +1242,10 @@ public class JalviewLite extends Applet implements String file = "No file"; - Button launcher = new Button("Start Jalview"); + String file2 = "No file"; + + Button launcher = new Button( + MessageManager.getString("label.start_jalview")); /** * The currentAlignFrame is static, it will change if and when the user @@ -1361,11 +1373,7 @@ public class JalviewLite extends Applet implements /** * turn on extra applet debugging */ - String dbg = getParameter("debug"); - if (dbg != null) - { - debug = dbg.toLowerCase().equals("true"); - } + debug = TRUE.equalsIgnoreCase(getParameter("debug")); if (debug) { @@ -1378,7 +1386,7 @@ public class JalviewLite extends Applet implements if (externalsviewer != null) { useXtrnalSviewer = externalsviewer.trim().toLowerCase() - .equals("true"); + .equals(TRUE); } /** * if true disable the check for jmol @@ -1386,7 +1394,7 @@ public class JalviewLite extends Applet implements String chkforJmol = getParameter("nojmol"); if (chkforJmol != null) { - checkForJmol = !chkforJmol.equals("true"); + checkForJmol = !chkforJmol.equals(TRUE); } /** * get the separator parameter if present @@ -1451,38 +1459,37 @@ public class JalviewLite extends Applet implements file = data.toString(); } } + file2 = getParameter("file2"); - final JalviewLite jvapplet = this; - if (getParameter("embedded") != null - && getParameter("embedded").equalsIgnoreCase("true")) + embedded = TRUE.equalsIgnoreCase(getParameter("embedded")); + if (embedded) { - // Launch as embedded applet in page - embedded = true; - LoadingThread loader = new LoadingThread(file, jvapplet); + LoadingThread loader = new LoadingThread(file, file2, this); loader.start(); } else if (file != null) { - if (getParameter("showbutton") == null - || !getParameter("showbutton").equalsIgnoreCase("false")) + /* + * Start the applet immediately or show a button to start it + */ + if (FALSE.equalsIgnoreCase(getParameter("showbutton"))) + { + LoadingThread loader = new LoadingThread(file, file2, this); + loader.start(); + } + else { - // Add the JalviewLite 'Button' to the page add(launcher); launcher.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { - LoadingThread loader = new LoadingThread(file, jvapplet); + LoadingThread loader = new LoadingThread(file, file2, + JalviewLite.this); loader.start(); } }); } - else - { - // Open jalviewLite immediately. - LoadingThread loader = new LoadingThread(file, jvapplet); - loader.start(); - } } else { @@ -1756,27 +1763,19 @@ public class JalviewLite extends Applet implements class LoadingThread extends Thread { /** - * State variable: File source - */ - String file; - - /** * State variable: protocol for access to file source */ String protocol; - /** - * State variable: format of file source - */ - String format; + String _file; // alignment file or URL spec - String _file; + String _file2; // second alignment file or URL spec JalviewLite applet; private void dbgMsg(String msg) { - if (applet.debug) + if (JalviewLite.debug) { System.err.println(msg); } @@ -1809,9 +1808,16 @@ public class JalviewLite extends Applet implements return file; } - public LoadingThread(String _file, JalviewLite _applet) + // public LoadingThread(String _file, JalviewLite _applet) + // { + // this._file = _file; + // applet = _applet; + // } + + public LoadingThread(String file, String file2, JalviewLite _applet) { - this._file = _file; + this._file = file; + this._file2 = file2; applet = _applet; } @@ -1828,25 +1834,112 @@ public class JalviewLite extends Applet implements } catch (Exception e) { } - ; } startLoading(); // applet.callInitCallback(); } + /** + * Load the alignment and any related files as specified by applet + * parameters + */ private void startLoading() { - AlignFrame newAlignFrame; dbgMsg("Loading thread started with:\n>>file\n" + _file + ">>endfile"); - file = setProtocolState(_file); - format = new jalview.io.IdentifyFile().Identify(file, protocol); - dbgMsg("File identified as '" + format + "'"); dbgMsg("Loading started."); - Alignment al = null; + + AlignFrame newAlignFrame = readAlignment(_file); + AlignFrame newAlignFrame2 = readAlignment(_file2); + if (newAlignFrame != null) + { + addToDisplay(newAlignFrame, newAlignFrame2); + loadTree(newAlignFrame); + + loadScoreFile(newAlignFrame); + + loadFeatures(newAlignFrame); + + loadAnnotations(newAlignFrame); + + loadJnetFile(newAlignFrame); + + loadPdbFiles(newAlignFrame); + } + else + { + fileFound = false; + applet.remove(launcher); + applet.repaint(); + } + callInitCallback(); + } + + /** + * Add an AlignFrame to the display; or if two are provided, a SplitFrame. + * + * @param af + * @param af2 + */ + public void addToDisplay(AlignFrame af, AlignFrame af2) + { + if (af2 == null) + { + af.addToDisplay(embedded); + } + else + { + SplitFrame sf = new SplitFrame(af, af2); + sf.addToDisplay(embedded, JalviewLite.this); + } + } + + /** + * Read the alignment file (from URL, text 'paste', or archive by + * classloader). + * + * @return + */ + protected AlignFrame readAlignment(String fileParam) + { + if (fileParam == null) + { + return null; + } + String resolvedFile = setProtocolState(fileParam); + String format = new IdentifyFile().Identify(resolvedFile, protocol); + dbgMsg("File identified as '" + format + "'"); + AlignmentI al = null; try { - al = new AppletFormatAdapter().readFile(file, protocol, format); + al = new AppletFormatAdapter().readFile(resolvedFile, protocol, format); + if ((al != null) && (al.getHeight() > 0)) + { + dbgMsg("Successfully loaded file."); + al.setDataset(null); + AlignFrame newAlignFrame = new AlignFrame(al, applet, + resolvedFile, embedded, false); + newAlignFrame.setTitle(resolvedFile); + if (initialAlignFrame == null) + { + initialAlignFrame = newAlignFrame; + } + // update the focus. + currentAlignFrame = newAlignFrame; + + if (protocol == AppletFormatAdapter.PASTE) + { + newAlignFrame.setTitle(MessageManager.formatMessage( + "label.sequences_from", new Object[] + { applet.getDocumentBase().toString() })); + } + + newAlignFrame.statusBar.setText(MessageManager.formatMessage( + "label.successfully_loaded_file", new Object[] + { resolvedFile })); + + return newAlignFrame; + } } catch (java.io.IOException ex) { dbgMsg("File load exception."); @@ -1855,9 +1948,9 @@ public class JalviewLite extends Applet implements { try { - FileParse fp = new FileParse(file, protocol); + FileParse fp = new FileParse(resolvedFile, protocol); String ln = null; - dbgMsg(">>>Dumping contents of '" + file + "' " + "(" + dbgMsg(">>>Dumping contents of '" + resolvedFile + "' " + "(" + protocol + ")"); while ((ln = fp.nextLine()) != null) { @@ -1872,350 +1965,378 @@ public class JalviewLite extends Applet implements } } } - if ((al != null) && (al.getHeight() > 0)) + return null; + } + + /** + * Load PDBFiles if any specified by parameter(s). Returns true if loaded, + * else false. + * + * @param alignFrame + * @return + */ + protected boolean loadPdbFiles(AlignFrame alignFrame) + { + boolean result = false; + /* + * Undocumented for 2.6 - + * related to JAL-434 + */ + + applet.setAlignPdbStructures(getDefaultParameter("alignpdbfiles", + false)); + /* + * + * + * + * + * + */ + + int pdbFileCount = 0; + // Accumulate pdbs here if they are heading for the same view (if + // alignPdbStructures is true) + Vector pdbs = new Vector(); + // create a lazy matcher if we're asked to + jalview.analysis.SequenceIdMatcher matcher = (applet + .getDefaultParameter("relaxedidmatch", false)) ? new jalview.analysis.SequenceIdMatcher( + alignFrame.getAlignViewport().getAlignment() + .getSequencesArray()) : null; + + String param; + do { - dbgMsg("Successfully loaded file."); - newAlignFrame = new AlignFrame(al, applet, file, embedded); - if (initialAlignFrame == null) + if (pdbFileCount > 0) { - initialAlignFrame = newAlignFrame; + param = applet.getParameter("PDBFILE" + pdbFileCount); } - // update the focus. - currentAlignFrame = newAlignFrame; - - if (protocol == jalview.io.AppletFormatAdapter.PASTE) + else { - newAlignFrame.setTitle(MessageManager.formatMessage( - "label.sequences_from", new String[] - { applet.getDocumentBase().toString() })); + param = applet.getParameter("PDBFILE"); } - newAlignFrame.statusBar.setText(MessageManager.formatMessage( - "label.successfully_loaded_file", new String[] - { file })); - - String treeFile = applet.getParameter("tree"); - if (treeFile == null) + if (param != null) { - treeFile = applet.getParameter("treeFile"); - } + PDBEntry pdb = new PDBEntry(); - if (treeFile != null) - { - try + String seqstring; + SequenceI[] seqs = null; + String[] chains = null; + + StringTokenizer st = new StringTokenizer(param, " "); + + if (st.countTokens() < 2) { - treeFile = setProtocolState(treeFile); - /* - * if (inArchive(treeFile)) { protocol = - * AppletFormatAdapter.CLASSLOADER; } else { protocol = - * AppletFormatAdapter.URL; treeFile = addProtocol(treeFile); } - */ - jalview.io.NewickFile fin = new jalview.io.NewickFile(treeFile, - protocol); - - fin.parse(); - - if (fin.getTree() != null) + String sequence = applet.getParameter("PDBSEQ"); + if (sequence != null) { - newAlignFrame.loadTree(fin, treeFile); - dbgMsg("Successfuly imported tree."); + seqs = new SequenceI[] + { matcher == null ? (Sequence) alignFrame.getAlignViewport() + .getAlignment().findName(sequence) : matcher + .findIdMatch(sequence) }; } - else + + } + else + { + param = st.nextToken(); + Vector tmp = new Vector(); + Vector tmp2 = new Vector(); + + while (st.hasMoreTokens()) + { + seqstring = st.nextToken(); + StringTokenizer st2 = new StringTokenizer(seqstring, "="); + if (st2.countTokens() > 1) + { + // This is the chain + tmp2.addElement(st2.nextToken()); + seqstring = st2.nextToken(); + } + tmp.addElement(matcher == null ? (Sequence) alignFrame + .getAlignViewport().getAlignment() + .findName(seqstring) : matcher.findIdMatch(seqstring)); + } + + seqs = new SequenceI[tmp.size()]; + tmp.copyInto(seqs); + if (tmp2.size() == tmp.size()) { - dbgMsg("Tree parameter did not resolve to a valid tree."); + chains = new String[tmp2.size()]; + tmp2.copyInto(chains); } - } catch (Exception ex) + } + param = setProtocolState(param); + + if (// !jmolAvailable + // && + protocol == AppletFormatAdapter.CLASSLOADER && !useXtrnalSviewer) { - ex.printStackTrace(); + // Re: JAL-357 : the bug isn't a problem if we are using an + // external viewer! + // TODO: verify this Re: + // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605 + // This exception preserves the current behaviour where, even if + // the local pdb file was identified in the class loader + protocol = AppletFormatAdapter.URL; // this is probably NOT + // CORRECT! + param = addProtocol(param); // } - } - /* - * Try to load T-Coffee score file - */ - String sScoreFile = applet.getParameter("scoreFile"); - if (sScoreFile != null && !"".equals(sScoreFile)) - { - try + pdb.setFile(param); + + if (seqs != null) { - if (debug) + for (int i = 0; i < seqs.length; i++) { - System.err - .println("Attempting to load T-COFFEE score file from the scoreFile parameter"); + if (seqs[i] != null) + { + ((Sequence) seqs[i]).addPDBId(pdb); + StructureSelectionManager.getStructureSelectionManager( + applet).registerPDBEntry(pdb); + } + else + { + if (JalviewLite.debug) + { + // this may not really be a problem but we give a warning + // anyway + System.err + .println("Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence " + + i + ")"); + } + } } - if (!newAlignFrame.loadScoreFile(sScoreFile)) + + if (!alignPdbStructures) { - System.err - .println("Failed to parse T-COFFEE parameter as a valid score file ('" - + sScoreFile + "')"); + alignFrame.newStructureView(applet, pdb, seqs, chains, + protocol); + } + else + { + pdbs.addElement(new Object[] + { pdb, seqs, chains, new String(protocol) }); } - } catch (Exception e) - { - System.err.printf("Cannot read score file: '%s'. Cause: %s \n", - sScoreFile, e.getMessage()); } } - // /////////////////////////// - // modify display of features - // we do this before any features have been loaded, ensuring any hidden - // groups are hidden when features first displayed - // - // hide specific groups - // - String param = applet.getParameter("hidefeaturegroups"); - if (param != null) - { - newAlignFrame.setFeatureGroupState(separatorListToArray(param), - false); - // applet.setFeatureGroupStateOn(newAlignFrame, param, false); - } - // show specific groups - param = applet.getParameter("showfeaturegroups"); - if (param != null) - { - newAlignFrame.setFeatureGroupState(separatorListToArray(param), - true); - // applet.setFeatureGroupStateOn(newAlignFrame, param, true); + pdbFileCount++; + } while (param != null || pdbFileCount < 10); + if (pdbs.size() > 0) + { + SequenceI[][] seqs = new SequenceI[pdbs.size()][]; + PDBEntry[] pdb = new PDBEntry[pdbs.size()]; + String[][] chains = new String[pdbs.size()][]; + String[] protocols = new String[pdbs.size()]; + for (int pdbsi = 0, pdbsiSize = pdbs.size(); pdbsi < pdbsiSize; pdbsi++) + { + Object[] o = (Object[]) pdbs.elementAt(pdbsi); + pdb[pdbsi] = (PDBEntry) o[0]; + seqs[pdbsi] = (SequenceI[]) o[1]; + chains[pdbsi] = (String[]) o[2]; + protocols[pdbsi] = (String) o[3]; } - // and now load features - param = applet.getParameter("features"); - if (param != null) + alignFrame.alignedStructureView(applet, pdb, seqs, chains, + protocols); + result = true; + } + return result; + } + + /** + * Load in a Jnetfile if specified by parameter. Returns true if loaded, + * else false. + * + * @param alignFrame + * @return + */ + protected boolean loadJnetFile(AlignFrame alignFrame) + { + boolean result = false; + String param = applet.getParameter("jnetfile"); + if (param != null) + { + try { param = setProtocolState(param); - - newAlignFrame.parseFeaturesFile(param, protocol); + JPredFile predictions = new JPredFile(param, protocol); + JnetAnnotationMaker.add_annotation(predictions, + alignFrame.viewport.getAlignment(), 0, false); + // false == do not add sequence profile from concise output + SequenceI repseq = alignFrame.viewport.getAlignment() + .getSequenceAt(0); + alignFrame.viewport.getAlignment().setSeqrep(repseq); + ColumnSelection cs = new ColumnSelection(); + cs.hideInsertionsFor(repseq); + alignFrame.viewport.setColumnSelection(cs); + alignFrame.alignPanel.fontChanged(); + alignFrame.alignPanel.setScrollValues(0, 0); + result = true; + } catch (Exception ex) + { + ex.printStackTrace(); } + } + return result; + } + + /** + * Load annotations if specified by parameter. Returns true if loaded, else + * false. + * + * @param alignFrame + * @return + */ + protected boolean loadAnnotations(AlignFrame alignFrame) + { + boolean result = false; + String param = applet.getParameter("annotations"); + if (param != null) + { + param = setProtocolState(param); - param = applet.getParameter("showFeatureSettings"); - if (param != null && param.equalsIgnoreCase("true")) + if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport, + param, protocol)) { - newAlignFrame.viewport.setShowSequenceFeatures(true); - new FeatureSettings(newAlignFrame.alignPanel); + alignFrame.alignPanel.fontChanged(); + alignFrame.alignPanel.setScrollValues(0, 0); + result = true; } - - param = applet.getParameter("annotations"); - if (param != null) + else { - param = setProtocolState(param); + System.err + .println("Annotations were not added from annotation file '" + + param + "'"); + } + } + return result; + } - if (new AnnotationFile().annotateAlignmentView( - newAlignFrame.viewport, param, protocol)) - { - newAlignFrame.alignPanel.fontChanged(); - newAlignFrame.alignPanel.setScrollValues(0, 0); - } - else - { - System.err - .println("Annotations were not added from annotation file '" - + param + "'"); - } + /** + * Load features file and view settings as specified by parameters. Returns + * true if features were loaded, else false. + * + * @param alignFrame + * @return + */ + protected boolean loadFeatures(AlignFrame alignFrame) + { + boolean result = false; + // /////////////////////////// + // modify display of features + // we do this before any features have been loaded, ensuring any hidden + // groups are hidden when features first displayed + // + // hide specific groups + // + String param = applet.getParameter("hidefeaturegroups"); + if (param != null) + { + alignFrame.setFeatureGroupState(separatorListToArray(param), false); + // applet.setFeatureGroupStateOn(newAlignFrame, param, false); + } + // show specific groups + param = applet.getParameter("showfeaturegroups"); + if (param != null) + { + alignFrame.setFeatureGroupState(separatorListToArray(param), true); + // applet.setFeatureGroupStateOn(newAlignFrame, param, true); + } + // and now load features + param = applet.getParameter("features"); + if (param != null) + { + param = setProtocolState(param); - } + result = alignFrame.parseFeaturesFile(param, protocol); + } - param = applet.getParameter("jnetfile"); - if (param != null) + param = applet.getParameter("showFeatureSettings"); + if (param != null && param.equalsIgnoreCase(TRUE)) + { + alignFrame.viewport.setShowSequenceFeatures(true); + new FeatureSettings(alignFrame.alignPanel); + } + return result; + } + + /** + * Load a score file if specified by parameter. Returns true if file was + * loaded, else false. + * + * @param alignFrame + */ + protected boolean loadScoreFile(AlignFrame alignFrame) + { + boolean result = false; + String sScoreFile = applet.getParameter("scoreFile"); + if (sScoreFile != null && !"".equals(sScoreFile)) + { + try { - try + if (debug) { - param = setProtocolState(param); - jalview.io.JPredFile predictions = new jalview.io.JPredFile( - param, protocol); - JnetAnnotationMaker.add_annotation(predictions, - newAlignFrame.viewport.getAlignment(), 0, false); // false==do - SequenceI repseq = newAlignFrame.viewport.getAlignment() - .getSequenceAt(0); - newAlignFrame.viewport.getAlignment().setSeqrep(repseq); - ColumnSelection cs = new ColumnSelection(); - cs.hideInsertionsFor(repseq); - newAlignFrame.viewport.setColumnSelection(cs); - // not - // add - // sequence - // profile - // from - // concise - // output - newAlignFrame.alignPanel.fontChanged(); - newAlignFrame.alignPanel.setScrollValues(0, 0); - } catch (Exception ex) + System.err + .println("Attempting to load T-COFFEE score file from the scoreFile parameter"); + } + result = alignFrame.loadScoreFile(sScoreFile); + if (!result) { - ex.printStackTrace(); + System.err + .println("Failed to parse T-COFFEE parameter as a valid score file ('" + + sScoreFile + "')"); } + } catch (Exception e) + { + System.err.printf("Cannot read score file: '%s'. Cause: %s \n", + sScoreFile, e.getMessage()); } - /* - * Undocumented for 2.6 - * - related to JAL-434 - */ - applet.setAlignPdbStructures(getDefaultParameter("alignpdbfiles", - false)); - /* - * - * - * - * - * - */ + } + return result; + } - int pdbFileCount = 0; - // Accumulate pdbs here if they are heading for the same view (if - // alignPdbStructures is true) - Vector pdbs = new Vector(); - // create a lazy matcher if we're asked to - jalview.analysis.SequenceIdMatcher matcher = (applet - .getDefaultParameter("relaxedidmatch", false)) ? new jalview.analysis.SequenceIdMatcher( - newAlignFrame.getAlignViewport().getAlignment() - .getSequencesArray()) : null; + /** + * Load a tree for the alignment if specified by parameter. Returns true if + * a tree was loaded, else false. + * + * @param alignFrame + * @return + */ + protected boolean loadTree(AlignFrame alignFrame) + { + boolean result = false; + String treeFile = applet.getParameter("tree"); + if (treeFile == null) + { + treeFile = applet.getParameter("treeFile"); + } - do + if (treeFile != null) + { + try { - if (pdbFileCount > 0) + treeFile = setProtocolState(treeFile); + NewickFile fin = new NewickFile(treeFile, protocol); + fin.parse(); + + if (fin.getTree() != null) { - param = applet.getParameter("PDBFILE" + pdbFileCount); + alignFrame.loadTree(fin, treeFile); + result = true; + dbgMsg("Successfully imported tree."); } else { - param = applet.getParameter("PDBFILE"); - } - - if (param != null) - { - PDBEntry pdb = new PDBEntry(); - - String seqstring; - SequenceI[] seqs = null; - String[] chains = null; - - StringTokenizer st = new StringTokenizer(param, " "); - - if (st.countTokens() < 2) - { - String sequence = applet.getParameter("PDBSEQ"); - if (sequence != null) - { - seqs = new SequenceI[] - { matcher == null ? (Sequence) newAlignFrame - .getAlignViewport().getAlignment() - .findName(sequence) : matcher.findIdMatch(sequence) }; - } - - } - else - { - param = st.nextToken(); - Vector tmp = new Vector(); - Vector tmp2 = new Vector(); - - while (st.hasMoreTokens()) - { - seqstring = st.nextToken(); - StringTokenizer st2 = new StringTokenizer(seqstring, "="); - if (st2.countTokens() > 1) - { - // This is the chain - tmp2.addElement(st2.nextToken()); - seqstring = st2.nextToken(); - } - tmp.addElement(matcher == null ? (Sequence) newAlignFrame - .getAlignViewport().getAlignment() - .findName(seqstring) : matcher - .findIdMatch(seqstring)); - } - - seqs = new SequenceI[tmp.size()]; - tmp.copyInto(seqs); - if (tmp2.size() == tmp.size()) - { - chains = new String[tmp2.size()]; - tmp2.copyInto(chains); - } - } - param = setProtocolState(param); - - if (// !jmolAvailable - // && - protocol == AppletFormatAdapter.CLASSLOADER - && !useXtrnalSviewer) - { - // Re: JAL-357 : the bug isn't a problem if we are using an - // external viewer! - // TODO: verify this Re: - // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605 - // This exception preserves the current behaviour where, even if - // the local pdb file was identified in the class loader - protocol = AppletFormatAdapter.URL; // this is probably NOT - // CORRECT! - param = addProtocol(param); // - } - - pdb.setFile(param); - - if (seqs != null) - { - for (int i = 0; i < seqs.length; i++) - { - if (seqs[i] != null) - { - ((Sequence) seqs[i]).addPDBId(pdb); - StructureSelectionManager.getStructureSelectionManager( - applet).registerPDBEntry(pdb); - } - else - { - if (JalviewLite.debug) - { - // this may not really be a problem but we give a warning - // anyway - System.err - .println("Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence " - + i + ")"); - } - } - } - - if (!alignPdbStructures) - { - newAlignFrame.newStructureView(applet, pdb, seqs, chains, - protocol); - } - else - { - pdbs.addElement(new Object[] - { pdb, seqs, chains, new String(protocol) }); - } - } + dbgMsg("Tree parameter did not resolve to a valid tree."); } - - pdbFileCount++; - } while (param != null || pdbFileCount < 10); - if (pdbs.size() > 0) + } catch (Exception ex) { - SequenceI[][] seqs = new SequenceI[pdbs.size()][]; - PDBEntry[] pdb = new PDBEntry[pdbs.size()]; - String[][] chains = new String[pdbs.size()][]; - String[] protocols = new String[pdbs.size()]; - for (int pdbsi = 0, pdbsiSize = pdbs.size(); pdbsi < pdbsiSize; pdbsi++) - { - Object[] o = (Object[]) pdbs.elementAt(pdbsi); - pdb[pdbsi] = (PDBEntry) o[0]; - seqs[pdbsi] = (SequenceI[]) o[1]; - chains[pdbsi] = (String[]) o[2]; - protocols[pdbsi] = (String) o[3]; - } - newAlignFrame.alignedStructureView(applet, pdb, seqs, chains, - protocols); - + ex.printStackTrace(); } } - else - { - fileFound = false; - applet.remove(launcher); - applet.repaint(); - } - callInitCallback(); + return result; } /** @@ -2246,48 +2367,88 @@ public class JalviewLite extends Applet implements } } - String addProtocol(String file) + /** + * If the file is not already in URL format, tries to locate it by resolving + * as a URL. + * + * @param file + * @return + */ + String addProtocol(final String file) { if (file.indexOf("://") == -1) { - String fl = applet.resolveUrlForLocalOrAbsolute(file, + /* + * Try relative to document base + */ + String url = applet.resolveUrlForLocalOrAbsolute(file, getDocumentBase()); - try + if (urlExists(url)) { - if (new java.net.URL(fl).openStream() != null) + if (debug) { - if (debug) - { - System.err.println("Prepended document base for resource: '" - + file + "'"); - } - return fl; + System.err.println("Prepended document base for resource: '" + + file + "'"); } - } catch (Exception x) - { + return url; } - ; - fl = applet.resolveUrlForLocalOrAbsolute(file, getCodeBase()); - try + + /* + * Try relative to codebase + */ + url = applet.resolveUrlForLocalOrAbsolute(file, getCodeBase()); + if (urlExists(url)) { - if (new java.net.URL(fl).openStream() != null) + if (debug) { - if (debug) - { - System.err.println("Prepended codebase for resource: '" - + file + "'"); - } - return fl; + System.err.println("Prepended codebase for resource: '" + file + + "'"); } - } catch (Exception x) - { + return url; } - ; - } + /* + * Not resolved, leave unchanged + */ return file; } + + /** + * Returns true if an input stream can be opened on the specified URL, else + * false. + * + * @param url + * @return + */ + private boolean urlExists(String url) + { + InputStream is = null; + try + { + is = new URL(url).openStream(); + if (is != null) + { + return true; + } + } catch (Exception x) + { + // ignore + } finally + { + if (is != null) + { + try + { + is.close(); + } catch (IOException e) + { + // ignore + } + } + } + return false; + } } /** @@ -2566,7 +2727,7 @@ public class JalviewLite extends Applet implements { return def; } - if (stn.toLowerCase().equals("true")) + if (stn.toLowerCase().equals(TRUE)) { return true; } diff --git a/src/jalview/commands/ChangeCaseCommand.java b/src/jalview/commands/ChangeCaseCommand.java index 47b4d9d..cc0502f 100644 --- a/src/jalview/commands/ChangeCaseCommand.java +++ b/src/jalview/commands/ChangeCaseCommand.java @@ -20,7 +20,10 @@ */ package jalview.commands; -import jalview.datamodel.*; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; + +import java.util.List; public class ChangeCaseCommand implements CommandI { @@ -36,10 +39,10 @@ public class ChangeCaseCommand implements CommandI SequenceI[] seqs; - int[][] regions; + List regions; public ChangeCaseCommand(String description, SequenceI[] seqs, - int[][] regions, int caseChange) + List regions, int caseChange) { this.description = description; this.seqs = seqs; @@ -73,21 +76,21 @@ public class ChangeCaseCommand implements CommandI String sequence; int start, end; char nextChar; - for (int r = 0; r < regions.length; r++) + for (int[] r : regions) { - start = regions[r][0]; + start = r[0]; for (int s = 0; s < seqs.length; s++) { sequence = seqs[s].getSequenceAsString(); StringBuffer newSeq = new StringBuffer(); - if (regions[r][1] > sequence.length()) + if (r[1] > sequence.length()) { end = sequence.length(); } else { - end = regions[r][1]; + end = r[1]; } if (start > 0) diff --git a/src/jalview/commands/EditCommand.java b/src/jalview/commands/EditCommand.java index 82de3b2..b2ecb7e 100644 --- a/src/jalview/commands/EditCommand.java +++ b/src/jalview/commands/EditCommand.java @@ -26,11 +26,16 @@ import jalview.datamodel.Annotation; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.util.ReverseListIterator; +import jalview.util.StringUtils; import java.util.ArrayList; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Map; /** * @@ -58,7 +63,55 @@ public class EditCommand implements CommandI { public enum Action { - INSERT_GAP, DELETE_GAP, CUT, PASTE, REPLACE, INSERT_NUC + INSERT_GAP + { + @Override + public Action getUndoAction() + { + return DELETE_GAP; + } + }, + DELETE_GAP + { + @Override + public Action getUndoAction() + { + return INSERT_GAP; + } + }, + CUT + { + @Override + public Action getUndoAction() + { + return PASTE; + } + }, + PASTE + { + @Override + public Action getUndoAction() + { + return CUT; + } + }, + REPLACE + { + @Override + public Action getUndoAction() + { + return REPLACE; + } + }, + INSERT_NUC + { + @Override + public Action getUndoAction() + { + return null; + } + }; + public abstract Action getUndoAction(); }; private List edits = new ArrayList(); @@ -110,13 +163,88 @@ public class EditCommand implements CommandI } /** - * Add the given edit command to the stored list of commands. + * Add the given edit command to the stored list of commands. If simply + * expanding the range of the last command added, then modify it instead of + * adding a new command. * * @param e */ - protected void addEdit(Edit e) + public void addEdit(Edit e) { - edits.add(e); + if (!expandEdit(edits, e)) + { + edits.add(e); + } + } + + /** + * Returns true if the new edit is incorporated by updating (expanding the + * range of) the last edit on the list, else false. We can 'expand' the last + * edit if the new one is the same action, on the same sequences, and acts on + * a contiguous range. This is the case where a mouse drag generates a series + * of contiguous gap insertions or deletions. + * + * @param edits + * @param e + * @return + */ + protected static boolean expandEdit(List edits, Edit e) + { + if (edits == null || edits.isEmpty()) + { + return false; + } + Edit lastEdit = edits.get(edits.size() - 1); + Action action = e.command; + if (lastEdit.command != action) + { + return false; + } + + /* + * Both commands must act on the same sequences - compare the underlying + * dataset sequences, rather than the aligned sequences, which change as + * they are edited. + */ + if (lastEdit.seqs.length != e.seqs.length) + { + return false; + } + for (int i = 0; i < e.seqs.length; i++) + { + if (lastEdit.seqs[i].getDatasetSequence() != e.seqs[i] + .getDatasetSequence()) + { + return false; + } + } + + /** + * Check a contiguous edit; either + *
    + *
  • a new Insert positions to the right of the last , or
  • + *
  • a new Delete gaps which is positions to the left of the last + * delete.
  • + *
+ */ + boolean contiguous = (action == Action.INSERT_GAP && e.position == lastEdit.position + + lastEdit.number) + || (action == Action.DELETE_GAP && e.position + e.number == lastEdit.position); + if (contiguous) + { + /* + * We are just expanding the range of the last edit. For delete gap, also + * moving the start position left. + */ + lastEdit.number += e.number; + lastEdit.seqs = e.seqs; + if (action == Action.DELETE_GAP) + { + lastEdit.position--; + } + return true; + } + return false; } /** @@ -209,7 +337,32 @@ public class EditCommand implements CommandI edit.fullAlignmentHeight = true; } - edits.add(edit); + addEdit(edit); + + if (performEdit) + { + performEdit(edit, views); + } + } + + /** + * Overloaded method that accepts an Edit object with additional parameters. + * + * @param edit + * @param al + * @param performEdit + * @param views + */ + final public void appendEdit(Edit edit, AlignmentI al, + boolean performEdit, AlignmentI[] views) + { + if (al.getHeight() == edit.seqs.length) + { + edit.al = al; + edit.fullAlignmentHeight = true; + } + + addEdit(edit); if (performEdit) { @@ -223,7 +376,7 @@ public class EditCommand implements CommandI * @param commandIndex * @param views */ - final void performEdit(int commandIndex, AlignmentI[] views) + public final void performEdit(int commandIndex, AlignmentI[] views) { ListIterator iterator = edits.listIterator(commandIndex); while (iterator.hasNext()) @@ -239,7 +392,7 @@ public class EditCommand implements CommandI * @param edit * @param views */ - protected void performEdit(Edit edit, AlignmentI[] views) + protected static void performEdit(Edit edit, AlignmentI[] views) { switch (edit.command) { @@ -316,13 +469,13 @@ public class EditCommand implements CommandI * * @param command */ - final private void insertGap(Edit command) + final private static void insertGap(Edit command) { for (int s = 0; s < command.seqs.length; s++) { - command.seqs[s].insertCharAt(command.position, command.number, - command.gapChar); + command.seqs[s].insertCharAt(command.position, + command.number, command.gapChar); // System.out.println("pos: "+command.position+" number: "+command.number); } @@ -348,7 +501,7 @@ public class EditCommand implements CommandI * * @param command */ - final private void deleteGap(Edit command) + final static private void deleteGap(Edit command) { for (int s = 0; s < command.seqs.length; s++) { @@ -366,7 +519,7 @@ public class EditCommand implements CommandI * @param command * @param views */ - void cut(Edit command, AlignmentI[] views) + static void cut(Edit command, AlignmentI[] views) { boolean seqDeleted = false; command.string = new char[command.seqs.length][]; @@ -430,7 +583,7 @@ public class EditCommand implements CommandI * @param command * @param views */ - void paste(Edit command, AlignmentI[] views) + static void paste(Edit command, AlignmentI[] views) { StringBuffer tmp; boolean newDSNeeded; @@ -446,7 +599,7 @@ public class EditCommand implements CommandI if (command.seqs[i].getLength() < 1) { // ie this sequence was deleted, we need to - // read it to the alignment + // readd it to the alignment if (command.alIndex[i] < command.al.getHeight()) { List sequences; @@ -548,7 +701,7 @@ public class EditCommand implements CommandI command.string = null; } - void replace(Edit command) + static void replace(Edit command) { StringBuffer tmp; String oldstring; @@ -625,7 +778,7 @@ public class EditCommand implements CommandI } } - final void adjustAnnotations(Edit command, boolean insert, + final static void adjustAnnotations(Edit command, boolean insert, boolean modifyVisibility, AlignmentI[] views) { AlignmentAnnotation[] annotations = null; @@ -949,7 +1102,7 @@ public class EditCommand implements CommandI } } - final void adjustFeatures(Edit command, int index, int i, int j, + final static void adjustFeatures(Edit command, int index, int i, int j, boolean insert) { SequenceI seq = command.seqs[index]; @@ -1027,7 +1180,112 @@ public class EditCommand implements CommandI } - class Edit + /** + * Returns the list of edit commands wrapped by this object. + * + * @return + */ + public List getEdits() + { + return this.edits; + } + + /** + * Returns a map whose keys are the dataset sequences, and values their + * aligned sequences before the command edit list was applied. The aligned + * sequences are copies, which may be updated without affecting the originals. + * + * The command holds references to the aligned sequences (after editing). If + * the command is an 'undo',then the prior state is simply the aligned state. + * Otherwise, we have to derive the prior state by working backwards through + * the edit list to infer the aligned sequences before editing. + * + * Note: an alternative solution would be to cache the 'before' state of each + * edit, but this would be expensive in space in the common case that the + * original is never needed (edits are not mirrored). + * + * @return + * @throws IllegalStateException + * on detecting an edit command of a type that can't be unwound + */ + public Map priorState(boolean forUndo) + { + Map result = new HashMap(); + if (getEdits() == null) + { + return result; + } + if (forUndo) + { + for (Edit e : getEdits()) + { + for (SequenceI seq : e.getSequences()) + { + SequenceI ds = seq.getDatasetSequence(); + SequenceI preEdit = result.get(ds); + if (preEdit == null) + { + preEdit = new Sequence("", seq.getSequenceAsString()); + preEdit.setDatasetSequence(ds); + result.put(ds, preEdit); + } + } + } + return result; + } + + /* + * Work backwards through the edit list, deriving the sequences before each + * was applied. The final result is the sequence set before any edits. + */ + Iterator edits = new ReverseListIterator(getEdits()); + while (edits.hasNext()) + { + Edit oldEdit = edits.next(); + Action action = oldEdit.getAction(); + int position = oldEdit.getPosition(); + int number = oldEdit.getNumber(); + final char gap = oldEdit.getGapCharacter(); + for (SequenceI seq : oldEdit.getSequences()) + { + SequenceI ds = seq.getDatasetSequence(); + SequenceI preEdit = result.get(ds); + if (preEdit == null) + { + preEdit = new Sequence("", seq.getSequenceAsString()); + preEdit.setDatasetSequence(ds); + result.put(ds, preEdit); + } + /* + * 'Undo' this edit action on the sequence (updating the value in the + * map). + */ + if (ds != null) + { + if (action == Action.DELETE_GAP) + { + preEdit.setSequence(new String(StringUtils.insertCharAt( + preEdit.getSequence(), position, + number, gap))); + } + else if (action == Action.INSERT_GAP) + { + preEdit.setSequence(new String(StringUtils.deleteChars( + preEdit.getSequence(), position, position + number))); + } + else + { + System.err.println("Can't undo edit action " + action); + // throw new IllegalStateException("Can't undo edit action " + + // action); + } + } + } + } + return result; + } + + public class Edit { public SequenceI[] oldds; @@ -1053,7 +1311,7 @@ public class EditCommand implements CommandI char gapChar; - Edit(Action command, SequenceI[] seqs, int position, int number, + public Edit(Action command, SequenceI[] seqs, int position, int number, char gapChar) { this.command = command; @@ -1099,5 +1357,49 @@ public class EditCommand implements CommandI fullAlignmentHeight = (al.getHeight() == seqs.length); } + + public SequenceI[] getSequences() + { + return seqs; + } + + public int getPosition() + { + return position; + } + + public Action getAction() + { + return command; + } + + public int getNumber() + { + return number; + } + + public char getGapCharacter() + { + return gapChar; + } + } + + /** + * Returns an iterator over the list of edit commands which traverses the list + * either forwards or backwards. + * + * @param forwards + * @return + */ + public Iterator getEditIterator(boolean forwards) + { + if (forwards) + { + return getEdits().iterator(); + } + else + { + return new ReverseListIterator(getEdits()); + } } } diff --git a/src/jalview/commands/OrderCommand.java b/src/jalview/commands/OrderCommand.java index b610a54..f4010a1 100644 --- a/src/jalview/commands/OrderCommand.java +++ b/src/jalview/commands/OrderCommand.java @@ -20,19 +20,46 @@ */ package jalview.commands; -import jalview.analysis.*; -import jalview.datamodel.*; +import jalview.analysis.AlignmentSorter; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +/** + * An undoable command to reorder the sequences in an alignment. + * + * @author gmcarstairs + * + */ public class OrderCommand implements CommandI { String description; + /* + * The sequence order before sorting (target order for an undo) + */ SequenceI[] seqs; + /* + * The sequence order specified by this command + */ SequenceI[] seqs2; + /* + * The alignment the command acts on + */ AlignmentI al; + /** + * Constructor given the 'undo' sequence order, and the (already) sorted + * alignment. + * + * @param description + * a text label for the 'undo' menu option + * @param seqs + * the sequence order for undo + * @param al + * the alignment as ordered by this command + */ public OrderCommand(String description, SequenceI[] seqs, AlignmentI al) { this.description = description; @@ -61,4 +88,15 @@ public class OrderCommand implements CommandI { AlignmentSorter.setOrder(al, seqs); } + + /** + * Returns the sequence order used to sort, or before sorting if undo=true. + * + * @param undo + * @return + */ + public SequenceI[] getSequenceOrder(boolean undo) + { + return undo ? seqs : seqs2; + } } diff --git a/src/jalview/datamodel/AlignedCodon.java b/src/jalview/datamodel/AlignedCodon.java new file mode 100644 index 0000000..0daa3fb --- /dev/null +++ b/src/jalview/datamodel/AlignedCodon.java @@ -0,0 +1,86 @@ +package jalview.datamodel; + +/** + * Holds the aligned column positions (base 0) for one codon in a nucleotide + * sequence, and (optionally) its peptide translation. The object is immutable + * once created. + * + * Example: in "G-AT-C-GA" the aligned codons are (0, 2, 3) and (5, 7, 8). + * + * @author gmcarstairs + * + */ +public final class AlignedCodon +{ + public final int pos1; + + public final int pos2; + + public final int pos3; + + public final String product; + + public AlignedCodon(int i, int j, int k) + { + this(i, j, k, null); + } + + public AlignedCodon(int i, int j, int k, String prod) + { + pos1 = i; + pos2 = j; + pos3 = k; + product = prod; + } + + /** + * Returns the column position for the given base (1, 2, 3). + * + * @param base + * @return + * @throws IllegalArgumentException + * if an argument value other than 1, 2 or 3 is supplied + */ + public int getBaseColumn(int base) + { + if (base < 1 || base > 3) + { + throw new IllegalArgumentException(Integer.toString(base)); + } + return base == 1 ? pos1 : (base == 2 ? pos2 : pos3); + } + + /** + * Two aligned codons are equal if all their base positions are the same. We + * don't care about the protein product. This test is required for correct + * alignment of translated gapped dna alignments (the same codon positions in + * different sequences occupy the same column in the translated alignment). + */ + @Override + public boolean equals(Object o) + { + /* + * Equality with null value required for consistency with + * Dna.compareCodonPos + */ + if (o == null) + { + return true; + } + if (!(o instanceof AlignedCodon)) + { + return false; + } + AlignedCodon ac = (AlignedCodon) o; + return (pos1 == ac.pos1 && pos2 == ac.pos2 && pos3 == ac.pos3); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("[").append(pos1).append(", ").append(pos2).append(", ") + .append(pos3).append("]"); + return sb.toString(); + } +} diff --git a/src/jalview/datamodel/AlignedCodonFrame.java b/src/jalview/datamodel/AlignedCodonFrame.java index 3fc08d1..cbddf1c 100644 --- a/src/jalview/datamodel/AlignedCodonFrame.java +++ b/src/jalview/datamodel/AlignedCodonFrame.java @@ -20,134 +20,36 @@ */ package jalview.datamodel; -import java.util.Enumeration; -import java.util.Vector; - import jalview.util.MapList; /** * Stores mapping between the columns of a protein alignment and a DNA alignment * and a list of individual codon to amino acid mappings between sequences. */ - public class AlignedCodonFrame { - /** - * array of nucleotide positions for aligned codons at column of aligned - * proteins. - */ - public int[][] codons = null; - - /** - * width of protein sequence alignement implicit assertion that codons.length - * >= aaWidth - */ - public int aaWidth = 0; - - /** - * initialise codon frame with a nominal alignment width - * - * @param aWidth - */ - public AlignedCodonFrame(int aWidth) - { - if (aWidth <= 0) - { - codons = null; - return; - } - codons = new int[aWidth][]; - for (int res = 0; res < aWidth; res++) - codons[res] = null; - } - - /** - * ensure that codons array is at least as wide as aslen residues - * - * @param aslen - * @return (possibly newly expanded) codon array - */ - public int[][] checkCodonFrameWidth(int aslen) - { - if (codons.length <= aslen + 1) - { - // probably never have to do this ? - int[][] c = new int[codons.length + 10][]; - for (int i = 0; i < codons.length; i++) - { - c[i] = codons[i]; - codons[i] = null; - } - codons = c; - } - return codons; - } - /** - * @return width of aligned translated amino acid residues + /* + * tied array of na Sequence objects. */ - public int getaaWidth() - { - return aaWidth; - } + private SequenceI[] dnaSeqs = null; - /** - * TODO: not an ideal solution - we reference the aligned amino acid sequences - * in order to make insertions on them Better would be dnaAlignment and - * aaAlignment reference.... + /* + * tied array of Mappings to protein sequence Objects and SequenceI[] + * aaSeqs=null; MapLists where each maps from the corresponding dnaSeqs + * element to corresponding aaSeqs element */ - Vector a_aaSeqs = new Vector(); + private Mapping[] dnaToProt = null; /** - * increase aaWidth by one and insert a new aligned codon position space at - * aspos. - * - * @param aspos + * Constructor */ - public void insertAAGap(int aspos, char gapCharacter) - { - // this aa appears before the aligned codons at aspos - so shift them in - // each pair of mapped sequences - aaWidth++; - if (a_aaSeqs != null) - { - // we actually have to modify the aligned sequences here, so use the - // a_aaSeqs vector - Enumeration sq = a_aaSeqs.elements(); - while (sq.hasMoreElements()) - { - ((SequenceI) sq.nextElement()).insertCharAt(aspos, gapCharacter); - } - } - checkCodonFrameWidth(aspos); - if (aspos < aaWidth) - { - aaWidth++; - System.arraycopy(codons, aspos, codons, aspos + 1, codons.length - - aspos - 1); - codons[aspos] = null; // clear so new codon position can be marked. - } - } - - public void setAaWidth(int aapos) + public AlignedCodonFrame() { - aaWidth = aapos; } /** - * tied array of na Sequence objects. - */ - SequenceI[] dnaSeqs = null; - - /** - * tied array of Mappings to protein sequence Objects and SequenceI[] - * aaSeqs=null; MapLists where eac maps from the corresponding dnaSeqs element - * to corresponding aaSeqs element - */ - Mapping[] dnaToProt = null; - - /** - * add a mapping between the dataset sequences for the associated dna and + * Adds a mapping between the dataset sequences for the associated dna and * protein sequence objects * * @param dnaseq @@ -179,7 +81,6 @@ public class AlignedCodonFrame // aaseq.transferAnnotation(dnaseq, new Mapping(map.getInverse())); mp.to = (aaseq.getDatasetSequence() == null) ? aaseq : aaseq .getDatasetSequence(); - a_aaSeqs.addElement(aaseq); dnaToProt[nlen] = mp; } @@ -191,7 +92,9 @@ public class AlignedCodonFrame public SequenceI[] getAaSeqs() { if (dnaToProt == null) + { return null; + } SequenceI[] sqs = new SequenceI[dnaToProt.length]; for (int sz = 0; sz < dnaToProt.length; sz++) { @@ -203,7 +106,9 @@ public class AlignedCodonFrame public MapList[] getdnaToProt() { if (dnaToProt == null) + { return null; + } MapList[] sqs = new MapList[dnaToProt.length]; for (int sz = 0; sz < dnaToProt.length; sz++) { @@ -218,9 +123,37 @@ public class AlignedCodonFrame } /** + * Returns the first mapping found which is to or from the given sequence, or + * null. + * + * @param seq + * @return + */ + public Mapping getMappingForSequence(SequenceI seq) + { + if (dnaSeqs == null) + { + return null; + } + SequenceI seqDs = seq.getDatasetSequence(); + seqDs = seqDs != null ? seqDs : seq; + + for (int ds = 0; ds < dnaSeqs.length; ds++) + { + if (dnaSeqs[ds] == seqDs || dnaToProt[ds].to == seqDs) + { + return dnaToProt[ds]; + } + } + return null; + } + + /** + * Return the corresponding aligned or dataset aa sequence for given dna + * sequence, null if not found. * * @param sequenceRef - * @return null or corresponding aaSeq entry for dnaSeq entry + * @return */ public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef) { @@ -232,7 +165,9 @@ public class AlignedCodonFrame for (int ds = 0; ds < dnaSeqs.length; ds++) { if (dnaSeqs[ds] == dnaSeqRef || dnaSeqs[ds] == dnads) + { return dnaToProt[ds].to; + } } return null; } @@ -252,7 +187,9 @@ public class AlignedCodonFrame for (int as = 0; as < dnaToProt.length; as++) { if (dnaToProt[as].to == aaSeqRef || dnaToProt[as].to == aads) + { return dnaSeqs[as]; + } } return null; } @@ -319,4 +256,124 @@ public class AlignedCodonFrame } } } + + /** + * Returns the DNA codon positions (base 1) for the given position (base 1) in + * a mapped protein sequence, or null if no mapping is found. + * + * Intended for use in aligning cDNA to match aligned protein. Only the first + * mapping found is returned, so not suitable for use if multiple protein + * sequences are mapped to the same cDNA (but aligning cDNA as protein is + * ill-defined for this case anyway). + * + * @param seq + * the DNA dataset sequence + * @param aaPos + * residue position (base 1) in a protein sequence + * @return + */ + public int[] getDnaPosition(SequenceI seq, int aaPos) + { + /* + * Adapted from markMappedRegion(). + */ + MapList ml = null; + for (int i = 0; i < dnaToProt.length; i++) + { + if (dnaSeqs[i] == seq) + { + ml = getdnaToProt()[i]; + break; + } + } + return ml == null ? null : ml.locateInFrom(aaPos, aaPos); + } + + /** + * Convenience method to return the first aligned sequence in the given + * alignment whose dataset has a mapping with the given dataset sequence. + * + * @param seq + * + * @param al + * @return + */ + public SequenceI findAlignedSequence(SequenceI seq, AlignmentI al) + { + /* + * Search mapped protein ('to') sequences first. + */ + if (this.dnaToProt != null) + { + for (int i = 0; i < dnaToProt.length; i++) + { + if (this.dnaSeqs[i] == seq) + { + for (SequenceI sourceAligned : al.getSequences()) + { + if (this.dnaToProt[i].to == sourceAligned.getDatasetSequence()) + { + return sourceAligned; + } + } + } + } + } + + /* + * Then try mapped dna sequences. + */ + if (this.dnaToProt != null) + { + for (int i = 0; i < dnaToProt.length; i++) + { + if (this.dnaToProt[i].to == seq) + { + for (SequenceI sourceAligned : al.getSequences()) + { + if (this.dnaSeqs[i] == sourceAligned.getDatasetSequence()) + { + return sourceAligned; + } + } + } + } + } + + return null; + } + + /** + * Returns the region in the 'mappedFrom' sequence's dataset that is mapped to + * position 'pos' (base 1) in the 'mappedTo' sequence's dataset. The region is + * a set of start/end position pairs. + * + * @param mappedFrom + * @param mappedTo + * @param pos + * @return + */ + public int[] getMappedRegion(SequenceI mappedFrom, SequenceI mappedTo, + int pos) + { + SequenceI targetDs = mappedFrom.getDatasetSequence() == null ? mappedFrom + : mappedFrom.getDatasetSequence(); + SequenceI sourceDs = mappedTo.getDatasetSequence() == null ? mappedTo + : mappedTo.getDatasetSequence(); + if (targetDs == null || sourceDs == null || dnaToProt == null) + { + return null; + } + for (int mi = 0; mi < dnaToProt.length; mi++) + { + if (dnaSeqs[mi] == targetDs && dnaToProt[mi].to == sourceDs) + { + int[] codon = dnaToProt[mi].map.locateInFrom(pos, pos); + if (codon != null) { + return codon; + } + } + } + return null; + } } diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index 01d3d8d..19819a6 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -20,13 +20,18 @@ */ package jalview.datamodel; +import jalview.analysis.AlignmentUtils; +import jalview.io.FastaFile; import jalview.util.MessageManager; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashSet; import java.util.Hashtable; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Vector; /** @@ -62,6 +67,8 @@ public class Alignment implements AlignmentI public Hashtable alignmentProperties; + private Set codonFrameList = new LinkedHashSet(); + private void initAlignment(SequenceI[] seqs) { int i = 0; @@ -86,6 +93,27 @@ public class Alignment implements AlignmentI } /** + * Make a 'copy' alignment - sequences have new copies of features and + * annotations, but share the original dataset sequences. + */ + public Alignment(AlignmentI al) + { + SequenceI[] seqs = al.getSequencesArray(); + for (int i = 0; i < seqs.length; i++) + { + seqs[i] = new Sequence(seqs[i]); + } + + /* + * Share the same dataset sequence mappings (if any). TODO: find a better + * place for these to live (alignment dataset?). + */ + this.codonFrameList = ((Alignment) al).codonFrameList; + + initAlignment(seqs); + } + + /** * Make an alignment from an array of Sequences. * * @param sequences @@ -123,11 +151,6 @@ public class Alignment implements AlignmentI // this(compactAlignment.refCigars); } - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ @Override public List getSequences() { @@ -157,6 +180,17 @@ public class Alignment implements AlignmentI } /** + * Returns a map of lists of sequences keyed by sequence name. + * + * @return + */ + @Override + public Map> getSequencesByName() + { + return AlignmentUtils.getSequencesByName(this); + } + + /** * DOCUMENT ME! * * @param i @@ -226,10 +260,9 @@ public class Alignment implements AlignmentI @Override public void setSequenceAt(int i, SequenceI snew) { - SequenceI oldseq = getSequenceAt(i); - deleteSequence(i); synchronized (sequences) { + deleteSequence(i); sequences.set(i, snew); } } @@ -298,8 +331,8 @@ public class Alignment implements AlignmentI synchronized (sequences) { sequences.remove(i); + hiddenSequences.adjustHeightSequenceDeleted(i); } - hiddenSequences.adjustHeightSequenceDeleted(i); } } @@ -343,14 +376,14 @@ public class Alignment implements AlignmentI for (int i = 0; i < gSize; i++) { SequenceGroup sg = groups.get(i); - if (sg == null || sg.getSequences(null) == null) + if (sg == null || sg.getSequences() == null) { this.deleteGroup(sg); gSize--; continue; } - if (sg.getSequences(null).contains(s)) + if (sg.getSequences().contains(s)) { temp.add(sg); } @@ -720,6 +753,28 @@ public class Alignment implements AlignmentI return true; } + /** + * Delete all annotations, including auto-calculated if the flag is set true. + * Returns true if at least one annotation was deleted, else false. + * + * @param includingAutoCalculated + * @return + */ + @Override + public boolean deleteAllAnnotations(boolean includingAutoCalculated) + { + boolean result = false; + for (AlignmentAnnotation alan : getAlignmentAnnotation()) + { + if (!alan.autoCalculated || includingAutoCalculated) + { + deleteAnnotation(alan); + result = true; + } + } + return result; + } + /* * (non-Javadoc) * @@ -1205,8 +1260,6 @@ public class Alignment implements AlignmentI return alignmentProperties; } - AlignedCodonFrame[] codonFrameList = null; - /* * (non-Javadoc) * @@ -1217,31 +1270,10 @@ public class Alignment implements AlignmentI @Override public void addCodonFrame(AlignedCodonFrame codons) { - if (codons == null) + if (codons != null) { - return; + codonFrameList.add(codons); } - if (codonFrameList == null) - { - codonFrameList = new AlignedCodonFrame[] - { codons }; - return; - } - AlignedCodonFrame[] t = new AlignedCodonFrame[codonFrameList.length + 1]; - System.arraycopy(codonFrameList, 0, t, 0, codonFrameList.length); - t[codonFrameList.length] = codons; - codonFrameList = t; - } - - /* - * (non-Javadoc) - * - * @see jalview.datamodel.AlignmentI#getCodonFrame(int) - */ - @Override - public AlignedCodonFrame getCodonFrame(int index) - { - return codonFrameList[index]; } /* @@ -1251,36 +1283,42 @@ public class Alignment implements AlignmentI * jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI) */ @Override - public AlignedCodonFrame[] getCodonFrame(SequenceI seq) + public List getCodonFrame(SequenceI seq) { - if (seq == null || codonFrameList == null) + if (seq == null) { return null; } - Vector cframes = new Vector(); - for (int f = 0; f < codonFrameList.length; f++) + List cframes = new ArrayList(); + for (AlignedCodonFrame acf : codonFrameList) { - if (codonFrameList[f].involvesSequence(seq)) + if (acf.involvesSequence(seq)) { - cframes.addElement(codonFrameList[f]); + cframes.add(acf); } } - if (cframes.size() == 0) - { - return null; - } - AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()]; - cframes.copyInto(cfr); - return cfr; + return cframes; } - /* - * (non-Javadoc) + /** + * Sets the codon frame mappings (replacing any existing mappings). + * + * @see jalview.datamodel.AlignmentI#setCodonFrames() + */ + @Override + public void setCodonFrames(Set acfs) + { + this.codonFrameList = acfs; + } + + /** + * Returns the set of codon frame mappings. Any changes to the returned set + * will affect the alignment. * * @see jalview.datamodel.AlignmentI#getCodonFrames() */ @Override - public AlignedCodonFrame[] getCodonFrames() + public Set getCodonFrames() { return codonFrameList; } @@ -1298,26 +1336,7 @@ public class Alignment implements AlignmentI { return false; } - boolean removed = false; - int i = 0, iSize = codonFrameList.length; - while (i < iSize) - { - if (codonFrameList[i] == codons) - { - removed = true; - if (i + 1 < iSize) - { - System.arraycopy(codonFrameList, i + 1, codonFrameList, i, iSize - - i - 1); - } - iSize--; - } - else - { - i++; - } - } - return removed; + return codonFrameList.remove(codons); } @Override @@ -1362,11 +1381,9 @@ public class Alignment implements AlignmentI { addAnnotation(alan[a]); } - AlignedCodonFrame[] acod = toappend.getCodonFrames(); - for (int a = 0; acod != null && a < acod.length; a++) - { - this.addCodonFrame(acod[a]); - } + + this.codonFrameList.addAll(toappend.getCodonFrames()); + List sg = toappend.getGroups(); if (sg != null) { @@ -1627,4 +1644,116 @@ public class Alignment implements AlignmentI { return dataset; } + + /** + * Align this alignment like the given (mapped) one. + */ + @Override + public int alignAs(AlignmentI al) + { + /* + * Currently retains unmapped gaps (in introns), regaps mapped regions + * (exons) + */ + return alignAs(al, false, true); + } + + /** + * Align this alignment 'the same as' the given one. Mapped sequences only are + * realigned. If both of the same type (nucleotide/protein) then align both + * identically. If this is nucleotide and the other is protein, make 3 gaps + * for each gap in the protein sequences. If this is protein and the other is + * nucleotide, insert a gap for each 3 gaps (or part thereof) between + * nucleotide bases. Does nothing if alignment of protein from cDNA is + * requested (not yet implemented). + * + * Parameters control whether gaps in exon (mapped) and intron (unmapped) + * regions are preserved. Gaps that connect introns to exons are treated + * conservatively, i.e. only preserved if both intron and exon gaps are + * preserved. + * + * @param al + * @param preserveMappedGaps + * if true, gaps within and between mapped codons are preserved + * @param preserveUnmappedGaps + * if true, gaps within and between unmapped codons are preserved + */ +// @Override + public int alignAs(AlignmentI al, boolean preserveMappedGaps, + boolean preserveUnmappedGaps) + { + // TODO should this method signature be the one in the interface? + int count = 0; + boolean thisIsNucleotide = this.isNucleotide(); + boolean thatIsProtein = !al.isNucleotide(); + if (!thatIsProtein && !thisIsNucleotide) + { + return AlignmentUtils.alignProteinAsDna(this, al); + } + + char thisGapChar = this.getGapCharacter(); + String gap = thisIsNucleotide && thatIsProtein ? String + .valueOf(new char[] + { thisGapChar, thisGapChar, thisGapChar }) : String + .valueOf(thisGapChar); + + /* + * Get mappings from 'that' alignment's sequences to this. + */ + for (SequenceI alignTo : getSequences()) + { + count += AlignmentUtils.alignSequenceAs(alignTo, al, gap, preserveMappedGaps, + preserveUnmappedGaps) ? 1 : 0; + } + return count; + } + + /** + * Returns the alignment in Fasta format. Behaviour of this method is not + * guaranteed between versions. + */ + @Override + public String toString() + { + return new FastaFile().print(getSequencesArray()); + } + + /** + * Returns the set of distinct sequence names. No ordering is guaranteed. + */ + @Override + public Set getSequenceNames() + { + Set names = new HashSet(); + for (SequenceI seq : getSequences()) + { + names.add(seq.getName()); + } + return names; + } + + /** + * Returns a (possibly empty) alignment whose sequences are aligned to match + * the current alignment, as mapped by the given codon mappings. + * + * @param codonFrames + * @return + */ + @Override + public AlignmentI getAlignedComplement(Set codonFrames) + { + // Note: passing codonFrames as a parameter rather than using + // this.codonFrameList as more flexible. Specifically, mappings are held + // on the protein alignment but we might want to act on dna. + + // TODO we want the gap character of the mapped alignment, not this one! + List alignedSeqs = AlignmentUtils.getAlignedTranslation( + getSequences(), getGapCharacter(), codonFrames); + final SequenceI[] seqsAsArray = alignedSeqs + .toArray(new SequenceI[alignedSeqs.size()]); + AlignmentI al = new Alignment(seqsAsArray); + al.padGaps(); + al.setDataset(null); + return al; + } } diff --git a/src/jalview/datamodel/AlignmentAnnotation.java b/src/jalview/datamodel/AlignmentAnnotation.java index e137225..0d99155 100755 --- a/src/jalview/datamodel/AlignmentAnnotation.java +++ b/src/jalview/datamodel/AlignmentAnnotation.java @@ -27,9 +27,8 @@ import jalview.analysis.WUSSParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Enumeration; import java.util.HashMap; -import java.util.Hashtable; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; @@ -155,7 +154,7 @@ public class AlignmentAnnotation /** * map of positions in the associated annotation */ - public java.util.Hashtable sequenceMapping; + private Map sequenceMapping; /** DOCUMENT ME!! */ public float graphMin; @@ -499,6 +498,7 @@ public class AlignmentAnnotation : annotations[index + offset].secondaryStructure); } + @Override public String toString() { char[] string = new char[max - offset]; @@ -710,12 +710,13 @@ public class AlignmentAnnotation if (annotation.sequenceMapping != null) { Integer p = null; - sequenceMapping = new Hashtable(); - Enumeration pos = annotation.sequenceMapping.keys(); - while (pos.hasMoreElements()) + sequenceMapping = new HashMap(); + Iterator pos = annotation.sequenceMapping.keySet() + .iterator(); + while (pos.hasNext()) { // could optimise this! - p = (Integer) pos.nextElement(); + p = pos.next(); Annotation a = annotation.sequenceMapping.get(p); if (a == null) { @@ -789,11 +790,11 @@ public class AlignmentAnnotation int epos = sequenceRef.findPosition(endRes); if (sequenceMapping != null) { - Hashtable newmapping = new Hashtable(); - Enumeration e = sequenceMapping.keys(); - while (e.hasMoreElements()) + Map newmapping = new HashMap(); + Iterator e = sequenceMapping.keySet().iterator(); + while (e.hasNext()) { - Integer pos = (Integer) e.nextElement(); + Integer pos = e.next(); if (pos.intValue() >= spos && pos.intValue() <= epos) { newmapping.put(pos, sequenceMapping.get(pos)); @@ -836,9 +837,10 @@ public class AlignmentAnnotation * * @return DOCUMENT ME! */ + @Override public String toString() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(256); for (int i = 0; i < annotations.length; i++) { @@ -911,7 +913,7 @@ public class AlignmentAnnotation { return; } - sequenceMapping = new java.util.Hashtable(); + sequenceMapping = new HashMap(); int seqPos; @@ -1223,7 +1225,7 @@ public class AlignmentAnnotation .getTo() == sq.getDatasetSequence()) : false; // TODO build a better annotation element map and get rid of annotations[] - Hashtable mapForsq = new Hashtable(); + Map mapForsq = new HashMap(); if (sequenceMapping != null) { if (sp2sq != null) @@ -1275,7 +1277,8 @@ public class AlignmentAnnotation { if (mapping != null) { - Hashtable old = sequenceMapping, remap = new Hashtable(); + Map old = sequenceMapping; + Map remap = new HashMap(); int index = -1; for (int mp[] : mapping) { diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java index c7e30a4..eb396ad 100755 --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@ -5,16 +5,16 @@ * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License + * modify it under the terms of the GNU General License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. + * PURPOSE. See the GNU General License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU General License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ @@ -23,6 +23,7 @@ package jalview.datamodel; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Set; /** * Data structure to hold and manipulate a multiple sequence alignment @@ -34,15 +35,16 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Number of sequences in alignment */ - public int getHeight(); + int getHeight(); /** + * * Calculates the maximum width of the alignment, including gaps. * * @return Greatest sequence length within alignment. */ @Override - public int getWidth(); + int getWidth(); /** * Calculates if this set of sequences (visible and invisible) are all the @@ -50,7 +52,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return true if all sequences in alignment are the same length */ - public boolean isAligned(); + boolean isAligned(); /** * Calculates if this set of sequences is all the same length @@ -59,7 +61,7 @@ public interface AlignmentI extends AnnotatedCollectionI * optionally exclude hidden sequences from test * @return true if all (or just visible) sequences are the same length */ - public boolean isAligned(boolean includeHidden); + boolean isAligned(boolean includeHidden); /** * Gets sequences as a Synchronized collection @@ -67,14 +69,14 @@ public interface AlignmentI extends AnnotatedCollectionI * @return All sequences in alignment. */ @Override - public List getSequences(); + List getSequences(); /** * Gets sequences as a SequenceI[] * * @return All sequences in alignment. */ - public SequenceI[] getSequencesArray(); + SequenceI[] getSequencesArray(); /** * Find a specific sequence in this alignment. @@ -84,7 +86,14 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return SequenceI at given index. */ - public SequenceI getSequenceAt(int i); + SequenceI getSequenceAt(int i); + + /** + * Returns a map of lists of sequences keyed by sequence name. + * + * @return + */ + Map> getSequencesByName(); /** * Add a new sequence to this alignment. @@ -92,7 +101,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param seq * New sequence will be added at end of alignment. */ - public void addSequence(SequenceI seq); + void addSequence(SequenceI seq); /** * Used to set a particular index of the alignment with the given sequence. @@ -102,7 +111,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param seq * New sequence to be inserted. */ - public void setSequenceAt(int i, SequenceI seq); + void setSequenceAt(int i, SequenceI seq); /** * Deletes a sequence from the alignment @@ -110,7 +119,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param s * Sequence to be deleted. */ - public void deleteSequence(SequenceI s); + void deleteSequence(SequenceI s); /** * Deletes a sequence from the alignment. @@ -118,7 +127,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param i * Index of sequence to be deleted. */ - public void deleteSequence(int i); + void deleteSequence(int i); /** * Finds sequence in alignment using sequence name as query. @@ -128,9 +137,9 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Sequence matching query, if found. If not found returns null. */ - public SequenceI findName(String name); + SequenceI findName(String name); - public SequenceI[] findSequenceMatch(String name); + SequenceI[] findSequenceMatch(String name); /** * Finds index of a given sequence in the alignment. @@ -140,7 +149,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Index of sequence within the alignment or -1 if not found */ - public int findIndex(SequenceI s); + int findIndex(SequenceI s); /** * Finds group that given sequence is part of. @@ -151,7 +160,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return First group found for sequence. WARNING : Sequences may be members * of several groups. This method is incomplete. */ - public SequenceGroup findGroup(SequenceI s); + SequenceGroup findGroup(SequenceI s); /** * Finds all groups that a given sequence is part of. @@ -161,7 +170,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return All groups containing given sequence. */ - public SequenceGroup[] findAllGroups(SequenceI s); + SequenceGroup[] findAllGroups(SequenceI s); /** * Adds a new SequenceGroup to this alignment. @@ -169,7 +178,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param sg * New group to be added. */ - public void addGroup(SequenceGroup sg); + void addGroup(SequenceGroup sg); /** * Deletes a specific SequenceGroup @@ -177,19 +186,19 @@ public interface AlignmentI extends AnnotatedCollectionI * @param g * Group will be deleted from alignment. */ - public void deleteGroup(SequenceGroup g); + void deleteGroup(SequenceGroup g); /** * Get all the groups associated with this alignment. * * @return All groups as a list. */ - public List getGroups(); + List getGroups(); /** * Deletes all groups from this alignment. */ - public void deleteAllGroups(); + void deleteAllGroups(); /** * Adds a new AlignmentAnnotation to this alignment @@ -197,7 +206,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @note Care should be taken to ensure that annotation is at least as wide as * the longest sequence in the alignment for rendering purposes. */ - public void addAnnotation(AlignmentAnnotation aa); + void addAnnotation(AlignmentAnnotation aa); /** * moves annotation to a specified index in alignment annotation display stack @@ -207,7 +216,16 @@ public interface AlignmentI extends AnnotatedCollectionI * @param index * the destination position */ - public void setAnnotationIndex(AlignmentAnnotation aa, int index); + void setAnnotationIndex(AlignmentAnnotation aa, int index); + + /** + * Delete all annotations, including auto-calculated if the flag is set true. + * Returns true if at least one annotation was deleted, else false. + * + * @param includingAutoCalculated + * @return + */ + boolean deleteAllAnnotations(boolean includingAutoCalculated); /** * Deletes a specific AlignmentAnnotation from the alignment, and removes its @@ -219,7 +237,7 @@ public interface AlignmentI extends AnnotatedCollectionI * the annotation to delete * @return true if annotation was deleted from this alignment. */ - public boolean deleteAnnotation(AlignmentAnnotation aa); + boolean deleteAnnotation(AlignmentAnnotation aa); /** * Deletes a specific AlignmentAnnotation from the alignment, and optionally @@ -235,7 +253,7 @@ public interface AlignmentI extends AnnotatedCollectionI * into the alignment * @return true if annotation was deleted from this alignment. */ - public boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook); + boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook); /** * Get the annotation associated with this alignment (this can be null if no @@ -244,7 +262,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return array of AlignmentAnnotation objects */ @Override - public AlignmentAnnotation[] getAlignmentAnnotation(); + AlignmentAnnotation[] getAlignmentAnnotation(); /** * Change the gap character used in this alignment to 'gc' @@ -252,34 +270,34 @@ public interface AlignmentI extends AnnotatedCollectionI * @param gc * the new gap character. */ - public void setGapCharacter(char gc); + void setGapCharacter(char gc); /** * Get the gap character used in this alignment * * @return gap character */ - public char getGapCharacter(); + char getGapCharacter(); /** * Test for all nucleotide alignment * * @return true if alignment is nucleotide sequence */ - public boolean isNucleotide(); + boolean isNucleotide(); /** * Test if alignment contains RNA structure * * @return true if RNA structure AligmnentAnnotation was added to alignment */ - public boolean hasRNAStructure(); + boolean hasRNAStructure(); /** * Set alignment to be a nucleotide sequence * */ - public void setNucleotide(boolean b); + void setNucleotide(boolean b); /** * Get the associated dataset for the alignment. @@ -287,7 +305,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return Alignment containing dataset sequences or null of this is a * dataset. */ - public Alignment getDataset(); + Alignment getDataset(); /** * Set the associated dataset for the alignment, or create one. @@ -295,23 +313,23 @@ public interface AlignmentI extends AnnotatedCollectionI * @param dataset * The dataset alignment or null to construct one. */ - public void setDataset(Alignment dataset); + void setDataset(Alignment dataset); /** * pads sequences with gaps (to ensure the set looks like an alignment) * * @return boolean true if alignment was modified */ - public boolean padGaps(); + boolean padGaps(); - public HiddenSequences getHiddenSequences(); + HiddenSequences getHiddenSequences(); /** * Compact representation of alignment * * @return CigarArray */ - public CigarArray getCompactAlignment(); + CigarArray getCompactAlignment(); /** * Set an arbitrary key value pair for an alignment. Note: both key and value @@ -320,7 +338,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param key * @param value */ - public void setProperty(Object key, Object value); + void setProperty(Object key, Object value); /** * Get a named property from the alignment. @@ -328,21 +346,21 @@ public interface AlignmentI extends AnnotatedCollectionI * @param key * @return value of property */ - public Object getProperty(Object key); + Object getProperty(Object key); /** * Get the property hashtable. * * @return hashtable of alignment properties (or null if none are defined) */ - public Hashtable getProperties(); + Hashtable getProperties(); /** * add a reference to a frame of aligned codons for this alignment * * @param codons */ - public void addCodonFrame(AlignedCodonFrame codons); + void addCodonFrame(AlignedCodonFrame codons); /** * remove a particular codon frame reference from this alignment @@ -350,27 +368,24 @@ public interface AlignmentI extends AnnotatedCollectionI * @param codons * @return true if codon frame was removed. */ - public boolean removeCodonFrame(AlignedCodonFrame codons); + boolean removeCodonFrame(AlignedCodonFrame codons); /** * get all codon frames associated with this alignment * * @return */ - public AlignedCodonFrame[] getCodonFrames(); + Set getCodonFrames(); /** - * get a particular codon frame - * - * @param index - * @return + * Set the codon frame mappings (replacing any existing set). */ - public AlignedCodonFrame getCodonFrame(int index); + void setCodonFrames(Set acfs); /** * get codon frames involving sequenceI */ - public AlignedCodonFrame[] getCodonFrame(SequenceI seq); + List getCodonFrame(SequenceI seq); /** * find sequence with given name in alignment @@ -382,7 +397,7 @@ public interface AlignmentI extends AnnotatedCollectionI * tried * @return matched sequence or null */ - public SequenceI findName(String token, boolean b); + SequenceI findName(String token, boolean b); /** * find next sequence with given name in alignment starting after a given @@ -398,7 +413,7 @@ public interface AlignmentI extends AnnotatedCollectionI * tried * @return matched sequence or null */ - public SequenceI findName(SequenceI startAfter, String token, boolean b); + SequenceI findName(SequenceI startAfter, String token, boolean b); /** * find first sequence in alignment which is involved in the given search @@ -407,7 +422,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param results * @return -1 or index of sequence in alignment */ - public int findIndex(SearchResults results); + int findIndex(SearchResults results); /** * append sequences and annotation from another alignment object to this one. @@ -420,7 +435,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param toappend * - the alignment to be appended. */ - public void append(AlignmentI toappend); + void append(AlignmentI toappend); /** * Justify the sequences to the left or right by deleting and inserting gaps @@ -430,7 +445,7 @@ public interface AlignmentI extends AnnotatedCollectionI * true if alignment padded to right, false to justify to left * @return true if alignment was changed TODO: return undo object */ - public boolean justify(boolean right); + boolean justify(boolean right); /** * add given annotation row at given position (0 is start, -1 is end) @@ -438,7 +453,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param consensus * @param i */ - public void addAnnotation(AlignmentAnnotation consensus, int i); + void addAnnotation(AlignmentAnnotation consensus, int i); /** * search for or create a specific annotation row on the alignment @@ -458,7 +473,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return existing annotation matching the given attributes */ - public AlignmentAnnotation findOrCreateAnnotation(String name, + AlignmentAnnotation findOrCreateAnnotation(String name, String calcId, boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef); @@ -472,7 +487,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param up * @param i */ - public void moveSelectedSequencesByOne(SequenceGroup sg, + void moveSelectedSequencesByOne(SequenceGroup sg, Map map, boolean up); /** @@ -481,5 +496,34 @@ public interface AlignmentI extends AnnotatedCollectionI * * @param alignmentAnnotation */ - public void validateAnnotation(AlignmentAnnotation alignmentAnnotation); + void validateAnnotation(AlignmentAnnotation alignmentAnnotation); + + /** + * Align this alignment the same as the given one. If both of the same type + * (nucleotide/protein) then align both identically. If this is nucleotide and + * the other is protein, make 3 gaps for each gap in the protein sequences. If + * this is protein and the other is nucleotide, insert a gap for each 3 gaps + * (or part thereof) between nucleotide bases. Returns the number of mapped + * sequences that were realigned . + * + * @param al + * @return + */ + int alignAs(AlignmentI al); + + /** + * Returns the set of distinct sequence names in the alignment. + * + * @return + */ + Set getSequenceNames(); + + /** + * Returns a (possibly empty) alignment whose sequences are aligned to match + * the current alignment, as mapped by the given codon mappings. + * + * @param codonFrames + * @return + */ + AlignmentI getAlignedComplement(Set codonFrames); } diff --git a/src/jalview/datamodel/AlignmentOrder.java b/src/jalview/datamodel/AlignmentOrder.java index c0f9ab4..92d5f6c 100755 --- a/src/jalview/datamodel/AlignmentOrder.java +++ b/src/jalview/datamodel/AlignmentOrder.java @@ -20,7 +20,9 @@ */ package jalview.datamodel; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class AlignmentOrder { @@ -51,7 +53,7 @@ public class AlignmentOrder private String Name; - private Vector Order = null; + private List Order = null; /** * Creates a new AlignmentOrder object. @@ -64,9 +66,8 @@ public class AlignmentOrder * AlignmentOrder * * @param anOrder - * Vector */ - public AlignmentOrder(Vector anOrder) + public AlignmentOrder(List anOrder) { Order = anOrder; } @@ -79,11 +80,11 @@ public class AlignmentOrder */ public AlignmentOrder(AlignmentI orderFrom) { - Order = new Vector(); + Order = new ArrayList(); - for (int i = 0, ns = orderFrom.getHeight(); i < ns; i++) + for (SequenceI seq : orderFrom.getSequences()) { - Order.addElement(orderFrom.getSequenceAt(i)); + Order.add(seq); } } @@ -95,12 +96,7 @@ public class AlignmentOrder */ public AlignmentOrder(SequenceI[] orderFrom) { - Order = new Vector(); - - for (int i = 0, ns = orderFrom.length; i < ns; i++) - { - Order.addElement(orderFrom[i]); - } + Order = new ArrayList(Arrays.asList(orderFrom)); } /** @@ -151,7 +147,7 @@ public class AlignmentOrder * @param Order * DOCUMENT ME! */ - public void setOrder(Vector Order) + public void setOrder(List Order) { this.Order = Order; } @@ -161,7 +157,7 @@ public class AlignmentOrder * * @return DOCUMENT ME! */ - public Vector getOrder() + public List getOrder() { return Order; } @@ -178,7 +174,7 @@ public class AlignmentOrder int found = Order.indexOf(oldref); if (found > -1) { - Order.setElementAt(newref, found); + Order.set(found, newref); } return found > -1; } @@ -189,9 +185,14 @@ public class AlignmentOrder * @param o * @return true if o orders the same sequenceI objects in the same way */ - public boolean equals(AlignmentOrder o) + @Override + public boolean equals(Object o) { - return equals(o, true); + if (o == null || !(o instanceof AlignmentOrder)) + { + return false; + } + return equals((AlignmentOrder) o, true); } /** @@ -223,7 +224,7 @@ public class AlignmentOrder { for (int i = 0, j = o.Order.size(); i < j; i++) { - if (Order.elementAt(i) != o.Order.elementAt(i)) + if (Order.get(i) != o.Order.get(i)) { return false; } @@ -271,7 +272,7 @@ public class AlignmentOrder } if (Order != null && o.Order != null) { - Vector c, s; + List c, s; if (o.Order.size() > Order.size()) { c = o.Order; @@ -292,7 +293,7 @@ public class AlignmentOrder int last = -1; for (int i = 0, j = s.size(); i < j; i++) { - int pos = c.indexOf(s.elementAt(i)); // JBPNote - optimize by + int pos = c.indexOf(s.get(i)); // JBPNote - optimize by // incremental position search if (pos > last) { diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 1d8b127..3093304 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -25,8 +25,7 @@ import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; +import java.util.Collections; import java.util.List; import java.util.Vector; @@ -35,7 +34,7 @@ import java.util.Vector; */ public class ColumnSelection { - Vector selected = new Vector(); + Vector selected = new Vector(); // Vector of int [] {startCol, endCol} Vector hiddenColumns; @@ -64,7 +63,7 @@ public class ColumnSelection } /** - * removes col from selection + * Removes value 'col' from the selection (not the col'th item) * * @param col * index of column to be removed @@ -75,6 +74,8 @@ public class ColumnSelection if (selected.contains(colInt)) { + // if this ever changes to List.remove(), ensure Integer not int argument + // as List.remove(int i) removes the i'th item which is wrong selected.removeElement(colInt); } } @@ -131,7 +132,7 @@ public class ColumnSelection */ public int columnAt(int i) { - return ((Integer) selected.elementAt(i)).intValue(); + return selected.elementAt(i).intValue(); } /** @@ -201,6 +202,7 @@ public class ColumnSelection if (temp >= start) { + // if this ever changes to List.set(), swap parameter order!! selected.setElementAt(new Integer(temp - change), i); } } @@ -258,6 +260,7 @@ public class ColumnSelection if (temp >= start) { + // if this ever changes to List.set(), swap parameter order!! selected.setElementAt(new Integer(temp - change), i); } } @@ -303,13 +306,13 @@ public class ColumnSelection { if (shiftrecord != null) { - Vector shifts = shiftrecord.shifts; + final List shifts = shiftrecord.getShifts(); if (shifts != null && shifts.size() > 0) { int shifted = 0; for (int i = 0, j = shifts.size(); i < j; i++) { - int[] sh = (int[]) shifts.elementAt(i); + int[] sh = shifts.get(i); // compensateForEdit(shifted+sh[0], sh[1]); compensateForDelEdits(shifted + sh[0], sh[1]); shifted -= sh[1]; @@ -324,16 +327,17 @@ public class ColumnSelection * removes intersection of position,length ranges in deletions from the * start,end regions marked in intervals. * - * @param deletions + * @param shifts * @param intervals * @return */ - private boolean pruneIntervalVector(Vector deletions, Vector intervals) + private boolean pruneIntervalVector(final List shifts, + Vector intervals) { boolean pruned = false; - int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1; - int hr[] = (int[]) intervals.elementAt(i); - int sr[] = (int[]) deletions.elementAt(s); + int i = 0, j = intervals.size() - 1, s = 0, t = shifts.size() - 1; + int hr[] = intervals.elementAt(i); + int sr[] = shifts.get(s); while (i <= j && s <= t) { boolean trailinghn = hr[1] >= sr[0]; @@ -341,7 +345,7 @@ public class ColumnSelection { if (i < j) { - hr = (int[]) intervals.elementAt(++i); + hr = intervals.elementAt(++i); } else { @@ -354,7 +358,7 @@ public class ColumnSelection { // leadinghc disjoint or not a deletion if (s < t) { - sr = (int[]) deletions.elementAt(++s); + sr = shifts.get(++s); } else { @@ -374,7 +378,7 @@ public class ColumnSelection j--; if (i <= j) { - hr = (int[]) intervals.elementAt(i); + hr = intervals.elementAt(i); } continue; } @@ -400,7 +404,7 @@ public class ColumnSelection // sr contained in hr if (s < t) { - sr = (int[]) deletions.elementAt(++s); + sr = shifts.get(++s); } else { @@ -414,15 +418,16 @@ public class ColumnSelection // operations. } - private boolean pruneColumnList(Vector deletion, Vector list) + private boolean pruneColumnList(final List shifts, + Vector list) { - int s = 0, t = deletion.size(); - int[] sr = (int[]) list.elementAt(s++); + int s = 0, t = shifts.size(); + int[] sr = shifts.get(s++); boolean pruned = false; int i = 0, j = list.size(); while (i < j && s <= t) { - int c = ((Integer) list.elementAt(i++)).intValue(); + int c = list.elementAt(i++).intValue(); if (sr[0] <= c) { if (sr[1] + sr[0] >= c) @@ -434,7 +439,7 @@ public class ColumnSelection { if (s < t) { - sr = (int[]) deletion.elementAt(s); + sr = shifts.get(s); } s++; } @@ -453,7 +458,7 @@ public class ColumnSelection { if (deletions != null) { - Vector shifts = deletions.shifts; + final List shifts = deletions.getShifts(); if (shifts != null && shifts.size() > 0) { // delete any intervals intersecting. @@ -485,8 +490,8 @@ public class ColumnSelection */ public List getHiddenColumns() { - return hiddenColumns == null ? Arrays.asList(new int[] - {}) : hiddenColumns; + return hiddenColumns == null ? Collections. emptyList() + : hiddenColumns; } /** @@ -644,7 +649,7 @@ public class ColumnSelection { if (hiddenColumns == null) { - hiddenColumns = new Vector(); + hiddenColumns = new Vector(); } boolean added = false; @@ -780,7 +785,7 @@ public class ColumnSelection { if (copy.selected != null) { - selected = new Vector(); + selected = new Vector(); for (int i = 0, j = copy.selected.size(); i < j; i++) { selected.addElement(copy.selected.elementAt(i)); @@ -788,7 +793,7 @@ public class ColumnSelection } if (copy.hiddenColumns != null) { - hiddenColumns = new Vector(copy.hiddenColumns.size()); + hiddenColumns = new Vector(copy.hiddenColumns.size()); for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++) { int[] rh, cp; @@ -885,7 +890,7 @@ public class ColumnSelection { if (hiddenColumns != null && hiddenColumns.size() > 0) { - Vector visiblecontigs = new Vector(); + List visiblecontigs = new ArrayList(); List regions = getHiddenColumns(); int vstart = start; @@ -904,7 +909,7 @@ public class ColumnSelection } if (hideStart > vstart) { - visiblecontigs.addElement(new int[] + visiblecontigs.add(new int[] { vstart, hideStart - 1 }); } vstart = hideEnd + 1; @@ -912,18 +917,18 @@ public class ColumnSelection if (vstart < end) { - visiblecontigs.addElement(new int[] + visiblecontigs.add(new int[] { vstart, end - 1 }); } int[] vcontigs = new int[visiblecontigs.size() * 2]; for (int i = 0, j = visiblecontigs.size(); i < j; i++) { - int[] vc = (int[]) visiblecontigs.elementAt(i); - visiblecontigs.setElementAt(null, i); + int[] vc = visiblecontigs.get(i); + visiblecontigs.set(i, null); vcontigs[i * 2] = vc[0]; vcontigs[i * 2 + 1] = vc[1]; } - visiblecontigs.removeAllElements(); + visiblecontigs.clear(); return vcontigs; } else @@ -970,7 +975,7 @@ public class ColumnSelection if (hiddenColumns != null && hiddenColumns.size() > 0) { // then mangle the alignmentAnnotation annotation array - Vector annels = new Vector(); + Vector annels = new Vector(); Annotation[] els = null; List regions = getHiddenColumns(); int blockStart = start, blockEnd = end; @@ -1026,12 +1031,12 @@ public class ColumnSelection { return; } - Enumeration e = annels.elements(); + alignmentAnnotation.annotations = new Annotation[w]; w = 0; - while (e.hasMoreElements()) + + for (Annotation [] chnk : annels) { - Annotation[] chnk = (Annotation[]) e.nextElement(); System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w, chnk.length); w += chnk.length; @@ -1079,15 +1084,13 @@ public class ColumnSelection { if (colsel != null && colsel.size() > 0) { - Enumeration e = colsel.getSelected().elements(); - while (e.hasMoreElements()) + for (Integer col : colsel.getSelected()) { - Object eo = e.nextElement(); - if (hiddenColumns != null && isVisible(((Integer) eo).intValue())) + if (hiddenColumns != null && isVisible(col.intValue())) { - if (!selected.contains(eo)) + if (!selected.contains(col)) { - selected.addElement(eo); + selected.addElement(col); } } } @@ -1102,22 +1105,20 @@ public class ColumnSelection */ public void setElementsFrom(ColumnSelection colsel) { - selected = new Vector(); + selected = new Vector(); if (colsel.selected != null && colsel.selected.size() > 0) { if (hiddenColumns != null && hiddenColumns.size() > 0) { // only select visible columns in this columns selection - selected = new Vector(); addElementsFrom(colsel); } else { // add everything regardless - Enumeration en = colsel.selected.elements(); - while (en.hasMoreElements()) + for (Integer col : colsel.getSelected()) { - selected.addElement(en.nextElement()); + addElement(col); } } } diff --git a/src/jalview/datamodel/IncompleteCodonException.java b/src/jalview/datamodel/IncompleteCodonException.java new file mode 100644 index 0000000..f716a53 --- /dev/null +++ b/src/jalview/datamodel/IncompleteCodonException.java @@ -0,0 +1,13 @@ +package jalview.datamodel; + +/** + * An exception to indicate that less than 3 nucleotide bases are available when + * trying to form a codon. + * + * @author gmcarstairs + * + */ +public class IncompleteCodonException extends RuntimeException +{ + +} diff --git a/src/jalview/datamodel/Mapping.java b/src/jalview/datamodel/Mapping.java index cb87719..be8fd58 100644 --- a/src/jalview/datamodel/Mapping.java +++ b/src/jalview/datamodel/Mapping.java @@ -20,21 +20,255 @@ */ package jalview.datamodel; -import java.util.Vector; - import jalview.util.MapList; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Vector; + public class Mapping { /** + * An iterator that serves the aligned codon positions (with their protein + * products). + * + * @author gmcarstairs + * + */ + public class AlignedCodonIterator implements Iterator + { + /* + * The gap character used in the aligned sequence + */ + private final char gap; + + /* + * The characters of the aligned sequence e.g. "-cGT-ACgTG-" + */ + private final char[] alignedSeq; + + /* + * Next position (base 0) in the aligned sequence + */ + private int alignedColumn = 0; + + /* + * Count of bases up to and including alignedColumn position + */ + private int alignedBases = 0; + + /* + * [start, end] from ranges (base 1) + */ + private Iterator fromRanges; + + /* + * [start, end] to ranges (base 1) + */ + private Iterator toRanges; + + /* + * The current [start, end] (base 1) from range + */ + private int[] currentFromRange = null; + + /* + * The current [start, end] (base 1) to range + */ + private int[] currentToRange = null; + + /* + * The next 'from' position (base 1) to process + */ + private int fromPosition = 0; + + /* + * The next 'to' position (base 1) to process + */ + private int toPosition = 0; + + /** + * Constructor + * + * @param cs + * the aligned sequence characters + * @param gapChar + */ + public AlignedCodonIterator(char[] cs, char gapChar) + { + this.alignedSeq = cs; + this.gap = gapChar; + fromRanges = map.getFromRanges().iterator(); + toRanges = map.getToRanges().iterator(); + if (fromRanges.hasNext()) + { + currentFromRange = fromRanges.next(); + fromPosition = currentFromRange[0]; + } + if (toRanges.hasNext()) + { + currentToRange = toRanges.next(); + toPosition = currentToRange[0]; + } + } + + /** + * Returns true unless we have already traversed the whole mapping. + */ + @Override + public boolean hasNext() + { + if (fromRanges.hasNext()) + { + return true; + } + if (currentFromRange == null || fromPosition >= currentFromRange[1]) + { + return false; + } + return true; + } + + /** + * Returns the next codon's aligned positions, and translated value. + * + * @throws NoSuchElementException + * if hasNext() would have returned false + * @throws IncompleteCodonException + * if not enough mapped bases are left to make up a codon + */ + @Override + public AlignedCodon next() throws IncompleteCodonException + { + if (!hasNext()) + { + throw new NoSuchElementException(); + } + + int[] codon = getNextCodon(); + int[] alignedCodon = getAlignedCodon(codon); + + String peptide = getPeptide(); + return new AlignedCodon(alignedCodon[0], alignedCodon[1], + alignedCodon[2], peptide); + } + + /** + * Retrieve the translation as the 'mapped to' position in the mapped to + * sequence. + * + * @return + */ + private String getPeptide() + { + // TODO should ideally handle toRatio other than 1 as well... + // i.e. code like getNextCodon() + if (toPosition <= currentToRange[1]) { + char pep = Mapping.this.to.getSequence()[toPosition - 1]; + toPosition++; + return String.valueOf(pep); + } + if (!toRanges.hasNext()) + { + throw new NoSuchElementException("Ran out of peptide at position " + + toPosition); + } + currentToRange = toRanges.next(); + toPosition = currentToRange[0]; + return getPeptide(); + } + + /** + * Get the (base 1) dataset positions for the next codon in the mapping. + * + * @throws IncompleteCodonException + * if less than 3 remaining bases are mapped + */ + private int[] getNextCodon() + { + int[] codon = new int[3]; + int codonbase = 0; + + while (codonbase < 3) + { + if (fromPosition <= currentFromRange[1]) + { + /* + * Add next position from the current start-end range + */ + codon[codonbase++] = fromPosition++; + } + else + { + /* + * Move to the next range - if there is one + */ + if (!fromRanges.hasNext()) + { + throw new IncompleteCodonException(); + } + currentFromRange = fromRanges.next(); + fromPosition = currentFromRange[0]; + } + } + return codon; + } + + /** + * Get the aligned column positions (base 0) for the given sequence + * positions (base 1), by counting ungapped characters in the aligned + * sequence. + * + * @param codon + * @return + */ + private int[] getAlignedCodon(int[] codon) + { + int[] aligned = new int[codon.length]; + for (int i = 0; i < codon.length; i++) + { + aligned[i] = getAlignedColumn(codon[i]); + } + return aligned; + } + + /** + * Get the aligned column position (base 0) for the given sequence position + * (base 1). + * + * @param sequencePos + * @return + */ + private int getAlignedColumn(int sequencePos) + { + while (alignedBases < sequencePos + && alignedColumn < alignedSeq.length) + { + if (alignedSeq[alignedColumn++] != gap) + { + alignedBases++; + } + } + return alignedColumn - 1; + } + + @Override + public void remove() + { + // ignore + } + + } + + /** * Contains the start-end pairs mapping from the associated sequence to the - * sequence in the database coordinate system it also takes care of step - * difference between coordinate systems + * sequence in the database coordinate system. It also takes care of step + * difference between coordinate systems. */ MapList map = null; /** - * The seuqence that map maps the associated seuqence to (if any). + * The sequence that map maps the associated sequence to (if any). */ SequenceI to = null; @@ -111,19 +345,31 @@ public class Mapping * @param other * @return */ - public boolean equals(Mapping other) + @Override + public boolean equals(Object o) { - if (other == null) + if (o == null || !(o instanceof Mapping)) + { return false; + } + Mapping other = (Mapping) o; if (other == this) + { return true; + } if (other.to != to) + { return false; + } if ((map != null && other.map == null) || (map == null && other.map != null)) + { return false; + } if (map.equals(other.map)) + { return true; + } return false; } @@ -251,7 +497,9 @@ public class Mapping vf[v].setBegin(frange[i]); vf[v].setEnd(frange[i + 1]); if (frange.length > 2) + { vf[v].setDescription(f.getDescription() + "\nPart " + (v + 1)); + } } return vf; } @@ -300,14 +548,18 @@ public class Mapping from = (map.getToLowest() < from) ? from : map.getToLowest(); to = (map.getToHighest() > to) ? to : map.getToHighest(); if (from > to) + { return null; + } } else { from = (map.getToHighest() > from) ? from : map.getToHighest(); to = (map.getToLowest() < to) ? to : map.getToLowest(); if (from < to) + { return null; + } } return map.locateInFrom(from, to); } @@ -333,14 +585,18 @@ public class Mapping from = (map.getFromLowest() < from) ? from : map.getFromLowest(); to = (map.getFromHighest() > to) ? to : map.getFromHighest(); if (from > to) + { return null; + } } else { from = (map.getFromHighest() > from) ? from : map.getFromHighest(); to = (map.getFromLowest() < to) ? to : map.getFromLowest(); if (from < to) + { return null; + } } return map.locateInTo(from, to); } @@ -455,4 +711,9 @@ public class Mapping super.finalize(); } + public Iterator getCodonIterator(SequenceI seq, char gapChar) + { + return new AlignedCodonIterator(seq.getSequence(), gapChar); + } + } diff --git a/src/jalview/datamodel/SearchResults.java b/src/jalview/datamodel/SearchResults.java index 8434e81..fb420b9 100755 --- a/src/jalview/datamodel/SearchResults.java +++ b/src/jalview/datamodel/SearchResults.java @@ -20,10 +20,81 @@ */ package jalview.datamodel; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Holds a list of search result matches, where each match is a contiguous + * stretch of a single sequence. + * + * @author gmcarstairs + * + */ public class SearchResults { - Match[] matches; + private List matches = new ArrayList(); + + public class Match + { + SequenceI sequence; + + /** + * Start position of match in sequence (base 1) + */ + int start; + + /** + * End position (inclusive) (base 1) + */ + int end; + + /** + * Constructor + * + * @param seq + * a sequence + * @param start + * start position of matched range (base 1) + * @param end + * end of matched range (inclusive, base 1) + */ + public Match(SequenceI seq, int start, int end) + { + sequence = seq; + this.start = start; + this.end = end; + } + + public SequenceI getSequence() + { + return sequence; + } + + public int getStart() + { + return start; + } + + public int getEnd() + { + return end; + } + + /** + * Returns the string of characters in the matched region. + */ + @Override + public String toString() + { + char[] chars = sequence.getSequence(); + // convert start/end to base 0 (with bounds check) + final int from = Math.max(start - 1, 0); + final int to = Math.min(end, chars.length + 1); + return String.valueOf(Arrays.copyOfRange(chars, from, to)); + } + } /** * This method replaces the old search results which merely held an alignment @@ -39,25 +110,7 @@ public class SearchResults */ public void addResult(SequenceI seq, int start, int end) { - if (matches == null) - { - matches = new Match[] - { new Match(seq, start, end) }; - return; - } - - int mSize = matches.length; - - Match[] tmp = new Match[mSize + 1]; - int m; - for (m = 0; m < mSize; m++) - { - tmp[m] = matches[m]; - } - - tmp[m] = new Match(seq, start, end); - - matches = tmp; + matches.add(new Match(seq, start, end)); } /** @@ -69,15 +122,11 @@ public class SearchResults */ public boolean involvesSequence(SequenceI sequence) { - if (matches == null || matches.length == 0) - { - return false; - } SequenceI ds = sequence.getDatasetSequence(); - for (int m = 0; m < matches.length; m++) + for (Match m : matches) { - if (matches[m].sequence != null - && (matches[m].sequence == sequence || matches[m].sequence == ds)) + if (m.sequence != null + && (m.sequence == sequence || m.sequence == ds)) { return true; } @@ -92,7 +141,7 @@ public class SearchResults */ public int[] getResults(SequenceI sequence, int start, int end) { - if (matches == null) + if (matches.isEmpty()) { return null; } @@ -101,22 +150,22 @@ public class SearchResults int[] tmp = null; int resultLength, matchStart = 0, matchEnd = 0; boolean mfound; - for (int m = 0; m < matches.length; m++) + for (Match m : matches) { mfound = false; - if (matches[m].sequence == sequence) + if (m.sequence == sequence) { mfound = true; // locate aligned position - matchStart = sequence.findIndex(matches[m].start) - 1; - matchEnd = sequence.findIndex(matches[m].end) - 1; + matchStart = sequence.findIndex(m.start) - 1; + matchEnd = sequence.findIndex(m.end) - 1; } - else if (matches[m].sequence == sequence.getDatasetSequence()) + else if (m.sequence == sequence.getDatasetSequence()) { mfound = true; // locate region in local context - matchStart = sequence.findIndex(matches[m].start) - 1; - matchEnd = sequence.findIndex(matches[m].end) - 1; + matchStart = sequence.findIndex(m.start) - 1; + matchEnd = sequence.findIndex(m.end) - 1; } if (mfound) { @@ -160,37 +209,71 @@ public class SearchResults public int getSize() { - return matches == null ? 0 : matches.length; + return matches.size(); } public SequenceI getResultSequence(int index) { - return matches[index].sequence; + return matches.get(index).sequence; } - public int getResultStart(int index) + /** + * Returns the start position of the i'th match in the search results. + * + * @param i + * @return + */ + public int getResultStart(int i) { - return matches[index].start; + return matches.get(i).start; } - public int getResultEnd(int index) + /** + * Returns the end position of the i'th match in the search results. + * + * @param i + * @return + */ + public int getResultEnd(int i) { - return matches[index].end; + return matches.get(i).end; } - class Match + /** + * Returns true if no search result matches are held. + * + * @return + */ + public boolean isEmpty() { - SequenceI sequence; - - int start; + return matches.isEmpty(); + } - int end; + /** + * Returns the list of matches. + * + * @return + */ + public List getResults() + { + return matches; + } - public Match(SequenceI seq, int start, int end) + /** + * Return the results as a string of characters. Meant for use when the + * context ensures that all matches are to regions of the same sequence + * (otherwise the result is meaningless). + * + * @return + */ + @Override + public String toString() + { + StringBuilder result = new StringBuilder(256); + for (Match m : matches) { - sequence = seq; - this.start = start; - this.end = end; + result.append(m.toString()); } + return result.toString(); } } diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 96e469a..78853c7 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -21,6 +21,7 @@ package jalview.datamodel; import jalview.analysis.AlignSeq; +import jalview.util.StringUtils; import java.util.ArrayList; import java.util.Enumeration; @@ -326,13 +327,26 @@ public class Sequence implements SequenceI } /** - * DOCUMENT ME! + * Returns the sequence features (if any), looking first on the sequence, then + * on its dataset sequence, and so on until a non-null value is found (or + * none). This supports retrieval of sequence features stored on the sequence + * (as in the applet) or on the dataset sequence (as in the Desktop version). * - * @return DOCUMENT ME! + * @return */ public SequenceFeature[] getSequenceFeatures() { - return sequenceFeatures; + SequenceFeature[] features = sequenceFeatures; + + SequenceI seq = this; + int count = 0; // failsafe against loop in sequence.datasetsequence... + while (features == null && seq.getDatasetSequence() != null + && count++ < 10) + { + seq = seq.getDatasetSequence(); + features = ((Sequence) seq).sequenceFeatures; + } + return features; } public void addPDBId(PDBEntry entry) @@ -726,24 +740,12 @@ public class Sequence implements SequenceI return; } - char[] tmp; - - if (j >= sequence.length) - { - tmp = new char[i]; - System.arraycopy(sequence, 0, tmp, 0, i); - j = sequence.length; - } - else - { - tmp = new char[sequence.length - j + i]; - System.arraycopy(sequence, 0, tmp, 0, i); - System.arraycopy(sequence, j, tmp, i, sequence.length - j); - } + char[] tmp = StringUtils.deleteChars(sequence, i, j); boolean createNewDs = false; - // TODO: take a look at the new dataset creation validation method below - - // this could become time comsuming for large sequences - consider making it - // more efficient + // TODO: take a (second look) at the dataset creation validation method for + // the very large sequence case + int eindex = -1, sindex = -1; + boolean ecalc = false, scalc = false; for (int s = i; s < j; s++) { if (jalview.schemes.ResidueProperties.aaIndex[sequence[s]] != 23) @@ -754,7 +756,11 @@ public class Sequence implements SequenceI } else { - int sindex = findIndex(start) - 1; + if (!scalc) + { + sindex = findIndex(start) - 1; + scalc = true; + } if (sindex == s) { // delete characters including start of sequence @@ -764,7 +770,11 @@ public class Sequence implements SequenceI else { // delete characters after start. - int eindex = findIndex(end) - 1; + if (!ecalc) + { + eindex = findIndex(end) - 1; + ecalc = true; + } if (eindex < j) { // delete characters at end of sequence @@ -1024,7 +1034,7 @@ public class Sequence implements SequenceI AlignmentAnnotation _aa = new AlignmentAnnotation(aa); _aa.sequenceRef = datasetSequence; _aa.adjustForAlignment(); // uses annotation's own record of - // sequence-column mapping + // sequence-column mapping datasetSequence.addAlignmentAnnotation(_aa); } } @@ -1245,8 +1255,10 @@ public class Sequence implements SequenceI String label) { List result = new ArrayList(); - if (this.annotation != null) { - for (AlignmentAnnotation ann : annotation) { + if (this.annotation != null) + { + for (AlignmentAnnotation ann : annotation) + { if (ann.calcId != null && ann.calcId.equals(calcId) && ann.label != null && ann.label.equals(label)) { diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java index c6b9cbd..739c8a0 100755 --- a/src/jalview/datamodel/SequenceGroup.java +++ b/src/jalview/datamodel/SequenceGroup.java @@ -1295,6 +1295,9 @@ public class SequenceGroup implements AnnotatedCollectionI return false; } + /** + * Remove all sequences from the group (leaving other properties unchanged). + */ public void clear() { synchronized (sequences) diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index 78311e4..1683921 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -172,8 +172,7 @@ public interface SequenceI public String getDescription(); /** - * Return the alignment column for a sequence position * Return the alignment - * position for a sequence position + * Return the alignment column for a sequence position * * @param pos * lying from start to end @@ -220,9 +219,9 @@ public interface SequenceI * if necessary and adjusting start and end positions accordingly. * * @param i - * first column in range to delete + * first column in range to delete (inclusive) * @param j - * last column in range to delete + * last column in range to delete (exclusive) */ public void deleteChars(int i, int j); @@ -238,13 +237,12 @@ public interface SequenceI /** * DOCUMENT ME! - * - * @param i + * @param position * DOCUMENT ME! - * @param c + * @param ch * DOCUMENT ME! */ - public void insertCharAt(int i, int length, char c); + public void insertCharAt(int position, int count, char ch); /** * DOCUMENT ME! diff --git a/src/jalview/datamodel/xdb/embl/EmblEntry.java b/src/jalview/datamodel/xdb/embl/EmblEntry.java index 3c88083..47c732f 100644 --- a/src/jalview/datamodel/xdb/embl/EmblEntry.java +++ b/src/jalview/datamodel/xdb/embl/EmblEntry.java @@ -425,9 +425,13 @@ public class EmblEntry { 1, dna.getLength() }, 1, 1)); // TODO: transform EMBL Database refs to canonical form if (dbRefs != null) + { for (Iterator i = dbRefs.iterator(); i.hasNext(); dna .addDBRef((DBRefEntry) i.next())) + { ; + } + } } try { @@ -440,7 +444,9 @@ public class EmblEntry { for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna .addDBRef((DBRefEntry) dbr.next())) + { ; + } } } if (FeatureProperties.isCodingFeature(sourceDb, feature.getName())) @@ -456,7 +462,9 @@ public class EmblEntry { for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna .addDBRef((DBRefEntry) dbr.next())) + { ; + } } } } @@ -659,7 +667,9 @@ public class EmblEntry // { 1prstart, prstart + prseq.length() - 1 }, 3, 1); pcdnaref.setMap(new Mapping(mp)); if (product != null) + { product.addDBRef(pcdnaref); + } } } @@ -671,18 +681,20 @@ public class EmblEntry sf.setEnd(exon[xint + 1]); sf.setType(feature.getName()); sf.setFeatureGroup(sourceDb); - sf.setDescription("Exon " + (1 + (int) (xint / 2)) + sf.setDescription("Exon " + (1 + xint / 2) + " for protein '" + prname + "' EMBLCDS:" + prid); sf.setValue(FeatureProperties.EXONPOS, new Integer(1 + xint)); sf.setValue(FeatureProperties.EXONPRODUCT, prname); if (vals != null && vals.size() > 0) { - Enumeration kv = vals.elements(); + Enumeration kv = vals.keys(); while (kv.hasMoreElements()) { Object key = kv.nextElement(); if (key != null) + { sf.setValue(key.toString(), vals.get(key)); + } } } dna.addSequenceFeature(sf); diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index 619144e..9569bd0 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -43,7 +43,6 @@ import java.awt.event.ComponentListener; import java.io.File; import java.net.URL; import java.security.AccessControlException; -import java.util.Enumeration; import java.util.Hashtable; import java.util.Map; import java.util.Vector; @@ -1328,17 +1327,15 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel return; } - String res; int index; Color col; jmolHistory(false); // TODO: Switch between nucleotide or aa selection expressions - Enumeration en = ResidueProperties.aa3Hash.keys(); - StringBuffer command = new StringBuffer("select *;color white;"); - while (en.hasMoreElements()) + StringBuilder command = new StringBuilder(128); + command.append("select *;color white;"); + for (String res : ResidueProperties.aa3Hash.keySet()) { - res = en.nextElement().toString(); - index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue(); + index = ResidueProperties.aa3Hash.get(res).intValue(); if (index > 20) { continue; diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index b345c5e..754bc7f 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -1,23 +1,3 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) - * Copyright (C) 2014 The Jalview Authors - * - * This file is part of Jalview. - * - * Jalview is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 - * of the License, or (at your option) any later version. - * - * Jalview is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jalview. If not, see . - * The Jalview Authors are detailed in the 'AUTHORS' file. - */ package jalview.ext.rbvi.chimera; import jalview.api.AlignmentViewPanel; @@ -39,7 +19,6 @@ import jalview.util.MessageManager; import java.awt.Color; import java.util.ArrayList; -import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -87,8 +66,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private Map chainFile; - private StringBuffer eval = new StringBuffer(); - public String fileLoadingError; /* @@ -109,6 +86,15 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private boolean loadedInline; /** + * current set of model filenames loaded + */ + String[] modelFileNames = null; + + String lastMousedOverAtomSpec; + + private List lastReply; + + /** * Open a PDB structure file in Chimera and set up mappings from Jalview. * * We check if the PDB model id is already loaded in Chimera, if so don't @@ -173,16 +159,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } /** - * current set of model filenames loaded - */ - String[] modelFileNames = null; - - - StringBuffer resetLastRes = new StringBuffer(); - - private List lastReply; - - /** * Constructor * * @param ssm @@ -693,7 +669,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } AlignmentI alignment = alignmentv.getAlignment(); - for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(files, sr, fr, alignment)) + for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands( + files, sr, fr, alignment)) { for (String command : cpdbbyseq.commands) { @@ -713,10 +690,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel String[] files, SequenceRenderer sr, FeatureRenderer fr, AlignmentI alignment) { - return ChimeraCommands - .getColourBySequenceCommand(getSsm(), files, getSequence(), sr, - fr, - alignment); + return ChimeraCommands.getColourBySequenceCommand(getSsm(), files, + getSequence(), sr, fr, alignment); } /** @@ -740,7 +715,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } } - + // End StructureListener // ////////////////////////// @@ -843,44 +818,44 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel public abstract SequenceRenderer getSequenceRenderer( AlignmentViewPanel alignment); - // jmol/ssm only + /** + * Construct and send a command to highlight an atom. + * + *
+   * Done by generating a command like (to 'highlight' position 44)
+   *   ~select #0:43.C;select #0:44.C
+   * Note this removes the selection from the previous position.
+   * 
+ */ public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile) { List cms = chimeraMaps.get(pdbfile); if (cms != null) { - int mdlNum = cms.get(0).getModelNumber(); - - viewerCommandHistory(false); - // viewer.stopListening(); - if (resetLastRes.length() > 0) + StringBuilder sb = new StringBuilder(); + sb.append(" #" + cms.get(0).getModelNumber()); + sb.append(":" + pdbResNum); + if (!chain.equals(" ")) { - eval.setLength(0); - eval.append(resetLastRes.toString() + ";"); + sb.append("." + chain); } + String atomSpec = sb.toString(); - eval.append("display "); // +modelNum - - resetLastRes.setLength(0); - resetLastRes.append("~display "); + StringBuilder command = new StringBuilder(32); + if (lastMousedOverAtomSpec != null) { - eval.append(" #" + (mdlNum)); - resetLastRes.append(" #" + (mdlNum)); + command.append("~select " + lastMousedOverAtomSpec + ";"); } - // complete select string - - eval.append(":" + pdbResNum); - resetLastRes.append(":" + pdbResNum); - if (!chain.equals(" ")) + viewerCommandHistory(false); + String cmd = command.toString(); + cmd = "select " + atomSpec; + if (cmd.length() > 0) { - eval.append("." + chain); - resetLastRes.append("." + chain); + viewer.sendChimeraCommand(cmd, false); } - - viewer.sendChimeraCommand(eval.toString(), false); viewerCommandHistory(true); - // viewer.startListening(); + this.lastMousedOverAtomSpec = atomSpec; } } @@ -1140,20 +1115,17 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel return; } - String res; int index; Color col; // Chimera expects RBG values in the range 0-1 final double normalise = 255D; viewerCommandHistory(false); // TODO: Switch between nucleotide or aa selection expressions - Enumeration en = ResidueProperties.aa3Hash.keys(); StringBuilder command = new StringBuilder(128); command.append("color white;"); - while (en.hasMoreElements()) + for (String res : ResidueProperties.aa3Hash.keySet()) { - res = en.nextElement().toString(); - index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue(); + index = ResidueProperties.aa3Hash.get(res).intValue(); if (index > 20) { continue; diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 6e3024d..e7a4735 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -25,12 +25,15 @@ import jalview.analysis.AlignmentSorter; import jalview.analysis.AlignmentUtils; import jalview.analysis.Conservation; import jalview.analysis.CrossRef; -import jalview.analysis.NJTree; +import jalview.analysis.Dna; import jalview.analysis.ParseProperties; import jalview.analysis.SequenceIdMatcher; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; +import jalview.api.SplitContainerI; +import jalview.api.ViewStyleI; import jalview.api.analysis.ScoreModelI; import jalview.bin.Cache; import jalview.commands.CommandI; @@ -53,6 +56,7 @@ import jalview.datamodel.SeqCigar; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.gui.ViewSelectionMenu.ViewSetProvider; import jalview.io.AlignmentProperties; import jalview.io.AnnotationFile; import jalview.io.BioJsHTMLOutput; @@ -86,6 +90,7 @@ import jalview.schemes.TurnColourScheme; import jalview.schemes.UserColourScheme; import jalview.schemes.ZappoColourScheme; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.jws1.Discoverer; import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.jabaws2.Jws2Instance; @@ -107,6 +112,8 @@ import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; @@ -118,9 +125,11 @@ import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Deque; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; +import java.util.Set; import java.util.Vector; import javax.swing.JButton; @@ -148,19 +157,20 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, IProgressIndicator, AlignViewControllerGuiI { - /** DOCUMENT ME!! */ public static final int DEFAULT_WIDTH = 700; - /** DOCUMENT ME!! */ public static final int DEFAULT_HEIGHT = 500; + /* + * The currently displayed panel (selected tabbed view if more than one) + */ public AlignmentPanel alignPanel; AlignViewport viewport; public AlignViewControllerI avc; - Vector alignPanels = new Vector(); + List alignPanels = new ArrayList(); /** * Last format used to load or save alignments in this window @@ -339,7 +349,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, buildSortByAnnotationScoresMenu(); buildTreeMenu(); - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { wrapMenuItem_actionPerformed(null); } @@ -351,6 +361,59 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, addKeyListener(); + final List selviews = new ArrayList(); + final List origview = new ArrayList(); + ViewSelectionMenu vsel = new ViewSelectionMenu("Transfer colours from", + new ViewSetProvider() + { + + @Override + public AlignmentPanel[] getAllAlignmentPanels() + { + origview.clear(); + origview.add(alignPanel); + return Desktop.getAlignmentPanels(null); + } + }, selviews, new ItemListener() + { + + @Override + public void itemStateChanged(ItemEvent e) + { + if (origview.size() > 0) + { + ViewStyleI vs = selviews.get(0).getAlignViewport() + .getViewStyle(); + origview.get(0).getAlignViewport().setViewStyle(vs); + AlignViewportI complement = origview.get(0) + .getAlignViewport().getCodingComplement(); + if (complement != null) + { + AlignFrame af = Desktop.getAlignFrameFor(complement); + if (complement.isNucleotide()) + { + complement.setViewStyle(vs); + vs.setCharWidth(vs.getCharWidth() / 3); + } + else + { + int rw = vs.getCharWidth(); + vs.setCharWidth(rw * 3); + complement.setViewStyle(vs); + vs.setCharWidth(rw); + } + af.alignPanel.updateLayout(); + af.setMenusForViewport(); + } + origview.get(0).updateLayout(); + origview.get(0).setSelected(true); + origview.get(0).alignFrame.setMenusForViewport(); + + } + } + }); + formatMenu.add(vsel); + } /** @@ -365,10 +428,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void setFileName(String file, String format) { fileName = file; - currentFileFormat = format; + setFileFormat(format); reload.setEnabled(true); } + /** + * Add a KeyListener with handlers for various KeyPressed and KeyReleased + * events + */ void addKeyListener() { addKeyListener(new KeyAdapter() @@ -542,7 +609,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, break; } case KeyEvent.VK_PAGE_UP: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(true); } @@ -553,7 +620,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } break; case KeyEvent.VK_PAGE_DOWN: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(false); } @@ -597,7 +664,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, avc = new jalview.controller.AlignViewController(this, viewport, alignPanel); - alignPanels.addElement(ap); + alignPanels.add(ap); PaintRefresher.Register(ap, ap.av.getSequenceSetId()); @@ -640,7 +707,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, expandViews.setEnabled(true); gatherViews.setEnabled(true); tabbedPane.setVisible(true); - AlignmentPanel first = (AlignmentPanel) alignPanels.firstElement(); + AlignmentPanel first = alignPanels.get(0); tabbedPane.addTab(first.av.viewName, first); this.getContentPane().add(tabbedPane, BorderLayout.CENTER); } @@ -701,6 +768,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, }).start(); } + /** + * Configure menu items that vary according to whether the alignment is + * nucleotide or protein + * + * @param nucleotide + */ public void setGUINucleotide(boolean nucleotide) { showTranslation.setVisible(nucleotide); @@ -709,16 +782,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, showGroupConservation.setEnabled(!nucleotide); rnahelicesColour.setEnabled(nucleotide); purinePyrimidineColour.setEnabled(nucleotide); - // Remember AlignFrame always starts as protein - // if (!nucleotide) - // { - // showTr - // calculateMenu.remove(calculateMenu.getItemCount() - 2); - // } + showComplementMenuItem.setText(MessageManager + .getString(nucleotide ? "label.protein" : "label.nucleotide")); + setColourSelected(jalview.bin.Cache.getDefault( + nucleotide ? Preferences.DEFAULT_COLOUR_NUC + : Preferences.DEFAULT_COLOUR_PROT, "None")); } /** - * set up menus for the currently viewport. This may be called after any + * set up menus for the current viewport. This may be called after any * operation that affects the data in the current view (selection changed, * etc) to update the menus to reflect the new state. */ @@ -737,17 +809,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, void setMenusFromViewport(AlignViewport av) { padGapsMenuitem.setSelected(av.isPadGaps()); - colourTextMenuItem.setSelected(av.showColourText); + colourTextMenuItem.setSelected(av.isShowColourText()); abovePIDThreshold.setSelected(av.getAbovePIDThreshold()); conservationMenuItem.setSelected(av.getConservationSelected()); seqLimits.setSelected(av.getShowJVSuffix()); idRightAlign.setSelected(av.isRightAlignIds()); - centreColumnLabelsMenuItem.setState(av.centreColumnLabels); - renderGapsMenuItem.setSelected(av.renderGaps); - wrapMenuItem.setSelected(av.wrapAlignment); - scaleAbove.setVisible(av.wrapAlignment); - scaleLeft.setVisible(av.wrapAlignment); - scaleRight.setVisible(av.wrapAlignment); + centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels()); + renderGapsMenuItem.setSelected(av.isRenderGaps()); + wrapMenuItem.setSelected(av.getWrapAlignment()); + scaleAbove.setVisible(av.getWrapAlignment()); + scaleLeft.setVisible(av.getWrapAlignment()); + scaleRight.setVisible(av.getWrapAlignment()); annotationPanelMenuItem.setState(av.isShowAnnotation()); /* * Show/hide annotations only enabled if annotation panel is shown @@ -756,8 +828,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState()); showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState()); hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState()); - viewBoxesMenuItem.setSelected(av.showBoxes); - viewTextMenuItem.setSelected(av.showText); + viewBoxesMenuItem.setSelected(av.getShowBoxes()); + viewTextMenuItem.setSelected(av.getShowText()); showNonconservedMenuItem.setSelected(av.getShowUnconserved()); showGroupConsensus.setSelected(av.isShowGroupConsensus()); showGroupConservation.setSelected(av.isShowGroupConservation()); @@ -769,10 +841,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .getGlobalColourScheme())); showSeqFeatures.setSelected(av.isShowSequenceFeatures()); - hiddenMarkers.setState(av.showHiddenMarkers); + hiddenMarkers.setState(av.getShowHiddenMarkers()); applyToAllGroups.setState(av.getColourAppliesToAllGroups()); - showNpFeatsMenuitem.setSelected(av.isShowNpFeats()); - showDbRefsMenuitem.setSelected(av.isShowDbRefs()); + showNpFeatsMenuitem.setSelected(av.isShowNPFeats()); + showDbRefsMenuitem.setSelected(av.isShowDBRefs()); autoCalculate.setSelected(av.autoCalculateConsensus); sortByTree.setSelected(av.sortByTree); listenToViewSelections.setSelected(av.followSelection); @@ -862,7 +934,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void actionPerformed(ActionEvent e) { handler.cancelActivity(id); - us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id); + us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id); } }); progressPanel.add(cancel, BorderLayout.EAST); @@ -1033,7 +1105,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, if (value == JalviewFileChooser.APPROVE_OPTION) { currentFileFormat = chooser.getSelectedFormat(); - if (currentFileFormat == null) + while (currentFileFormat == null) { JOptionPane .showInternalMessageDialog( @@ -1043,8 +1115,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, MessageManager .getString("label.file_format_not_specified"), JOptionPane.WARNING_MESSAGE); + currentFileFormat = chooser.getSelectedFormat(); value = chooser.showSaveDialog(this); - return; + if (value != JalviewFileChooser.APPROVE_OPTION) + { + return; + } } fileName = chooser.getSelectedFile().getPath(); @@ -1141,7 +1217,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, this.setTitle(file); statusBar.setText(MessageManager.formatMessage( "label.successfully_saved_to_file_in_format", - new String[] + new Object[] { fileName, format })); } catch (Exception ex) { @@ -1154,7 +1230,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, if (!success) { JOptionPane.showInternalMessageDialog(this, MessageManager - .formatMessage("label.couldnt_save_file", new String[] + .formatMessage("label.couldnt_save_file", new Object[] { fileName }), MessageManager .getString("label.error_saving_file"), JOptionPane.WARNING_MESSAGE); @@ -1216,7 +1292,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, viewport.getAlignment(), omitHidden, viewport.getColumnSelection())); Desktop.addInternalFrame(cap, MessageManager.formatMessage( - "label.alignment_output_command", new String[] + "label.alignment_output_command", new Object[] { e.getActionCommand() }), 600, 500); } catch (OutOfMemoryError oom) { @@ -1362,7 +1438,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // setClosed(true) is called for (int i = 0; i < alignPanels.size(); i++) { - AlignmentPanel ap = (AlignmentPanel) alignPanels.elementAt(i); + AlignmentPanel ap = alignPanels.get(i); ap.closePanel(); } } @@ -1384,22 +1460,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } /** - * close alignPanel2 and shuffle tabs appropriately. + * Close the specified panel and close up tabs appropriately. * - * @param alignPanel2 + * @param panelToClose */ - public void closeView(AlignmentPanel alignPanel2) + public void closeView(AlignmentPanel panelToClose) { int index = tabbedPane.getSelectedIndex(); - int closedindex = tabbedPane.indexOfComponent(alignPanel2); - alignPanels.removeElement(alignPanel2); - // Unnecessary - // if (viewport == alignPanel2.av) - // { - // viewport = null; - // } - alignPanel2.closePanel(); - alignPanel2 = null; + int closedindex = tabbedPane.indexOfComponent(panelToClose); + alignPanels.remove(panelToClose); + panelToClose.closePanel(); + panelToClose = null; tabbedPane.removeTabAt(closedindex); tabbedPane.validate(); @@ -1419,12 +1490,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, void updateEditMenuBar() { - if (viewport.historyList.size() > 0) + if (viewport.getHistoryList().size() > 0) { undoMenuItem.setEnabled(true); - CommandI command = viewport.historyList.peek(); + CommandI command = viewport.getHistoryList().peek(); undoMenuItem.setText(MessageManager.formatMessage( - "label.undo_command", new String[] + "label.undo_command", new Object[] { command.getDescription() })); } else @@ -1433,13 +1504,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, undoMenuItem.setText(MessageManager.getString("action.undo")); } - if (viewport.redoList.size() > 0) + if (viewport.getRedoList().size() > 0) { redoMenuItem.setEnabled(true); - CommandI command = viewport.redoList.peek(); + CommandI command = viewport.getRedoList().peek(); redoMenuItem.setText(MessageManager.formatMessage( - "label.redo_command", new String[] + "label.redo_command", new Object[] { command.getDescription() })); } else @@ -1453,8 +1524,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { if (command.getSize() > 0) { - viewport.historyList.push(command); - viewport.redoList.clear(); + viewport.addToHistoryList(command); + viewport.clearRedoList(); updateEditMenuBar(); viewport.updateHiddenColumns(); // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null @@ -1472,11 +1543,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { if (alignPanels != null) { - Enumeration e = alignPanels.elements(); AlignmentI[] als = new AlignmentI[alignPanels.size()]; - for (int i = 0; e.hasMoreElements(); i++) + int i = 0; + for (AlignmentPanel ap : alignPanels) { - als[i] = ((AlignmentPanel) e.nextElement()).av.getAlignment(); + als[i++] = ap.av.getAlignment(); } return als; } @@ -1497,15 +1568,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void undoMenuItem_actionPerformed(ActionEvent e) { - if (viewport.historyList.empty()) + if (viewport.getHistoryList().isEmpty()) { return; } - CommandI command = viewport.historyList.pop(); - viewport.redoList.push(command); + CommandI command = viewport.getHistoryList().pop(); + viewport.addToRedoList(command); command.undoCommand(getViewAlignments()); - AlignViewport originalSource = getOriginatingSource(command); + AlignmentViewport originalSource = getOriginatingSource(command); updateEditMenuBar(); if (originalSource != null) @@ -1535,16 +1606,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void redoMenuItem_actionPerformed(ActionEvent e) { - if (viewport.redoList.size() < 1) + if (viewport.getRedoList().size() < 1) { return; } - CommandI command = viewport.redoList.pop(); - viewport.historyList.push(command); + CommandI command = viewport.getRedoList().pop(); + viewport.addToHistoryList(command); command.doCommand(getViewAlignments()); - AlignViewport originalSource = getOriginatingSource(command); + AlignmentViewport originalSource = getOriginatingSource(command); updateEditMenuBar(); if (originalSource != null) @@ -1566,9 +1637,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } - AlignViewport getOriginatingSource(CommandI command) + AlignmentViewport getOriginatingSource(CommandI command) { - AlignViewport originalSource = null; + AlignmentViewport originalSource = null; // For sequence removal and addition, we need to fire // the property change event FROM the viewport where the // original alignment was altered @@ -1577,16 +1648,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { EditCommand editCommand = (EditCommand) command; al = editCommand.getAlignment(); - Vector comps = (Vector) PaintRefresher.components.get(viewport + List comps = PaintRefresher.components.get(viewport .getSequenceSetId()); - for (int i = 0; i < comps.size(); i++) + for (Component comp : comps) { - if (comps.elementAt(i) instanceof AlignmentPanel) + if (comp instanceof AlignmentPanel) { - if (al == ((AlignmentPanel) comps.elementAt(i)).av.getAlignment()) + if (al == ((AlignmentPanel) comp).av.getAlignment()) { - originalSource = ((AlignmentPanel) comps.elementAt(i)).av; + originalSource = ((AlignmentPanel) comp).av; break; } } @@ -1629,7 +1700,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, synchronized void slideSequences(boolean right, int size) { - List sg = new Vector(); + List sg = new ArrayList(); if (viewport.cursorMode) { sg.add(viewport.getAlignment().getSequenceAt( @@ -1648,13 +1719,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return; } - Vector invertGroup = new Vector(); + List invertGroup = new ArrayList(); - for (int i = 0; i < viewport.getAlignment().getHeight(); i++) + for (SequenceI seq : viewport.getAlignment().getSequences()) { - if (!sg.contains(viewport.getAlignment().getSequenceAt(i))) + if (!sg.contains(seq)) { - invertGroup.add(viewport.getAlignment().getSequenceAt(i)); + invertGroup.add(seq); } } @@ -1663,7 +1734,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, SequenceI[] seqs2 = new SequenceI[invertGroup.size()]; for (int i = 0; i < invertGroup.size(); i++) { - seqs2[i] = (SequenceI) invertGroup.elementAt(i); + seqs2[i] = invertGroup.get(i); } SlideSequencesCommand ssc; @@ -1711,11 +1782,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } boolean appendHistoryItem = false; - if (viewport.historyList != null && viewport.historyList.size() > 0 - && viewport.historyList.peek() instanceof SlideSequencesCommand) + Deque historyList = viewport.getHistoryList(); + if (historyList != null + && historyList.size() > 0 + && historyList.peek() instanceof SlideSequencesCommand) { appendHistoryItem = ssc - .appendSlideCommand((SlideSequencesCommand) viewport.historyList + .appendSlideCommand((SlideSequencesCommand) historyList .peek()); } @@ -1791,7 +1864,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, Desktop.jalviewClipboard = new Object[] { seqs, viewport.getAlignment().getDataset(), hiddenColumns }; statusBar.setText(MessageManager.formatMessage( - "label.copied_sequences_to_clipboard", new String[] + "label.copied_sequences_to_clipboard", new Object[] { Integer.valueOf(seqs.length).toString() })); } @@ -2089,7 +2162,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, alignment.getSequences()); if (alignPanels != null) { - for (AlignmentPanel ap : ((Vector) alignPanels)) + for (AlignmentPanel ap : alignPanels) { ap.validateAnnotationDimensions(false); } @@ -2236,15 +2309,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return; } - List seqs = new ArrayList(sg.getSize()); - SequenceI seq; - for (int i = 0; i < sg.getSize(); i++) - { - seq = sg.getSequenceAt(i); - seqs.add(seq); - } - - // If the cut affects all sequences, warn, remove highlighted columns + /* + * If the cut affects all sequences, warn, remove highlighted columns + */ if (sg.getSize() == viewport.getAlignment().getHeight()) { int confirm = JOptionPane.showConfirmDialog(this, @@ -2261,15 +2328,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sg.getEndRes() + 1); } - SequenceI[] cut = new SequenceI[seqs.size()]; - for (int i = 0; i < seqs.size(); i++) - { - cut[i] = seqs.get(i); - } + SequenceI[] cut = sg.getSequences() + .toArray(new SequenceI[sg.getSize()]); - /* - * //ADD HISTORY ITEM - */ addHistoryItem(new EditCommand( MessageManager.getString("label.cut_sequences"), Action.CUT, cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1, @@ -2511,7 +2572,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, addHistoryItem(removeGapCols); statusBar.setText(MessageManager.formatMessage( - "label.removed_empty_columns", new String[] + "label.removed_empty_columns", new Object[] { Integer.valueOf(removeGapCols.getSize()).toString() })); // This is to maintain viewport position on first residue @@ -2582,16 +2643,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .getSequences()); } - // else - { - // if (justifySeqs>0) - { - // alignment.justify(justifySeqs!=RIGHT_JUSTIFY); - } - } - - // } - /** * DOCUMENT ME! * @@ -2604,74 +2655,80 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, new Finder(); } - @Override - public void newView_actionPerformed(ActionEvent e) - { - newView(true); - } - - /** - * - * @param copyAnnotation - * if true then duplicate all annnotation, groups and settings - * @return new alignment panel, already displayed. - */ - public AlignmentPanel newView(boolean copyAnnotation) - { - return newView(null, copyAnnotation); - } - /** - * - * @param viewTitle - * title of newly created view - * @return new alignment panel, already displayed. + * Create a new view of the current alignment. */ - public AlignmentPanel newView(String viewTitle) + @Override + public void newView_actionPerformed(ActionEvent e) { - return newView(viewTitle, true); + newView(null, true); } /** + * Creates and shows a new view of the current alignment. * * @param viewTitle - * title of newly created view + * title of newly created view; if null, one will be generated * @param copyAnnotation * if true then duplicate all annnotation, groups and settings * @return new alignment panel, already displayed. */ public AlignmentPanel newView(String viewTitle, boolean copyAnnotation) { + /* + * Create a new AlignmentPanel (with its own, new Viewport) + */ AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel, true); if (!copyAnnotation) { - // just remove all the current annotation except for the automatic stuff + /* + * remove all groups and annotation except for the automatic stuff + */ newap.av.getAlignment().deleteAllGroups(); - for (AlignmentAnnotation alan : newap.av.getAlignment() - .getAlignmentAnnotation()) - { - if (!alan.autoCalculated) - { - newap.av.getAlignment().deleteAnnotation(alan); - } - ; - } + newap.av.getAlignment().deleteAllAnnotations(false); } - newap.av.gatherViewsHere = false; + newap.av.setGatherViewsHere(false); if (viewport.viewName == null) { - viewport.viewName = "Original"; + viewport.viewName = MessageManager + .getString("label.view_name_original"); } - newap.av.historyList = viewport.historyList; - newap.av.redoList = viewport.redoList; + /* + * Views share the same edits, undo and redo stacks, mappings. + */ + newap.av.setHistoryList(viewport.getHistoryList()); + newap.av.setRedoList(viewport.getRedoList()); + newap.av.getAlignment().setCodonFrames( + viewport.getAlignment().getCodonFrames()); + + newap.av.viewName = getNewViewName(viewTitle); + + addAlignmentPanel(newap, true); + newap.alignmentChanged(); + if (alignPanels.size() == 2) + { + viewport.setGatherViewsHere(true); + } + tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); + return newap; + } + + /** + * Make a new name for the view, ensuring it is unique within the current + * sequenceSetId. (This used to be essential for Jalview Project archives, but + * these now use viewId. Unique view names are still desirable for usability.) + * + * @param viewTitle + * @return + */ + protected String getNewViewName(String viewTitle) + { int index = Desktop.getViewCount(viewport.getSequenceSetId()); - // make sure the new view has a unique name - this is essential for Jalview - // 2 archives boolean addFirstIndex = false; if (viewTitle == null || viewTitle.trim().length() == 0) { @@ -2683,45 +2740,55 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, index = 1;// we count from 1 if given a specific name } String newViewName = viewTitle + ((addFirstIndex) ? " " + index : ""); - Vector comps = (Vector) PaintRefresher.components.get(viewport + + List comps = PaintRefresher.components.get(viewport .getSequenceSetId()); - Vector existingNames = new Vector(); - for (int i = 0; i < comps.size(); i++) - { - if (comps.elementAt(i) instanceof AlignmentPanel) - { - AlignmentPanel ap = (AlignmentPanel) comps.elementAt(i); - if (!existingNames.contains(ap.av.viewName)) - { - existingNames.addElement(ap.av.viewName); - } - } - } + + List existingNames = getExistingViewNames(comps); while (existingNames.contains(newViewName)) { newViewName = viewTitle + " " + (++index); } + return newViewName; + } - newap.av.viewName = newViewName; - - addAlignmentPanel(newap, true); - newap.alignmentChanged(); - - if (alignPanels.size() == 2) + /** + * Returns a list of distinct view names found in the given list of + * components. View names are held on the viewport of an AlignmentPanel. + * + * @param comps + * @return + */ + protected List getExistingViewNames(List comps) + { + List existingNames = new ArrayList(); + for (Component comp : comps) { - viewport.gatherViewsHere = true; + if (comp instanceof AlignmentPanel) + { + AlignmentPanel ap = (AlignmentPanel) comp; + if (!existingNames.contains(ap.av.viewName)) + { + existingNames.add(ap.av.viewName); + } + } } - tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); - return newap; + return existingNames; } + /** + * Explode tabbed views into separate windows. + */ @Override public void expandViews_actionPerformed(ActionEvent e) { Desktop.instance.explodeViews(this); } + /** + * Gather views in separate windows back into a tabbed presentation. + */ @Override public void gatherViews_actionPerformed(ActionEvent e) { @@ -2766,7 +2833,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void centreColumnLabels_actionPerformed(ActionEvent e) { - viewport.centreColumnLabels = centreColumnLabelsMenuItem.getState(); + viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState()); alignPanel.paintAlignment(true); } @@ -2778,6 +2845,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void followHighlight_actionPerformed() { + /* + * Set the 'follow' flag on the Viewport (and scroll to position if now + * true). + */ if (viewport.followHighlight = this.followHighlightMenuItem.getState()) { alignPanel.scrollToPosition( @@ -2811,7 +2882,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, scaleLeft.setVisible(wrapMenuItem.isSelected()); scaleRight.setVisible(wrapMenuItem.isSelected()); viewport.setWrapAlignment(wrapMenuItem.isSelected()); - alignPanel.setWrapAlignment(wrapMenuItem.isSelected()); + alignPanel.updateLayout(); } @Override @@ -2831,7 +2902,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void hideSelSequences_actionPerformed(ActionEvent e) { viewport.hideAllSelectedSeqs(); - alignPanel.paintAlignment(true); +// alignPanel.paintAlignment(true); } /** @@ -3115,11 +3186,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { final boolean setVisible = annotationPanelMenuItem.isSelected(); viewport.setShowAnnotation(setVisible); - alignPanel.setAnnotationVisible(setVisible); this.showAllSeqAnnotations.setEnabled(setVisible); this.hideAllSeqAnnotations.setEnabled(setVisible); this.showAllAlAnnotations.setEnabled(setVisible); this.hideAllAlAnnotations.setEnabled(setVisible); + alignPanel.updateLayout(); } @Override @@ -3130,13 +3201,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, StringBuffer contents = new AlignmentProperties(viewport.getAlignment()) .formatAsHtml(); editPane.setText(MessageManager.formatMessage("label.html_content", - new String[] + new Object[] { contents.toString() })); JInternalFrame frame = new JInternalFrame(); frame.getContentPane().add(new JScrollPane(editPane)); - Desktop.instance.addInternalFrame(frame, MessageManager.formatMessage( - "label.alignment_properties", new String[] + Desktop.addInternalFrame(frame, MessageManager.formatMessage( + "label.alignment_properties", new Object[] { getTitle() }), 500, 400); } @@ -3158,7 +3229,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, OverviewPanel overview = new OverviewPanel(alignPanel); frame.setContentPane(overview); Desktop.addInternalFrame(frame, MessageManager.formatMessage( - "label.overview_params", new String[] + "label.overview_params", new Object[] { this.getTitle() }), frame.getWidth(), frame.getHeight()); frame.pack(); frame.setLayer(JLayeredPane.PALETTE_LAYER); @@ -3361,11 +3432,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background"); - cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus()); + cs.setThreshold(threshold, viewport.isIgnoreGapsConsensus()); } else { - cs.setThreshold(0, viewport.getIgnoreGapsConsensus()); + cs.setThreshold(0, viewport.isIgnoreGapsConsensus()); } if (viewport.getConservationSelected()) @@ -3428,7 +3499,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { - sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus()); + sg.cs.setThreshold(threshold, viewport.isIgnoreGapsConsensus()); sg.cs.setConsensus(AAFrequency.calculate( sg.getSequences(viewport.getHiddenRepSequences()), @@ -3436,7 +3507,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } else { - sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, viewport.isIgnoreGapsConsensus()); } if (viewport.getConservationSelected()) @@ -3565,8 +3636,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { Component[] menuItems = colourMenu.getMenuComponents(); - int i, iSize = menuItems.length; - for (i = 0; i < iSize; i++) + int iSize = menuItems.length; + for (int i = 0; i < iSize; i++) { if (menuItems[i].getName() != null && menuItems[i].getName().equals("USER_DEFINED")) @@ -3827,7 +3898,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("AV", "PID", "Average distance tree using PID"); + newTreePanel("AV", "PID", "Average distance tree using PID"); } /** @@ -3839,7 +3910,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void neighbourTreeMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("NJ", "PID", "Neighbour joining tree using PID"); + newTreePanel("NJ", "PID", "Neighbour joining tree using PID"); } /** @@ -3851,7 +3922,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62"); + newTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62"); } /** @@ -3863,7 +3934,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62"); + newTreePanel("AV", "BL", "Average distance tree using BLOSUM62"); } /** @@ -3876,7 +3947,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * @param title * DOCUMENT ME! */ - void NewTreePanel(String type, String pwType, String title) + void newTreePanel(String type, String pwType, String title) { TreePanel tp; @@ -3967,7 +4038,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void addSortByOrderMenuItem(String title, final AlignmentOrder order) { - final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new String[]{title})); + final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new Object[]{title})); sort.add(item); item.addActionListener(new java.awt.event.ActionListener() { @@ -4091,7 +4162,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { String treecalcnm = MessageManager.getString("label.tree_calc_" + type.toLowerCase()); - for (final Object pwtype : ResidueProperties.scoreMatrices.keySet()) + for (final String pwtype : ResidueProperties.scoreMatrices.keySet()) { JMenuItem tm = new JMenuItem(); ScoreModelI sm = ResidueProperties.scoreMatrices.get(pwtype); @@ -4107,7 +4178,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void actionPerformed(ActionEvent e) { - NewTreePanel(type, (String) pwtype, title); + newTreePanel(type, pwtype, title); } }); calculateTree.add(tm); @@ -4117,21 +4188,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } sortByTreeMenu.removeAll(); - Vector comps = (Vector) PaintRefresher.components.get(viewport + List comps = PaintRefresher.components.get(viewport .getSequenceSetId()); - Vector treePanels = new Vector(); - int i, iSize = comps.size(); - for (i = 0; i < iSize; i++) + List treePanels = new ArrayList(); + for (Component comp : comps) { - if (comps.elementAt(i) instanceof TreePanel) + if (comp instanceof TreePanel) { - treePanels.add(comps.elementAt(i)); + treePanels.add((TreePanel) comp); } } - iSize = treePanels.size(); - - if (iSize < 1) + if (treePanels.size() < 1) { sortByTreeMenu.setVisible(false); return; @@ -4139,17 +4207,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sortByTreeMenu.setVisible(true); - for (i = 0; i < treePanels.size(); i++) + for (final TreePanel tp : treePanels) { - final TreePanel tp = (TreePanel) treePanels.elementAt(i); final JMenuItem item = new JMenuItem(tp.getTitle()); - final NJTree tree = ((TreePanel) treePanels.elementAt(i)).getTree(); item.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent e) { - tp.sortByTree_actionPerformed(null); + tp.sortByTree_actionPerformed(); addHistoryItem(tp.sortAlignmentIn(alignPanel)); } @@ -4389,7 +4455,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } catch (Exception e) { } - ; } final AlignFrame me = this; buildingMenu = true; @@ -4544,14 +4609,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .debug("Exception during web service menu building process.", e); } - ; } }); } catch (Exception e) { } - ; - buildingMenu = false; } }).start(); @@ -4663,7 +4725,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void actionPerformed(ActionEvent e) { // TODO: new thread for this call with vis-delay - af.showProductsFor(af.viewport.getSequenceSelection(), ds, + af.showProductsFor(af.viewport.getSequenceSelection(), isRegSel, dna, source); } @@ -4682,14 +4744,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return showp; } - protected void showProductsFor(SequenceI[] sel, Alignment ds, - boolean isRegSel, boolean dna, String source) + protected void showProductsFor(final SequenceI[] sel, + final boolean isRegSel, final boolean dna, final String source) { - final boolean fisRegSel = isRegSel; - final boolean fdna = dna; - final String fsrc = source; - final AlignFrame ths = this; - final SequenceI[] fsel = sel; Runnable foo = new Runnable() { @@ -4697,15 +4754,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void run() { final long sttime = System.currentTimeMillis(); - ths.setProgressBar(MessageManager.formatMessage("status.searching_for_sequences_from", new String[]{fsrc}), sttime); + AlignFrame.this.setProgressBar(MessageManager.formatMessage( + "status.searching_for_sequences_from", new Object[] + { source }), sttime); try { - Alignment ds = ths.getViewport().getAlignment().getDataset(); // update - // our local - // dataset - // reference + // update our local dataset reference + Alignment ds = AlignFrame.this.getViewport().getAlignment() + .getDataset(); Alignment prods = CrossRef - .findXrefSequences(fsel, fdna, fsrc, ds); + .findXrefSequences(sel, dna, source, ds); if (prods != null) { SequenceI[] sprods = new SequenceI[prods.getHeight()]; @@ -4721,25 +4779,46 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sprods[s].updatePDBIds(); } Alignment al = new Alignment(sprods); - AlignedCodonFrame[] cf = prods.getCodonFrames(); + Set cf = prods.getCodonFrames(); al.setDataset(ds); - for (int s = 0; cf != null && s < cf.length; s++) + for (AlignedCodonFrame acf : cf) { - al.addCodonFrame(cf[s]); - cf[s] = null; + al.addCodonFrame(acf); } AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); - String newtitle = "" + ((fdna) ? "Proteins " : "Nucleotides ") - + " for " + ((fisRegSel) ? "selected region of " : "") + String newtitle = "" + ((dna) ? "Proteins" : "Nucleotides") + + " for " + ((isRegSel) ? "selected region of " : "") + getTitle(); - Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH, - DEFAULT_HEIGHT); + naf.setTitle(newtitle); + + // remove this flag once confirmed we want a split view + boolean asSplitFrame = true; + if (asSplitFrame) + { + AlignFrame copyThis = new AlignFrame( + AlignFrame.this.viewport.getAlignment(), + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + copyThis.setTitle(AlignFrame.this.getTitle()); + // SplitFrame with dna above, protein below + SplitFrame sf = new SplitFrame(dna ? copyThis : naf, + dna ? naf : copyThis); + naf.setVisible(true); + copyThis.setVisible(true); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + Desktop.addInternalFrame(sf, linkedTitle, -1, -1); + } + else + { + Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH, + DEFAULT_HEIGHT); + } } else { System.err.println("No Sequences generated for xRef type " - + fsrc); + + source); } } catch (Exception e) { @@ -4753,7 +4832,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, jalview.bin.Cache.log.error("Error when finding crossreferences", e); } - ths.setProgressBar(MessageManager.formatMessage("status.finished_searching_for_sequences_from", new String[]{fsrc}), + AlignFrame.this.setProgressBar(MessageManager.formatMessage( + "status.finished_searching_for_sequences_from", + new Object[] + { source }), sttime); } @@ -4779,96 +4861,66 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } - @Override - public void showProducts_actionPerformed(ActionEvent e) - { - // ///////////////////////////// - // Collect Data to be translated/transferred - - SequenceI[] selection = viewport.getSequenceSelection(); - AlignmentI al = null; - try - { - al = jalview.analysis.Dna.CdnaTranslate(selection, viewport - .getViewAsVisibleContigs(true), viewport.getGapCharacter(), - viewport.getAlignment().getDataset()); - } catch (Exception ex) - { - al = null; - jalview.bin.Cache.log.debug("Exception during translation.", ex); - } - if (al == null) - { - JOptionPane - .showMessageDialog( - Desktop.desktop, - MessageManager - .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"), - MessageManager.getString("label.translation_failed"), - JOptionPane.WARNING_MESSAGE); - } - else - { - AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); - Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.translation_of_params", new String[] - { this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT); - } - } - + /** + * Construct and display a new frame containing the translation of this + * frame's DNA sequences to their aligned protein (amino acid) equivalents. + */ @Override public void showTranslation_actionPerformed(ActionEvent e) { - // ///////////////////////////// - // Collect Data to be translated/transferred - - SequenceI[] selection = viewport.getSequenceSelection(); - String[] seqstring = viewport.getViewAsString(true); AlignmentI al = null; try { - al = jalview.analysis.Dna.CdnaTranslate(selection, seqstring, - viewport.getViewAsVisibleContigs(true), viewport - .getGapCharacter(), viewport.getAlignment() - .getAlignmentAnnotation(), viewport.getAlignment() - .getWidth(), viewport.getAlignment().getDataset()); + Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true)); + + al = dna.translateCdna(); } catch (Exception ex) { - al = null; jalview.bin.Cache.log.error( "Exception during translation. Please report this !", ex); - JOptionPane - .showMessageDialog( - Desktop.desktop, - MessageManager - .getString("label.error_when_translating_sequences_submit_bug_report"), - MessageManager - .getString("label.implementation_error") - + MessageManager - .getString("translation_failed"), - JOptionPane.ERROR_MESSAGE); + final String msg = MessageManager + .getString("label.error_when_translating_sequences_submit_bug_report"); + final String title = MessageManager + .getString("label.implementation_error") + + MessageManager.getString("translation_failed"); + JOptionPane.showMessageDialog(Desktop.desktop, msg, title, + JOptionPane.ERROR_MESSAGE); return; } - if (al == null) + if (al == null || al.getHeight() == 0) { - JOptionPane - .showMessageDialog( - Desktop.desktop, - MessageManager - .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"), - MessageManager.getString("label.translation_failed"), - JOptionPane.WARNING_MESSAGE); + final String msg = MessageManager + .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"); + final String title = MessageManager + .getString("label.translation_failed"); + JOptionPane.showMessageDialog(Desktop.desktop, msg, title, + JOptionPane.WARNING_MESSAGE); } else { AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); - Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.translation_of_params", new String[] - { this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT); + af.setFileFormat(this.currentFileFormat); + final String newTitle = MessageManager.formatMessage( + "label.translation_of_params", new Object[] + { this.getTitle() }); + af.setTitle(newTitle); + final SequenceI[] seqs = viewport.getSelectionAsNewSequence(); + viewport.openSplitFrame(af, new Alignment(seqs), al.getCodonFrames()); + // Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH, DEFAULT_HEIGHT); } } /** + * Set the file format + * + * @param fileFormat + */ + public void setFileFormat(String fileFormat) + { + this.currentFileFormat = fileFormat; + } + + /** * Try to load a features file onto the alignment. * * @param file @@ -5060,7 +5112,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, MessageManager .formatMessage( "label.automatically_associate_pdb_files_with_sequences_same_name", - new String[] + new Object[] { Integer.valueOf( filesmatched .size()) @@ -5103,7 +5155,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, ""+MessageManager .formatMessage( "label.ignore_unmatched_dropped_files_info", - new String[] + new Object[] { Integer.valueOf( filesnotmatched .size()) @@ -5211,7 +5263,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { jalview.io.JPredFile predictions = new jalview.io.JPredFile( file, protocol); - new JnetAnnotationMaker().add_annotation(predictions, + new JnetAnnotationMaker(); + JnetAnnotationMaker.add_annotation(predictions, viewport.getAlignment(), 0, false); isAnnotation = true; } @@ -5283,31 +5336,55 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } + /** + * Method invoked by the ChangeListener on the tabbed pane, in other words + * when a different tabbed pane is selected by the user or programmatically. + */ @Override public void tabSelectionChanged(int index) { if (index > -1) { - alignPanel = (AlignmentPanel) alignPanels.elementAt(index); + alignPanel = alignPanels.get(index); viewport = alignPanel.av; avc.setViewportAndAlignmentPanel(viewport, alignPanel); setMenusFromViewport(viewport); } + + /* + * If there is a frame linked to this one in a SplitPane, switch it to the + * same view tab index. No infinite recursion of calls should happen, since + * tabSelectionChanged() should not get invoked on setting the selected + * index to an unchanged value. Guard against setting an invalid index + * before the new view peer tab has been created. + */ + final AlignViewportI peer = viewport.getCodingComplement(); + if (peer != null) + { + AlignFrame linkedAlignFrame = ((AlignViewport) peer).getAlignPanel().alignFrame; + if (linkedAlignFrame.tabbedPane.getTabCount() > index) + { + linkedAlignFrame.tabbedPane.setSelectedIndex(index); + } + } } + /** + * On right mouse click on view tab, prompt for and set new view name. + */ @Override public void tabbedPane_mousePressed(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { - String reply = JOptionPane.showInternalInputDialog(this, - MessageManager.getString("label.enter_view_name"), - MessageManager.getString("label.enter_view_name"), + String msg = MessageManager.getString("label.enter_view_name"); + String reply = JOptionPane.showInternalInputDialog(this, msg, msg, JOptionPane.QUESTION_MESSAGE); if (reply != null) { viewport.viewName = reply; + // TODO warn if reply is in getExistingViewNames()? tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply); } } @@ -5347,7 +5424,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void showDbRefs_actionPerformed(ActionEvent e) { - viewport.setShowDbRefs(showDbRefsMenuitem.isSelected()); + viewport.setShowDBRefs(showDbRefsMenuitem.isSelected()); } /* @@ -5359,7 +5436,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void showNpFeats_actionPerformed(ActionEvent e) { - viewport.setShowNpFeats(showNpFeatsMenuitem.isSelected()); + viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected()); } /** @@ -5368,7 +5445,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * * @param av */ - public boolean closeView(AlignViewport av) + public boolean closeView(AlignViewportI av) { if (viewport == av) { @@ -5514,7 +5591,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } }); - fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{src.getDbName()}))); + fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{src.getDbName()}))); dfetch.add(fetchr); comp++; } @@ -5525,7 +5602,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // fetch all entry DbSourceProxy src = otherdb.get(0); fetchr = new JMenuItem(MessageManager.formatMessage( - "label.fetch_all_param", new String[] + "label.fetch_all_param", new Object[] { src.getDbSource() })); fetchr.addActionListener(new ActionListener() { @@ -5547,11 +5624,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } }); - fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new String[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()}))); + fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new Object[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()}))); dfetch.add(fetchr); comp++; // and then build the rest of the individual menus - ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new String[]{src.getDbSource()})); + ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new Object[]{src.getDbSource()})); icomp = 0; String imname = null; int i = 0; @@ -5564,7 +5641,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, 0, 10) + "..." : dbname; if (imname == null) { - imname = MessageManager.formatMessage("label.from_msname", new String[]{sname}); + imname = MessageManager.formatMessage("label.from_msname", new Object[]{sname}); } fetchr = new JMenuItem(msname); final DbSourceProxy[] dassrc = @@ -5591,7 +5668,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, }); fetchr.setToolTipText("" - + MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{dbname})); + + MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{dbname})); ifetch.add(fetchr); ++i; if (++icomp >= mcomp || i == (otherdb.size())) @@ -5797,7 +5874,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, throw new Error(MessageManager.getString("error.implementation_error_cannot_show_view_alignment_frame")); } if (tabbedPane != null - & alignPanels.indexOf(alignmentPanel) != tabbedPane + && tabbedPane.getTabCount() > 0 + && alignPanels.indexOf(alignmentPanel) != tabbedPane .getSelectedIndex()) { tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel)); @@ -5845,11 +5923,74 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, /** * - * @return alignment panels in this alignemnt frame + * @return alignment panels in this alignment frame + */ + public List getAlignPanels() + { + return alignPanels == null ? Arrays.asList(alignPanel) + : alignPanels; + } + + /** + * Open a new alignment window, with the cDNA associated with this (protein) + * alignment, aligned as is the protein. + */ + protected void viewAsCdna_actionPerformed() + { + // TODO no longer a menu action - refactor as required + final AlignmentI alignment = getViewport().getAlignment(); + Set mappings = alignment.getCodonFrames(); + if (mappings == null) + { + return; + } + List cdnaSeqs = new ArrayList(); + for (SequenceI aaSeq : alignment.getSequences()) { + for (AlignedCodonFrame acf : mappings) { + SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence()); + if (dnaSeq != null) + { + /* + * There is a cDNA mapping for this protein sequence - add to new + * alignment. It will share the same dataset sequence as other mapped + * cDNA (no new mappings need to be created). + */ + final Sequence newSeq = new Sequence(dnaSeq); + newSeq.setDatasetSequence(dnaSeq); + cdnaSeqs.add(newSeq); + } + } + } + if (cdnaSeqs.size() == 0) + { + // show a warning dialog no mapped cDNA + return; + } + AlignmentI cdna = new Alignment(cdnaSeqs.toArray(new SequenceI[cdnaSeqs + .size()])); + AlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + cdna.alignAs(alignment); + String newtitle = "cDNA " + MessageManager.getString("label.for") + " " + + this.title; + Desktop.addInternalFrame(alignFrame, newtitle, + AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + + /** + * Set visibility of dna/protein complement view (available when shown in a + * split frame). + * + * @param show */ - public List getAlignPanels() + @Override + protected void showComplement_actionPerformed(boolean show) { - return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels; + SplitContainerI sf = getSplitViewContainer(); + if (sf != null) { + sf.setComplementVisible(this, show); + } } } diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index 1c105d0..430f373 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -38,11 +38,16 @@ */ package jalview.gui; +import jalview.analysis.AlignmentUtils; +import jalview.analysis.AlignmentUtils.MappingResult; import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.NJTree; import jalview.api.AlignViewportI; +import jalview.api.ViewStyleI; import jalview.bin.Cache; import jalview.commands.CommandI; +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.PDBEntry; @@ -51,21 +56,26 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.UserColourScheme; +import jalview.structure.CommandListener; import jalview.structure.SelectionSource; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; +import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; import jalview.ws.params.AutoCalcSetting; -import java.awt.Color; import java.awt.Container; +import java.awt.Dimension; import java.awt.Font; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Hashtable; -import java.util.Stack; +import java.util.Set; import java.util.Vector; +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; + /** * DOCUMENT ME! * @@ -73,7 +83,7 @@ import java.util.Vector; * @version $Revision: 1.141 $ */ public class AlignViewport extends AlignmentViewport implements - SelectionSource, VamsasSource, AlignViewportI + SelectionSource, AlignViewportI, CommandListener { int startRes; @@ -83,61 +93,29 @@ public class AlignViewport extends AlignmentViewport implements int endSeq; - boolean showJVSuffix = true; - - boolean showText = true; - - boolean showColourText = false; - - boolean showBoxes = true; - - boolean wrapAlignment = false; - - boolean renderGaps = true; SequenceAnnotationOrder sortAnnotationsBy = null; - int charHeight; - - int charWidth; - - boolean validCharWidth; - - int wrappedWidth; - Font font; - boolean seqNameItalics; - NJTree currentTree = null; - boolean scaleAboveWrapped = false; - - boolean scaleLeftWrapped = true; - - boolean scaleRightWrapped = true; - - boolean showHiddenMarkers = true; - boolean cursorMode = false; boolean antiAlias = false; - Rectangle explodedPosition; + private Rectangle explodedGeometry; String viewName; - boolean gatherViewsHere = false; - - Stack historyList = new Stack(); - - Stack redoList = new Stack(); - - int thresholdTextColour = 0; - - Color textColour = Color.black; - - Color textColour2 = Color.white; + /* + * Flag set true on the view that should 'gather' multiple views of the same + * sequence set id when a project is reloaded. Set false on all views when + * they are 'exploded' into separate windows. Set true on the current view + * when 'Gather' is performed, and also on the first tab when the first new + * view is created. + */ + private boolean gatherViewsHere = false; private AnnotationColumnChooser annotationColumnSelectionState; /** @@ -247,32 +225,46 @@ public class AlignViewport extends AlignmentViewport implements init(); } - void init() + private void applyViewProperties() { - this.startRes = 0; - this.endRes = alignment.getWidth() - 1; - this.startSeq = 0; - this.endSeq = alignment.getHeight() - 1; - antiAlias = Cache.getDefault("ANTI_ALIAS", false); - showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true); + viewStyle.setShowJVSuffix(Cache.getDefault("SHOW_JVSUFFIX", true)); setShowAnnotation(Cache.getDefault("SHOW_ANNOTATIONS", true)); setRightAlignIds(Cache.getDefault("RIGHT_ALIGN_IDS", false)); - centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false); + setCentreColumnLabels(Cache.getDefault("CENTRE_COLUMN_LABELS", false)); autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true); setPadGaps(Cache.getDefault("PAD_GAPS", true)); - shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true); - showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP", true); + setShowNPFeats(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true)); + setShowDBRefs(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true)); + viewStyle.setSeqNameItalics(Cache.getDefault("ID_ITALICS", true)); + viewStyle.setWrapAlignment(Cache.getDefault("WRAP_ALIGNMENT", false)); + viewStyle.setShowUnconserved(Cache + .getDefault("SHOW_UNCONSERVED", false)); + sortByTree = Cache.getDefault("SORT_BY_TREE", false); + followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true); + sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault( + Preferences.SORT_ANNOTATIONS, + SequenceAnnotationOrder.NONE.name())); + showAutocalculatedAbove = Cache.getDefault( + Preferences.SHOW_AUTOCALC_ABOVE, false); + + } + + void init() + { + this.startRes = 0; + this.endRes = alignment.getWidth() - 1; + this.startSeq = 0; + this.endSeq = alignment.getHeight() - 1; + applyViewProperties(); String fontName = Cache.getDefault("FONT_NAME", "SansSerif"); String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + ""); String fontSize = Cache.getDefault("FONT_SIZE", "10"); - seqNameItalics = Cache.getDefault("ID_ITALICS", true); - int style = 0; if (fontStyle.equals("bold")) @@ -284,7 +276,7 @@ public class AlignViewport extends AlignmentViewport implements style = 2; } - setFont(new Font(fontName, style, Integer.parseInt(fontSize))); + setFont(new Font(fontName, style, Integer.parseInt(fontSize)), true); alignment .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0)); @@ -309,16 +301,24 @@ public class AlignViewport extends AlignmentViewport implements showConsensus = Cache.getDefault("SHOW_IDENTITY", true); } initAutoAnnotation(); - if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null) + String colourProperty = alignment.isNucleotide() ? Preferences.DEFAULT_COLOUR_NUC + : Preferences.DEFAULT_COLOUR_PROT; + String propertyValue = Cache.getProperty(colourProperty); + if (propertyValue == null) + { + // fall back on this property for backwards compatibility + propertyValue = Cache.getProperty(Preferences.DEFAULT_COLOUR); + } + if (propertyValue != null) { globalColourScheme = ColourSchemeProperty.getColour(alignment, - jalview.bin.Cache.getProperty("DEFAULT_COLOUR")); + propertyValue); if (globalColourScheme instanceof UserColourScheme) { globalColourScheme = UserDefinedColours.loadDefaultColours(); ((UserColourScheme) globalColourScheme).setThreshold(0, - getIgnoreGapsConsensus()); + isIgnoreGapsConsensus()); } if (globalColourScheme != null) @@ -326,31 +326,9 @@ public class AlignViewport extends AlignmentViewport implements globalColourScheme.setConsensus(hconsensus); } } - - wrapAlignment = Cache.getDefault("WRAP_ALIGNMENT", false); - showUnconserved = Cache.getDefault("SHOW_UNCONSERVED", false); - sortByTree = Cache.getDefault("SORT_BY_TREE", false); - followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true); - sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault( - Preferences.SORT_ANNOTATIONS, - SequenceAnnotationOrder.NONE.name())); - showAutocalculatedAbove = Cache.getDefault( - Preferences.SHOW_AUTOCALC_ABOVE, false); } /** - * centre columnar annotation labels in displayed alignment annotation TODO: - * add to jalviewXML and annotation display settings - */ - boolean centreColumnLabels = false; - - private boolean showdbrefs; - - private boolean shownpfeats; - - // --------END Structure Conservation - - /** * get the consensus sequence as displayed under the PID consensus annotation * row. * @@ -494,105 +472,52 @@ public class AlignViewport extends AlignmentViewport implements return endSeq; } + boolean validCharWidth; + /** - * DOCUMENT ME! + * update view settings with the given font. You may need to call + * alignPanel.fontChanged to update the layout geometry * - * @param f - * DOCUMENT ME! + * @param setGrid + * when true, charWidth/height is set according to font mentrics */ - public void setFont(Font f) + public void setFont(Font f, boolean setGrid) { font = f; Container c = new Container(); java.awt.FontMetrics fm = c.getFontMetrics(font); - setCharHeight(fm.getHeight()); - setCharWidth(fm.charWidth('M')); - validCharWidth = true; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public Font getFont() - { - return font; - } - - /** - * DOCUMENT ME! - * - * @param w - * DOCUMENT ME! - */ - public void setCharWidth(int w) - { - this.charWidth = w; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int getCharWidth() - { - return charWidth; - } - - /** - * DOCUMENT ME! - * - * @param h - * DOCUMENT ME! - */ - public void setCharHeight(int h) - { - this.charHeight = h; - } + int w = viewStyle.getCharWidth(), ww = fm.charWidth('M'), h = viewStyle + .getCharHeight(); + if (setGrid) + { + setCharHeight(fm.getHeight()); + setCharWidth(ww); + } + viewStyle.setFontName(font.getName()); + viewStyle.setFontStyle(font.getStyle()); + viewStyle.setFontSize(font.getSize()); - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int getCharHeight() - { - return charHeight; + validCharWidth = true; } - /** - * DOCUMENT ME! - * - * @param w - * DOCUMENT ME! - */ - public void setWrappedWidth(int w) + @Override + public void setViewStyle(ViewStyleI settingsForView) { - this.wrappedWidth = w; - } + super.setViewStyle(settingsForView); + setFont(new Font(viewStyle.getFontName(), viewStyle.getFontStyle(), + viewStyle.getFontSize()), false); - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int getWrappedWidth() - { - return wrappedWidth; } - /** * DOCUMENT ME! * * @return DOCUMENT ME! */ - public AlignmentI getAlignment() + public Font getFont() { - return alignment; + return font; } /** @@ -619,101 +544,6 @@ public class AlignViewport extends AlignmentViewport implements /** * DOCUMENT ME! * - * @param state - * DOCUMENT ME! - */ - public void setWrapAlignment(boolean state) - { - wrapAlignment = state; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setShowText(boolean state) - { - showText = state; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setRenderGaps(boolean state) - { - renderGaps = state; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getColourText() - { - return showColourText; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setColourText(boolean state) - { - showColourText = state; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setShowBoxes(boolean state) - { - showBoxes = state; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getWrapAlignment() - { - return wrapAlignment; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getShowText() - { - return showText; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getShowBoxes() - { - return showBoxes; - } - - /** - * DOCUMENT ME! - * * @return DOCUMENT ME! */ public char getGapCharacter() @@ -767,110 +597,6 @@ public class AlignViewport extends AlignmentViewport implements } /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getShowJVSuffix() - { - return showJVSuffix; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setShowJVSuffix(boolean b) - { - showJVSuffix = b; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getScaleAboveWrapped() - { - return scaleAboveWrapped; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getScaleLeftWrapped() - { - return scaleLeftWrapped; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getScaleRightWrapped() - { - return scaleRightWrapped; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setScaleAboveWrapped(boolean b) - { - scaleAboveWrapped = b; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setScaleLeftWrapped(boolean b) - { - scaleLeftWrapped = b; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setScaleRightWrapped(boolean b) - { - scaleRightWrapped = b; - } - - public void setDataset(boolean b) - { - isDataset = b; - } - - public boolean isDataset() - { - return isDataset; - } - - public boolean getShowHiddenMarkers() - { - return showHiddenMarkers; - } - - public void setShowHiddenMarkers(boolean show) - { - showHiddenMarkers = show; - } - - /** * returns the visible column regions of the alignment * * @param selectedRegionOnly @@ -943,55 +669,6 @@ public class AlignViewport extends AlignmentViewport implements return false; } - public boolean getCentreColumnLabels() - { - return centreColumnLabels; - } - - public void setCentreColumnLabels(boolean centrecolumnlabels) - { - centreColumnLabels = centrecolumnlabels; - } - - /** - * enable or disable the display of Database Cross References in the sequence - * ID tooltip - */ - public void setShowDbRefs(boolean show) - { - showdbrefs = show; - } - - /** - * - * @return true if Database References are to be displayed on tooltips. - */ - public boolean isShowDbRefs() - { - return showdbrefs; - } - - /** - * - * @return true if Non-positional features are to be displayed on tooltips. - */ - public boolean isShowNpFeats() - { - return shownpfeats; - } - - /** - * enable or disable the display of Non-Positional sequence features in the - * sequence ID tooltip - * - * @param show - */ - public void setShowNpFeats(boolean show) - { - shownpfeats = show; - } - - /** * when set, view will scroll to show the highlighted position */ @@ -1018,6 +695,9 @@ public class AlignViewport extends AlignmentViewport implements return followSelection; } + /** + * Send the current selection to be broadcast to any selection listeners. + */ public void sendSelection() { jalview.structure.StructureSelectionManager @@ -1038,7 +718,6 @@ public class AlignViewport extends AlignmentViewport implements { AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this .getSequenceSetId()); - AlignmentPanel ap = null; for (int p = 0; aps != null && p < aps.length; p++) { if (aps[p].av == this) @@ -1092,6 +771,10 @@ public class AlignViewport extends AlignmentViewport implements } } + /** + * Returns the (Desktop) instance of the StructureSelectionManager + */ + @Override public StructureSelectionManager getStructureSelectionManager() { return StructureSelectionManager @@ -1199,6 +882,247 @@ public class AlignViewport extends AlignmentViewport implements this.showAutocalculatedAbove = showAutocalculatedAbove; } + /** + * Method called when another alignment's edit (or possibly other) command is + * broadcast to here. + * + * To allow for sequence mappings (e.g. protein to cDNA), we have to first + * 'unwind' the command on the source sequences (in simulation, not in fact), + * and then for each edit in turn: + *
    + *
  • compute the equivalent edit on the mapped sequences
  • + *
  • apply the mapped edit
  • + *
  • 'apply' the source edit to the working copy of the source sequences
  • + *
+ * + * @param command + * @param undo + * @param ssm + */ + @Override + public void mirrorCommand(CommandI command, boolean undo, + StructureSelectionManager ssm, VamsasSource source) + { + /* + * Do nothing unless we are a 'complement' of the source. May replace this + * with direct calls not via SSM. + */ + if (source instanceof AlignViewportI + && ((AlignViewportI) source).getCodingComplement() == this) + { + // ok to continue; + } + else + { + return; + } + + CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(), + getGapCharacter()); + if (mappedCommand != null) + { + AlignmentI[] views = getAlignPanel().alignFrame.getViewAlignments(); + mappedCommand.doCommand(views); + getAlignPanel().alignmentChanged(); + } + } + + /** + * Add the sequences from the given alignment to this viewport. Optionally, + * may give the user the option to open a new frame, or split panel, with cDNA + * and protein linked. + * + * @param al + * @param title + */ + public void addAlignment(AlignmentI al, String title) + { + // TODO: promote to AlignViewportI? applet CutAndPasteTransfer is different + + // JBPComment: title is a largely redundant parameter at the moment + // JBPComment: this really should be an 'insert/pre/append' controller + // JBPComment: but the DNA/Protein check makes it a bit more complex + + // refactored from FileLoader / CutAndPasteTransfer / SequenceFetcher with + // this comment: + // TODO: create undo object for this JAL-1101 + + /* + * If one alignment is protein and one nucleotide, with at least one + * sequence name in common, offer to open a linked alignment. + */ + if (getAlignment().isNucleotide() != al.isNucleotide()) + { + // TODO: JAL-845 try a bit harder to link up imported sequences + final Set sequenceNames = getAlignment().getSequenceNames(); + sequenceNames.retainAll(al.getSequenceNames()); + if (!sequenceNames.isEmpty()) // at least one sequence name in both + { + if (openLinkedAlignment(al, title)) + { + return; + } + } + } + // TODO: JAL-407 regardless of above - identical sequences (based on ID and + // provenance) should share the same dataset sequence + + for (int i = 0; i < al.getHeight(); i++) + { + getAlignment().addSequence(al.getSequenceAt(i)); + } + // TODO this call was done by SequenceFetcher but not FileLoader or + // CutAndPasteTransfer. Is it needed? + // JBPComment: this repositions the view to show the new sequences + // JBPComment: so it is needed for UX + setEndSeq(getAlignment().getHeight()); + firePropertyChange("alignment", null, getAlignment().getSequences()); + } + + /** + * Show a dialog with the option to open and link (cDNA <-> protein) as a new + * alignment. Returns true if the new alignment was opened, false if not, + * because the user declined the offer. + * + * @param title + */ + protected boolean openLinkedAlignment(AlignmentI al, String title) + { + String[] options = new String[] + { MessageManager.getString("action.no"), + MessageManager.getString("label.split_window"), + MessageManager.getString("label.new_window"), }; + final String question = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.open_split_window?")); + int response = JOptionPane.showOptionDialog(Desktop.desktop, question, + MessageManager.getString("label.open_split_window"), + JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, + options, options[0]); + + if (response != 1 && response != 2) + { + return false; + } + final boolean openSplitPane = (response == 1); + final boolean openInNewWindow = (response == 2); + + /* + * Create the AlignFrame first (which creates the new alignment's datasets), + * before attempting sequence mapping. + */ + AlignFrame newAlignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + newAlignFrame.setTitle(title); + + /* + * Identify protein and dna alignments. Make a copy of this one if opening + * in a new split pane. + */ + AlignmentI thisAlignment = openSplitPane ? new Alignment(getAlignment()) + : getAlignment(); + AlignmentI protein = al.isNucleotide() ? thisAlignment : al; + final AlignmentI cdna = al.isNucleotide() ? al : thisAlignment; + + newAlignFrame.statusBar.setText(MessageManager.formatMessage( + "label.successfully_loaded_file", new Object[] + { title })); + + // TODO if we want this (e.g. to enable reload of the alignment from file), + // we will need to add parameters to the stack. + // if (!protocol.equals(AppletFormatAdapter.PASTE)) + // { + // alignFrame.setFileName(file, format); + // } + + if (openInNewWindow) + { + Desktop.addInternalFrame(newAlignFrame, title, + AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + + /* + * Try to find mappings for at least one sequence. Any mappings made will be + * added to the protein alignment. + */ + MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna); + if (mapped != MappingResult.Mapped) + { + /* + * No mapping possible - warn the user, but leave window open. + */ + final String msg = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.mapping_failed")); + JOptionPane.showInternalMessageDialog(Desktop.desktop, msg, + MessageManager.getString("label.no_mappings"), + JOptionPane.WARNING_MESSAGE); + } + + try + { + newAlignFrame.setMaximum(jalview.bin.Cache.getDefault( + "SHOW_FULLSCREEN", + false)); + } catch (java.beans.PropertyVetoException ex) + { + } + + if (openSplitPane) + { + protein = openSplitFrame(newAlignFrame, thisAlignment, + protein.getCodonFrames()); + } + + /* + * Register the mappings (held on the protein alignment) with the + * StructureSelectionManager (for mouseover linking). + */ + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addMappings(protein.getCodonFrames()); + + return true; + } + + /** + * Helper method to open a new SplitFrame holding linked dna and protein + * alignments. + * + * @param newAlignFrame + * containing a new alignment to be shown + * @param complement + * cdna/protein complement alignment to show in the other split half + * @param mappings + * @return the protein alignment in the split frame + */ + protected AlignmentI openSplitFrame(AlignFrame newAlignFrame, + AlignmentI complement, Set mappings) + { + /* + * Open in split pane. DNA sequence above, protein below. + */ + AlignFrame copyMe = new AlignFrame(complement, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + copyMe.setTitle(getAlignPanel().alignFrame.getTitle()); + + AlignmentI al = newAlignFrame.viewport.getAlignment(); + final AlignFrame proteinFrame = al.isNucleotide() ? copyMe + : newAlignFrame; + final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame + : copyMe; + AlignmentI protein = proteinFrame.viewport.getAlignment(); + protein.setCodonFrames(mappings); + + cdnaFrame.setVisible(true); + proteinFrame.setVisible(true); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame); + Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1); + + return protein; + } + public AnnotationColumnChooser getAnnotationColumnSelectionState() { return annotationColumnSelectionState; @@ -1209,4 +1133,39 @@ public class AlignViewport extends AlignmentViewport implements { this.annotationColumnSelectionState = currentAnnotationColumnSelectionState; } + + @Override + public void setIdWidth(int i) + { + super.setIdWidth(i); + AlignmentPanel ap = getAlignPanel(); + if (ap != null) + { + // modify GUI elements to reflect geometry change + Dimension idw = getAlignPanel().getIdPanel().getIdCanvas() + .getPreferredSize(); + idw.width = i; + getAlignPanel().getIdPanel().getIdCanvas().setPreferredSize(idw); + } + } + + public Rectangle getExplodedGeometry() + { + return explodedGeometry; + } + + public void setExplodedGeometry(Rectangle explodedPosition) + { + this.explodedGeometry = explodedPosition; + } + + public boolean isGatherViewsHere() + { + return gatherViewsHere; + } + + public void setGatherViewsHere(boolean gatherViewsHere) + { + this.gatherViewsHere = gatherViewsHere; + } } diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 6517e70..ccbc031 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -21,6 +21,7 @@ package jalview.gui; import jalview.analysis.AnnotationSorter; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.datamodel.AlignmentI; @@ -94,9 +95,7 @@ public class AlignmentPanel extends GAlignmentPanel implements * Creates a new AlignmentPanel object. * * @param af - * DOCUMENT ME! * @param av - * DOCUMENT ME! */ public AlignmentPanel(AlignFrame af, final AlignViewport av) { @@ -122,8 +121,6 @@ public class AlignmentPanel extends GAlignmentPanel implements setScrollValues(0, 0); - setAnnotationVisible(av.isShowAnnotation()); - hscroll.addAdjustmentListener(this); vscroll.addAdjustmentListener(this); @@ -141,9 +138,14 @@ public class AlignmentPanel extends GAlignmentPanel implements }); fontChanged(); adjustAnnotationHeight(); - + updateLayout(); } + @Override + public AlignViewportI getAlignViewport() + { + return av; + } public void alignmentChanged() { av.alignmentChanged(this); @@ -163,9 +165,10 @@ public class AlignmentPanel extends GAlignmentPanel implements // to prevent drawing old image FontMetrics fm = getFontMetrics(av.getFont()); - scalePanelHolder.setPreferredSize(new Dimension(10, av.charHeight + scalePanelHolder.setPreferredSize(new Dimension(10, av.getCharHeight() + fm.getDescent())); - idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av.charHeight + idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av + .getCharHeight() + fm.getDescent())); getIdPanel().getIdCanvas().gg = null; @@ -173,6 +176,7 @@ public class AlignmentPanel extends GAlignmentPanel implements getAnnotationPanel().adjustPanelHeight(); Dimension d = calculateIdWidth(); + d.setSize(d.width + 4, d.height); getIdPanel().getIdCanvas().setPreferredSize(d); hscrollFillerPanel.setPreferredSize(d); @@ -195,11 +199,21 @@ public class AlignmentPanel extends GAlignmentPanel implements public Dimension calculateIdWidth() { // calculate sensible default width when no preference is available - - int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); - int maxwidth = Math.max(20, - Math.min(afwidth - 200, 2 * afwidth / 3)); - return calculateIdWidth(maxwidth); + Dimension r = null; + if (av.getIdWidth() < 0) + { + int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); + int maxwidth = Math.max(20, Math.min(afwidth - 200, 2 * afwidth / 3)); + r = calculateIdWidth(maxwidth); + av.setIdWidth(r.width); + } + else + { + r = new Dimension(); + r.width = av.getIdWidth(); + r.height = 0; + } + return r; } /** @@ -339,7 +353,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } } } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { if ((startv = av.getStartRes()) >= start) { @@ -412,7 +426,7 @@ public class AlignmentPanel extends GAlignmentPanel implements */ public void setAnnotationVisible(boolean b) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { annotationSpaceFillerHolder.setVisible(b); annotationScroller.setVisible(b); @@ -488,13 +502,16 @@ public class AlignmentPanel extends GAlignmentPanel implements } /** - * DOCUMENT ME! + * update alignment layout for viewport settings * * @param wrap * DOCUMENT ME! */ - public void setWrapAlignment(boolean wrap) + public void updateLayout() { + fontChanged(); + setAnnotationVisible(av.isShowAnnotation()); + boolean wrap = av.getWrapAlignment(); av.startSeq = 0; scalePanelHolder.setVisible(!wrap); hscroll.setVisible(!wrap); @@ -605,10 +622,11 @@ public class AlignmentPanel extends GAlignmentPanel implements width = av.getColumnSelection().findColumnPosition(width); } - av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av.charWidth)) - 1); + av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av + .getCharWidth())) - 1); - hextent = getSeqPanel().seqCanvas.getWidth() / av.charWidth; - vextent = getSeqPanel().seqCanvas.getHeight() / av.charHeight; + hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth(); + vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight(); if (hextent > width) { @@ -652,7 +670,6 @@ public class AlignmentPanel extends GAlignmentPanel implements */ public void adjustmentValueChanged(AdjustmentEvent evt) { - int oldX = av.getStartRes(); int oldY = av.getStartSeq(); @@ -859,7 +876,7 @@ public class AlignmentPanel extends GAlignmentPanel implements { int idWidth = getVisibleIdWidth(false); FontMetrics fm = getFontMetrics(av.getFont()); - int scaleHeight = av.charHeight + fm.getDescent(); + int scaleHeight = av.getCharHeight() + fm.getDescent(); pg.setColor(Color.white); pg.fillRect(0, 0, pwidth, pheight); @@ -949,7 +966,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } pg.setColor(currentColor); - pg.fillRect(0, (i - startSeq) * av.charHeight, idWidth, + pg.fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth, av.getCharHeight()); pg.setColor(currentTextColor); @@ -966,7 +983,7 @@ public class AlignmentPanel extends GAlignmentPanel implements pg.drawString( seq.getDisplayId(av.getShowJVSuffix()), xPos, - (((i - startSeq) * av.charHeight) + av.getCharHeight()) + (((i - startSeq) * av.getCharHeight()) + av.getCharHeight()) - (av.getCharHeight() / 5)); } @@ -981,7 +998,8 @@ public class AlignmentPanel extends GAlignmentPanel implements // draw annotation - need to offset for current scroll position int offset = -getAlabels().getScrollOffset(); pg.translate(0, offset); - pg.translate(-idWidth - 3, (endSeq - startSeq) * av.charHeight + 3); + pg.translate(-idWidth - 3, (endSeq - startSeq) * av.getCharHeight() + + 3); getAlabels().drawComponent(pg, idWidth); pg.translate(idWidth + 3, 0); getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av, @@ -1012,7 +1030,6 @@ public class AlignmentPanel extends GAlignmentPanel implements public int printWrappedAlignment(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException { - int annotationHeight = 0; AnnotationLabels labels = null; if (av.isShowAnnotation()) @@ -1021,13 +1038,13 @@ public class AlignmentPanel extends GAlignmentPanel implements labels = new AnnotationLabels(av); } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + hgap + annotationHeight; int idWidth = getVisibleIdWidth(false); @@ -1071,18 +1088,19 @@ public class AlignmentPanel extends GAlignmentPanel implements xPos = idWidth - fm.stringWidth(string) - 4; } pg.drawString(string, xPos, - ((i * av.charHeight) + ypos + av.charHeight) - - (av.charHeight / 5)); + ((i * av.getCharHeight()) + ypos + av.getCharHeight()) + - (av.getCharHeight() / 5)); } if (labels != null) { pg.translate(-3, ypos - + (av.getAlignment().getHeight() * av.charHeight)); + + (av.getAlignment().getHeight() * av.getCharHeight())); pg.setFont(av.getFont()); labels.drawComponent(pg, idWidth); pg.translate(+3, -ypos - - (av.getAlignment().getHeight() * av.charHeight)); + - (av.getAlignment().getHeight() * av + .getCharHeight())); } ypos += cHeight; @@ -1149,8 +1167,7 @@ public class AlignmentPanel extends GAlignmentPanel implements if (alignFrame != null && !headless) { alignFrame.setProgressBar(MessageManager.formatMessage( - "status.saving_file", - new String[] + "status.saving_file", new Object[] { type.getLabel() }), progress); } try @@ -1225,9 +1242,9 @@ public class AlignmentPanel extends GAlignmentPanel implements maxwidth = av.getColumnSelection().findColumnPosition(maxwidth); } - int height = ((av.getAlignment().getHeight() + 1) * av.charHeight) + int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight()) + getScalePanel().getHeight(); - int width = getVisibleIdWidth(false) + (maxwidth * av.charWidth); + int width = getVisibleIdWidth(false) + (maxwidth * av.getCharWidth()); if (av.getWrapAlignment()) { @@ -1283,7 +1300,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // //////////////////////////////////////////// int idWidth = getVisibleIdWidth(false); FontMetrics fm = getFontMetrics(av.getFont()); - int scaleHeight = av.charHeight + fm.getDescent(); + int scaleHeight = av.getCharHeight() + fm.getDescent(); // Gen image map // //////////////////////////////// @@ -1302,7 +1319,7 @@ public class AlignmentPanel extends GAlignmentPanel implements for (s = 0; s < sSize; s++) { - sy = s * av.charHeight + scaleHeight; + sy = s * av.getCharHeight() + scaleHeight; SequenceI seq = av.getAlignment().getSequenceAt(s); SequenceFeature[] features = seq.getDatasetSequence() @@ -1311,24 +1328,24 @@ public class AlignmentPanel extends GAlignmentPanel implements for (res = 0; res < alwidth; res++) { text = new StringBuffer(); - Object obj = null; + String triplet = null; if (av.getAlignment().isNucleotide()) { - obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res) + triplet = ResidueProperties.nucleotideName.get(seq + .getCharAt(res) + ""); } else { - obj = ResidueProperties.aa2Triplet.get(seq.getCharAt(res) + triplet = ResidueProperties.aa2Triplet.get(seq.getCharAt(res) + ""); } - if (obj == null) + if (triplet == null) { continue; } - String triplet = obj.toString(); int alIndex = seq.findPosition(res); gSize = groups.length; for (g = 0; g < gSize; g++) @@ -1336,9 +1353,10 @@ public class AlignmentPanel extends GAlignmentPanel implements if (text.length() < 1) { text.append(" 20) { @@ -683,10 +683,10 @@ public class AnnotationLabels extends JPanel implements MouseListener, pop.addSeparator(); // av and sequencegroup need to implement same interface for final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem( - MessageManager.getString("label.ignore_gaps_consensus"), + MessageManager.getString("label.ignore_gaps_consensus"), (aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef .getIgnoreGapsConsensus() : ap.av - .getIgnoreGapsConsensus()); + .isIgnoreGapsConsensus()); final AlignmentAnnotation aaa = aa[selectedRow]; cbmi.addActionListener(new ActionListener() { @@ -709,7 +709,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, if (aaa.groupRef != null) { final JCheckBoxMenuItem chist = new JCheckBoxMenuItem( - MessageManager.getString("label.show_group_histogram"), + MessageManager.getString("label.show_group_histogram"), aa[selectedRow].groupRef.isShowConsensusHistogram()); chist.addActionListener(new ActionListener() { @@ -728,7 +728,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(chist); final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem( - MessageManager.getString("label.show_group_logo"), + MessageManager.getString("label.show_group_logo"), aa[selectedRow].groupRef.isShowSequenceLogo()); cprofl.addActionListener(new ActionListener() { @@ -747,7 +747,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(cprofl); final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem( - MessageManager.getString("label.normalise_group_logo"), + MessageManager.getString("label.normalise_group_logo"), aa[selectedRow].groupRef.isNormaliseSequenceLogo()); cproflnorm.addActionListener(new ActionListener() { @@ -772,7 +772,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, else { final JCheckBoxMenuItem chist = new JCheckBoxMenuItem( - MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram()); + MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram()); chist.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -791,7 +791,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(chist); final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem( - MessageManager.getString("label.show_logo"), av.isShowSequenceLogo()); + MessageManager.getString("label.show_logo"), av.isShowSequenceLogo()); cprof.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -810,7 +810,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(cprof); final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem( - MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo()); + MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo()); cprofnorm.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -1122,7 +1122,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, dragEvent.getY() - getScrollOffset()); } - if (!av.wrapAlignment && ((aa == null) || (aa.length < 1))) + if (!av.getWrapAlignment() && ((aa == null) || (aa.length < 1))) { g.drawString(MessageManager.getString("label.right_click"), 2, 8); g.drawString(MessageManager.getString("label.to_add_annotation"), 2, diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java index 3a97f96..8733459 100755 --- a/src/jalview/gui/AnnotationPanel.java +++ b/src/jalview/gui/AnnotationPanel.java @@ -757,10 +757,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, public void drawCursor(Graphics graphics, SequenceI seq, int res, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.charWidth, av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); if (av.validCharWidth) { @@ -768,9 +768,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, char s = seq.getCharAt(res); - charOffset = (av.charWidth - fm.charWidth(s)) / 2; + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; graphics.drawString(String.valueOf(s), charOffset + x1, - (y1 + av.charHeight) - pady); + (y1 + av.getCharHeight()) - pady); } } @@ -799,7 +799,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, return; } } - imgWidth = (av.endRes - av.startRes + 1) * av.charWidth; + imgWidth = (av.endRes - av.startRes + 1) * av.getCharWidth(); if (imgWidth < 1) { return; @@ -867,7 +867,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, return; } long stime = System.currentTimeMillis(); - gg.copyArea(0, 0, imgWidth, getHeight(), -horizontal * av.charWidth, 0); + gg.copyArea(0, 0, imgWidth, getHeight(), + -horizontal * av.getCharWidth(), 0); long mtime = System.currentTimeMillis(); int sr = av.startRes; int er = av.endRes + 1; @@ -875,7 +876,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, if (horizontal > 0) // scrollbar pulled right, image to the left { - transX = (er - sr - horizontal) * av.charWidth; + transX = (er - sr - horizontal) * av.getCharWidth(); sr = er - horizontal; } else if (horizontal < 0) @@ -960,7 +961,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, } g.setColor(Color.white); - g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getHeight()); + g.fillRect(0, 0, (endRes - startRes) * av.getCharWidth(), getHeight()); g.setFont(av.getFont()); if (fm == null) diff --git a/src/jalview/gui/AppVarnaBinding.java b/src/jalview/gui/AppVarnaBinding.java index a738a2c..03799e1 100644 --- a/src/jalview/gui/AppVarnaBinding.java +++ b/src/jalview/gui/AppVarnaBinding.java @@ -20,6 +20,7 @@ */ package jalview.gui; +import jalview.structure.AtomSpec; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -827,8 +828,6 @@ public class AppVarnaBinding extends jalview.ext.varna.JalviewVarnaBinding public void onWarningEmitted(String s) { - // TODO Auto-generated method stub - } public void mouseClicked(MouseEvent e) @@ -852,127 +851,73 @@ public class AppVarnaBinding extends jalview.ext.varna.JalviewVarnaBinding public void mouseEntered(MouseEvent arg0) { - // TODO Auto-generated method stub - } public void mouseExited(MouseEvent arg0) { - // TODO Auto-generated method stub - } public void mousePressed(MouseEvent arg0) { - // TODO Auto-generated method stub - } public void mouseReleased(MouseEvent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public Color getColour(int atomIndex, int pdbResNum, String chain, - String pdbId) - { - // TODO Auto-generated method stub - return null; } @Override public String[] getPdbFile() { - // TODO Auto-generated method stub return null; } @Override - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbId) - { - // TODO Auto-generated method stub - - } - - @Override - public void mouseOverStructure(int atomIndex, String strInfo) - { - // TODO Auto-generated method stub - - } - - @Override public void releaseReferences(Object svl) { - // TODO Auto-generated method stub - } @Override public void updateColours(Object source) { - // TODO Auto-generated method stub - } @Override public void componentHidden(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void componentMoved(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void componentResized(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void componentShown(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void onStructureRedrawn() { - // TODO Auto-generated method stub - } @Override public void onZoomLevelChanged() { - // TODO Auto-generated method stub - } @Override public void onTranslationChanged() { - // TODO Auto-generated method stub + } + @Override + public void highlightAtoms(List atoms) + { } } - -/* - * public static void main(String[] args) { JTextField str = new - * JTextField("ATGC"); - * - * AppVarnaBinding vab = new AppVarnaBinding(); vab.varnagui.set_seq(str); - * vab.varnagui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - * vab.varnagui.pack(); vab.varnagui.setVisible(true); } } - */ diff --git a/src/jalview/gui/CutAndPasteHtmlTransfer.java b/src/jalview/gui/CutAndPasteHtmlTransfer.java index 7fd091f..40a02f8 100644 --- a/src/jalview/gui/CutAndPasteHtmlTransfer.java +++ b/src/jalview/gui/CutAndPasteHtmlTransfer.java @@ -33,6 +33,7 @@ import javax.swing.event.HyperlinkEvent.EventType; import jalview.io.*; import jalview.jbgui.*; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; /** * Cut'n'paste files into the desktop See JAL-1105 @@ -43,7 +44,7 @@ import jalview.util.MessageManager; public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer { - AlignViewport viewport; + AlignmentViewport viewport; public CutAndPasteHtmlTransfer() { @@ -102,7 +103,7 @@ public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer /** * DOCUMENT ME! */ - public void setForInput(AlignViewport viewport) + public void setForInput(AlignmentViewport viewport) { this.viewport = viewport; if (viewport != null) diff --git a/src/jalview/gui/CutAndPasteTransfer.java b/src/jalview/gui/CutAndPasteTransfer.java index 0c22b14..6705f42 100644 --- a/src/jalview/gui/CutAndPasteTransfer.java +++ b/src/jalview/gui/CutAndPasteTransfer.java @@ -20,16 +20,28 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.event.*; -import javax.swing.*; - -import jalview.datamodel.*; -import jalview.io.*; -import jalview.jbgui.*; +import jalview.datamodel.Alignment; +import jalview.io.FormatAdapter; +import jalview.io.IdentifyFile; +import jalview.io.JalviewFileChooser; +import jalview.io.JalviewFileView; +import jalview.jbgui.GCutAndPasteTransfer; import jalview.util.MessageManager; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; + +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; + /** * Cut'n'paste files into the desktop See JAL-1105 * @@ -190,24 +202,19 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer if (al != null) { + String title = MessageManager.formatMessage( + "label.input_cut_paste_params", new String[] + { format }); if (viewport != null) { - for (int i = 0; i < al.getHeight(); i++) - { - viewport.getAlignment().addSequence(al.getSequenceAt(i)); - } - - viewport.firePropertyChange("alignment", null, viewport - .getAlignment().getSequences()); + viewport.addAlignment(al, title); } else { AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); af.currentFileFormat = format; - Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.input_cut_paste_params", new String[] - { format }), AlignFrame.DEFAULT_WIDTH, + Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); af.statusBar.setText(MessageManager .getString("label.successfully_pasted_alignment_file")); diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 70c8355..393818b 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -20,16 +20,20 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.io.FileLoader; import jalview.io.FormatAdapter; import jalview.io.IdentifyFile; import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; +import jalview.jbgui.GSplitFrame; import jalview.jbgui.GStructureViewer; import jalview.structure.StructureSelectionManager; import jalview.util.ImageMaker; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.params.ParamManager; import java.awt.BorderLayout; @@ -69,6 +73,7 @@ import java.lang.reflect.Constructor; import java.net.URL; import java.util.ArrayList; import java.util.Hashtable; +import java.util.List; import java.util.StringTokenizer; import java.util.Vector; import java.util.concurrent.ExecutorService; @@ -162,6 +167,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements static final int yOffset = 30; + private static final int THREE = 3; + public static jalview.ws.jws1.Discoverer discoverer; public static Object[] jalviewClipboard; @@ -330,8 +337,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements + jalview.bin.Cache.getProperty("VERSION") + "\n" + "Jalview Installation: " + jalview.bin.Cache.getDefault("INSTALLATION", "unknown") - + "\n" - + "Build Date: " + + "\n" + "Build Date: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n" + "Java version: " + System.getProperty("java.version") + "\n" + System.getProperty("os.arch") + " " @@ -432,9 +438,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements { ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault( Preferences.ADD_TEMPFACT_ANN, true)); - ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true)); - ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW, - true)); + ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault( + Preferences.STRUCT_FROM_PDB, true)); + ssm.setSecStructServices(jalview.bin.Cache.getDefault( + Preferences.USE_RNAVIEW, true)); } else { @@ -480,7 +487,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements public void run() { long instance = System.currentTimeMillis(); - Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance); + Desktop.instance.setProgressBar( + MessageManager.getString("status.refreshing_news"), + instance); jvnews.refreshNews(); Desktop.instance.setProgressBar(null, instance); jvnews.showNews(); @@ -648,7 +657,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements addInternalFrame(frame, title, true, w, h, true); } - /** * Add an internal frame to the Jalview desktop * @@ -1087,7 +1095,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements if (format.equals("URL NOT FOUND")) { JOptionPane.showInternalMessageDialog(Desktop.desktop, - MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"), + MessageManager.formatMessage("label.couldnt_locate", + new Object[] + { url }), MessageManager + .getString("label.url_not_found"), JOptionPane.WARNING_MESSAGE); return; @@ -1190,8 +1201,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements if (shortv) { message.append("

Version: " - + jalview.bin.Cache.getProperty("VERSION") - + "

"); + + jalview.bin.Cache.getProperty("VERSION") + ""); message.append("Last Updated: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + ""); @@ -1237,8 +1247,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements } message.append("
Authors: " + jalview.bin.Cache - .getDefault( - "AUTHORFNAMES", + .getDefault("AUTHORFNAMES", "The Jalview Authors (See AUTHORS file for current list)") + "

Development managed by The Barton Group, University of Dundee, Scotland, UK.
" + "

For help, see the FAQ at www.jalview.org/faq and/or join the jalview-discuss@jalview.org mailing list" @@ -1363,7 +1372,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements return; } - AlignViewport source = null, target = null; + AlignmentViewport source = null, target = null; if (frames[0] instanceof AlignFrame) { source = ((AlignFrame) frames[0]).getCurrentView(); @@ -1475,8 +1484,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements public void run() { - setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}), - choice.hashCode()); + setProgressBar(MessageManager.formatMessage( + "label.saving_jalview_project", new Object[] + { choice.getName() }), choice.hashCode()); jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent()); // TODO catch and handle errors for savestate @@ -1493,10 +1503,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements Cache.log.error( "Problems whilst trying to save to " + choice.getName(), ex); - JOptionPane.showMessageDialog( - me, - MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}), - MessageManager.getString("label.couldnt_save_project"), + JOptionPane.showMessageDialog(me, MessageManager.formatMessage( + "label.error_whilst_saving_current_state_to", + new Object[] + { choice.getName() }), MessageManager + .getString("label.couldnt_save_project"), JOptionPane.WARNING_MESSAGE); } setProgressBar(null, choice.hashCode()); @@ -1564,13 +1575,15 @@ public class Desktop extends jalview.jbgui.GDesktop implements final File selectedFile = chooser.getSelectedFile(); setProjectFile(selectedFile); final String choice = selectedFile.getAbsolutePath(); - jalview.bin.Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent()); + jalview.bin.Cache.setProperty("LAST_DIRECTORY", + selectedFile.getParent()); new Thread(new Runnable() { public void run() { - setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}), - choice.hashCode()); + setProgressBar(MessageManager.formatMessage( + "label.loading_jalview_project", new Object[] + { choice }), choice.hashCode()); try { new Jalview2XML().loadJalviewAlign(choice); @@ -1581,9 +1594,13 @@ public class Desktop extends jalview.jbgui.GDesktop implements { Cache.log.error("Problems whilst loading project from " + choice, ex); - JOptionPane.showMessageDialog(Desktop.desktop, - MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}), - MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE); + JOptionPane.showMessageDialog(Desktop.desktop, MessageManager + .formatMessage( + "label.error_whilst_loading_project_from", + new Object[] + { choice }), MessageManager + .getString("label.couldnt_load_project"), + JOptionPane.WARNING_MESSAGE); } setProgressBar(null, choice.hashCode()); } @@ -1604,7 +1621,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements { if (fileLoadingCount == 0) { - fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName}))); + fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage( + "label.loading_file", new Object[] + { fileName }))); } fileLoadingCount++; } @@ -1670,38 +1689,37 @@ public class Desktop extends jalview.jbgui.GDesktop implements public static int getViewCount(String alignmentId) { - AlignViewport[] aps = getViewports(alignmentId); + AlignmentViewport[] aps = getViewports(alignmentId); return (aps == null) ? 0 : aps.length; } /** * * @param alignmentId + * - if null, all sets are returned * @return all AlignmentPanels concerning the alignmentId sequence set */ public static AlignmentPanel[] getAlignmentPanels(String alignmentId) { - int count = 0; if (Desktop.desktop == null) { // no frames created and in headless mode // TODO: verify that frames are recoverable when in headless mode return null; } - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); - ArrayList aps = new ArrayList(); - for (int t = 0; t < frames.length; t++) + List aps = new ArrayList(); + AlignFrame[] frames = getAlignFrames(); + if (frames == null) { - if (frames[t] instanceof AlignFrame) + return null; + } + for (AlignFrame af : frames) + { + for (AlignmentPanel ap : af.alignPanels) { - AlignFrame af = (AlignFrame) frames[t]; - for (int a = 0; a < af.alignPanels.size(); a++) + if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId())) { - if (alignmentId.equals(((AlignmentPanel) af.alignPanels - .elementAt(a)).av.getSequenceSetId())) - { - aps.add(af.alignPanels.elementAt(a)); - } + aps.add(ap); } } } @@ -1709,11 +1727,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements { return null; } - AlignmentPanel[] vap = new AlignmentPanel[aps.size()]; - for (int t = 0; t < vap.length; t++) - { - vap[t] = (AlignmentPanel) aps.get(t); - } + AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]); return vap; } @@ -1721,52 +1735,51 @@ public class Desktop extends jalview.jbgui.GDesktop implements * get all the viewports on an alignment. * * @param sequenceSetId - * unique alignment id + * unique alignment id (may be null - all viewports returned in that + * case) * @return all viewports on the alignment bound to sequenceSetId */ - public static AlignViewport[] getViewports(String sequenceSetId) + public static AlignmentViewport[] getViewports(String sequenceSetId) { - Vector viewp = new Vector(); + List viewp = new ArrayList(); if (desktop != null) { - javax.swing.JInternalFrame[] frames = instance.getAllFrames(); + AlignFrame[] frames = Desktop.getAlignFrames(); - for (int t = 0; t < frames.length; t++) + for (AlignFrame afr : frames) { - if (frames[t] instanceof AlignFrame) + if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId)) { - AlignFrame afr = ((AlignFrame) frames[t]); - if (afr.getViewport().getSequenceSetId().equals(sequenceSetId)) + if (afr.alignPanels != null) { - if (afr.alignPanels != null) + for (AlignmentPanel ap : afr.alignPanels) { - for (int a = 0; a < afr.alignPanels.size(); a++) + if (sequenceSetId == null + || sequenceSetId.equals(ap.av.getSequenceSetId())) { - if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels - .elementAt(a)).av.getSequenceSetId())) - { - viewp.addElement(((AlignmentPanel) afr.alignPanels - .elementAt(a)).av); - } + viewp.add(ap.av); } } - else - { - viewp.addElement(((AlignFrame) frames[t]).getViewport()); - } + } + else + { + viewp.add(afr.getViewport()); } } } if (viewp.size() > 0) { - AlignViewport[] vp = new AlignViewport[viewp.size()]; - viewp.copyInto(vp); - return vp; + return viewp.toArray(new AlignmentViewport[viewp.size()]); } } return null; } + /** + * Explode the views in the given frame into separate AlignFrame + * + * @param af + */ public void explodeViews(AlignFrame af) { int size = af.alignPanels.size(); @@ -1777,15 +1790,21 @@ public class Desktop extends jalview.jbgui.GDesktop implements for (int i = 0; i < size; i++) { - AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i); + AlignmentPanel ap = af.alignPanels.get(i); AlignFrame newaf = new AlignFrame(ap); - if (ap.av.explodedPosition != null - && !ap.av.explodedPosition.equals(af.getBounds())) + + /* + * Restore the view's last exploded frame geometry if known. Multiple + * views from one exploded frame share and restore the same (frame) + * position and size. + */ + Rectangle geometry = ap.av.getExplodedGeometry(); + if (geometry != null) { - newaf.setBounds(ap.av.explodedPosition); + newaf.setBounds(geometry); } - ap.av.gatherViewsHere = false; + ap.av.setGatherViewsHere(false); addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); @@ -1796,10 +1815,18 @@ public class Desktop extends jalview.jbgui.GDesktop implements } + /** + * Gather expanded views (separate AlignFrame's) with the same sequence set + * identifier back in to this frame as additional views, and close the + * expanded views. Note the expanded frames may themselves have multiple + * views. We take the lot. + * + * @param source + */ public void gatherViews(AlignFrame source) { - source.viewport.gatherViewsHere = true; - source.viewport.explodedPosition = source.getBounds(); + source.viewport.setGatherViewsHere(true); + source.viewport.setExplodedGeometry(source.getBounds()); JInternalFrame[] frames = desktop.getAllFrames(); String viewId = source.viewport.getSequenceSetId(); @@ -1811,12 +1838,12 @@ public class Desktop extends jalview.jbgui.GDesktop implements boolean gatherThis = false; for (int a = 0; a < af.alignPanels.size(); a++) { - AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a); + AlignmentPanel ap = af.alignPanels.get(a); if (viewId.equals(ap.av.getSequenceSetId())) { gatherThis = true; - ap.av.gatherViewsHere = false; - ap.av.explodedPosition = af.getBounds(); + ap.av.setGatherViewsHere(false); + ap.av.setExplodedGeometry(af.getBounds()); source.addAlignmentPanel(ap, false); } } @@ -1842,7 +1869,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements jalview.bin.Cache.getProperty("LAST_DIRECTORY")); chooser.setFileView(new JalviewFileView()); - chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session")); + chooser.setDialogTitle(MessageManager + .getString("label.open_saved_vamsas_session")); chooser.setToolTipText(MessageManager .getString("label.select_vamsas_session_opened_as_new_vamsas_session")); @@ -1858,7 +1886,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements Desktop.desktop, MessageManager.formatMessage( "label.couldnt_import_as_vamsas_session", - new String[] + new Object[] { fle }), MessageManager .getString("label.vamsas_document_import_failed"), @@ -1935,23 +1963,26 @@ public class Desktop extends jalview.jbgui.GDesktop implements return false; } - setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}), - file.hashCode()); + setProgressBar(MessageManager.formatMessage( + "status.importing_vamsas_session_from", new Object[] + { file.getName() }), file.hashCode()); try { v_client = new jalview.gui.VamsasApplication(this, file, null); } catch (Exception ex) { - setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}), - file.hashCode()); + setProgressBar(MessageManager.formatMessage( + "status.importing_vamsas_session_from", new Object[] + { file.getName() }), file.hashCode()); jalview.bin.Cache.log.error( "New vamsas session from existing session file failed:", ex); return false; } setupVamsasConnectedGui(); v_client.initial_update(); // TODO: thread ? - setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}), - file.hashCode()); + setProgressBar(MessageManager.formatMessage( + "status.importing_vamsas_session_from", new Object[] + { file.getName() }), file.hashCode()); return v_client.inSession(); } @@ -1959,11 +1990,14 @@ public class Desktop extends jalview.jbgui.GDesktop implements { if (v_client != null) { - throw new Error(MessageManager.getString("error.try_join_vamsas_session_another")); + throw new Error( + MessageManager + .getString("error.try_join_vamsas_session_another")); } if (mysesid == null) { - throw new Error(MessageManager.getString("error.invalid_vamsas_session_id")); + throw new Error( + MessageManager.getString("error.invalid_vamsas_session_id")); } v_client = new VamsasApplication(this, mysesid); setupVamsasConnectedGui(); @@ -2053,7 +2087,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements JMenuItem sessit = new JMenuItem(); sessit.setText(sess[i]); sessit.setToolTipText(MessageManager.formatMessage( - "label.connect_to_session", new String[] + "label.connect_to_session", new Object[] { sess[i] })); final Desktop dsktp = this; final String mysesid = sess[i]; @@ -2110,14 +2144,17 @@ public class Desktop extends jalview.jbgui.GDesktop implements { "Vamsas Document" }, "Vamsas Document"); chooser.setFileView(new JalviewFileView()); - chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive")); + chooser.setDialogTitle(MessageManager + .getString("label.save_vamsas_document_archive")); int value = chooser.showSaveDialog(this); if (value == JalviewFileChooser.APPROVE_OPTION) { java.io.File choice = chooser.getSelectedFile(); - JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()})); + JPanel progpanel = addProgressPanel(MessageManager.formatMessage( + "label.saving_vamsas_doc", new Object[] + { choice.getName() })); jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent()); String warnmsg = null; String warnttl = null; @@ -2169,7 +2206,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements } if (b) { - vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session")); + vamUpdate = this.addProgressPanel(MessageManager + .getString("label.updating_vamsas_session")); } vamsasStart.setVisible(!b); vamsasStop.setVisible(!b); @@ -2204,6 +2242,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements public class MyDesktopPane extends JDesktopPane implements Runnable { + private static final float ONE_MB = 1048576f; + boolean showMemoryUsage = false; Runtime runtime; @@ -2243,9 +2283,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements { try { - maxMemory = runtime.maxMemory() / 1048576f; - allocatedMemory = runtime.totalMemory() / 1048576f; - freeMemory = runtime.freeMemory() / 1048576f; + maxMemory = runtime.maxMemory() / ONE_MB; + allocatedMemory = runtime.totalMemory() / ONE_MB; + freeMemory = runtime.freeMemory() / ONE_MB; totalFreeMemory = freeMemory + (maxMemory - allocatedMemory); percentUsage = (totalFreeMemory / maxMemory) * 100; @@ -2279,7 +2319,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements { g.drawString(MessageManager.formatMessage( "label.memory_stats", - new String[] + new Object[] { df.format(totalFreeMemory), df.format(maxMemory), df.format(percentUsage) }), 10, getHeight() - fm.getHeight()); @@ -2319,8 +2359,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements /** * Accessor method to quickly get all the AlignmentFrames loaded. + * + * @return an array of AlignFrame, or null if none found */ - public static AlignFrame[] getAlignframes() + public static AlignFrame[] getAlignFrames() { JInternalFrame[] frames = Desktop.desktop.getAllFrames(); @@ -2328,35 +2370,43 @@ public class Desktop extends jalview.jbgui.GDesktop implements { return null; } - Vector avp = new Vector(); - try + List avp = new ArrayList(); + // REVERSE ORDER + for (int i = frames.length - 1; i > -1; i--) { - // REVERSE ORDER - for (int i = frames.length - 1; i > -1; i--) + if (frames[i] instanceof AlignFrame) { - if (frames[i] instanceof AlignFrame) + avp.add((AlignFrame) frames[i]); + } + else if (frames[i] instanceof SplitFrame) + { + /* + * Also check for a split frame containing an AlignFrame + */ + GSplitFrame sf = (GSplitFrame) frames[i]; + if (sf.getTopFrame() instanceof AlignFrame) + { + avp.add((AlignFrame) sf.getTopFrame()); + } + if (sf.getBottomFrame() instanceof AlignFrame) { - AlignFrame af = (AlignFrame) frames[i]; - avp.addElement(af); + avp.add((AlignFrame) sf.getBottomFrame()); } } - } catch (Exception ex) - { - ex.printStackTrace(); } if (avp.size() == 0) { return null; } - AlignFrame afs[] = new AlignFrame[avp.size()]; - for (int i = 0, j = avp.size(); i < j; i++) - { - afs[i] = (AlignFrame) avp.elementAt(i); - } - avp.clear(); + AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]); return afs; } + /** + * Returns an array of any AppJmol frames in the Desktop (or null if none). + * + * @return + */ public GStructureViewer[] getJmols() { JInternalFrame[] frames = Desktop.desktop.getAllFrames(); @@ -2365,32 +2415,21 @@ public class Desktop extends jalview.jbgui.GDesktop implements { return null; } - Vector avp = new Vector(); - try + List avp = new ArrayList(); + // REVERSE ORDER + for (int i = frames.length - 1; i > -1; i--) { - // REVERSE ORDER - for (int i = frames.length - 1; i > -1; i--) + if (frames[i] instanceof AppJmol) { - if (frames[i] instanceof AppJmol) - { - GStructureViewer af = (GStructureViewer) frames[i]; - avp.addElement(af); - } + GStructureViewer af = (GStructureViewer) frames[i]; + avp.add(af); } - } catch (Exception ex) - { - ex.printStackTrace(); } if (avp.size() == 0) { return null; } - GStructureViewer afs[] = new GStructureViewer[avp.size()]; - for (int i = 0, j = avp.size(); i < j; i++) - { - afs[i] = (GStructureViewer) avp.elementAt(i); - } - avp.clear(); + GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]); return afs; } @@ -2402,7 +2441,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements // use reflection to avoid creating compilation dependency. if (!jalview.bin.Cache.groovyJarsPresent()) { - throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell")); + throw new Error( + MessageManager + .getString("error.implementation_error_cannot_create_groovyshell")); } try { @@ -2420,13 +2461,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements } catch (Exception ex) { jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex); - JOptionPane - .showInternalMessageDialog( - Desktop.desktop, + JOptionPane.showInternalMessageDialog(Desktop.desktop, - MessageManager.getString("label.couldnt_create_groovy_shell"), - MessageManager.getString("label.groovy_support_failed"), - JOptionPane.ERROR_MESSAGE); + MessageManager.getString("label.couldnt_create_groovy_shell"), + MessageManager.getString("label.groovy_support_failed"), + JOptionPane.ERROR_MESSAGE); } } @@ -2476,7 +2515,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements { if (progressBarHandlers == null || !progressBars.contains(new Long(id))) { - throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler")); + throw new Error( + MessageManager + .getString("error.call_setprogressbar_before_registering_handler")); } progressBarHandlers.put(new Long(id), handler); final JPanel progressPanel = progressBars.get(new Long(id)); @@ -2491,7 +2532,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements public void actionPerformed(ActionEvent e) { handler.cancelActivity(id); - us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id); + us.setProgressBar(MessageManager.formatMessage( + "label.cancelled_params", new Object[] + { ((JLabel) progressPanel.getComponent(0)).getText() }), + id); } }); progressPanel.add(cancel, BorderLayout.EAST); @@ -2513,20 +2557,21 @@ public class Desktop extends jalview.jbgui.GDesktop implements } /** - * This will return the first AlignFrame viewing AlignViewport av. It will - * break if there are more than one AlignFrames viewing a particular av. This + * This will return the first AlignFrame holding the given viewport instance. It + * will break if there are more than one AlignFrames viewing a particular av. * - * @param av - * @return alignFrame for av + * @param viewport + * @return alignFrame for viewport */ - public static AlignFrame getAlignFrameFor(AlignViewport av) + public static AlignFrame getAlignFrameFor(AlignViewportI viewport) { if (desktop != null) { - AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId()); + AlignmentPanel[] aps = getAlignmentPanels(viewport + .getSequenceSetId()); for (int panel = 0; aps != null && panel < aps.length; panel++) { - if (aps[panel] != null && aps[panel].av == av) + if (aps[panel] != null && aps[panel].av == viewport) { return aps[panel].alignFrame; } @@ -2753,17 +2798,18 @@ public class Desktop extends jalview.jbgui.GDesktop implements { if (progress != null) { - progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode()); + progress.setProgressBar(MessageManager.formatMessage( + "status.opening_params", new Object[] + { url }), this.hashCode()); } jalview.util.BrowserLauncher.openURL(url); } catch (Exception ex) { - JOptionPane - .showInternalMessageDialog( - Desktop.desktop, - MessageManager.getString("label.web_browser_not_found_unix"), - MessageManager.getString("label.web_browser_not_found"), - JOptionPane.WARNING_MESSAGE); + JOptionPane.showInternalMessageDialog(Desktop.desktop, + MessageManager + .getString("label.web_browser_not_found_unix"), + MessageManager.getString("label.web_browser_not_found"), + JOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } @@ -2878,6 +2924,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements dialogPause = false; block.release(); } + @Override protected void snapShotWindow_actionPerformed(ActionEvent e) { @@ -2887,14 +2934,139 @@ public class Desktop extends jalview.jbgui.GDesktop implements "View of Desktop", getWidth(), getHeight(), of = new File( "Jalview_snapshot" + System.currentTimeMillis() + ".eps"), "View of desktop"); - try { + try + { paintAll(im.getGraphics()); im.writeImage(); } catch (Exception q) { - Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q); + Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(), + q); return; } - Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath()); + Cache.log.info("Successfully written snapshot to file " + + of.getAbsolutePath()); + } + + /** + * Explode the views in the given frame into separate AlignFrame windows. + * + * @param sf + */ + public void explodeViews(SplitFrame sf) + { + AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame(); + AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame(); + List topPanels = oldTopFrame + .getAlignPanels(); + List bottomPanels = oldBottomFrame + .getAlignPanels(); + int viewCount = topPanels.size(); + if (viewCount < 2) + { + return; + } + + /* + * Processing in reverse order works, forwards order leaves the first panels + * not visible. I don't know why! + */ + for (int i = viewCount - 1; i >= 0; i--) + { + /* + * Make new top and bottom frames. These take over the respective + * AlignmentPanel objects, including their AlignmentViewports, so the + * cdna/protein relationships between the viewports is carried over to the + * new split frames. + */ + AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i); + AlignFrame newTopFrame = new AlignFrame(topPanel); + newTopFrame.setVisible(true); + AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i); + AlignFrame newBottomFrame = new AlignFrame(bottomPanel); + newBottomFrame.setVisible(true); + topPanel.av.setGatherViewsHere(false); + bottomPanel.av.setGatherViewsHere(false); + JInternalFrame splitFrame = new SplitFrame(newTopFrame, + newBottomFrame); + // either panel may hold previous exploded frame geometry + Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport()) + .getExplodedGeometry(); + if (geometry != null) + { + splitFrame.setBounds(geometry); + } + Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1); + } + + /* + * Clear references to the panels (now relocated in the new SplitFrames) + * before closing the old SplitFrame. + */ + topPanels.clear(); + bottomPanels.clear(); + sf.close(); + } + + /** + * Gather expanded split frames, sharing the same pairs of sequence set ids, + * back into the given SplitFrame as additional views. Note that the gathered + * frames may themselves have multiple views. + * + * @param source + */ + public void gatherViews(GSplitFrame source) + { + AlignFrame myTopFrame = (AlignFrame) source.getTopFrame(); + AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame(); + myTopFrame.viewport.setExplodedGeometry(source.getBounds()); + myBottomFrame.viewport.setExplodedGeometry(source.getBounds()); + myTopFrame.viewport.setGatherViewsHere(true); + myBottomFrame.viewport.setGatherViewsHere(true); + String topViewId = myTopFrame.viewport.getSequenceSetId(); + String bottomViewId = myBottomFrame.viewport.getSequenceSetId(); + + JInternalFrame[] frames = desktop.getAllFrames(); + for (JInternalFrame frame : frames) + { + if (frame instanceof SplitFrame && frame != source) + { + SplitFrame sf = (SplitFrame) frame; + AlignFrame topFrame = (AlignFrame) sf.getTopFrame(); + AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame(); + boolean gatherThis = false; + for (int a = 0; a < topFrame.alignPanels.size(); a++) + { + AlignmentPanel topPanel = topFrame.alignPanels.get(a); + AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a); + if (topViewId.equals(topPanel.av.getSequenceSetId()) + && bottomViewId.equals(bottomPanel.av.getSequenceSetId())) + { + gatherThis = true; + topPanel.av.setGatherViewsHere(false); + bottomPanel.av.setGatherViewsHere(false); + // both panels refer to the same split frame geometry + Rectangle position = sf.getBounds(); + topPanel.av.setExplodedGeometry(position); + bottomPanel.av.setExplodedGeometry(position); + myTopFrame.addAlignmentPanel(topPanel, false); + myBottomFrame.addAlignmentPanel(bottomPanel, false); + } + } + + if (gatherThis) + { + topFrame.getAlignPanels().clear(); + bottomFrame.getAlignPanels().clear(); + sf.close(); + } + } + } + + /* + * The dust settles...give focus to the tab we did this from. + */ + myTopFrame.setDisplayedView(myTopFrame.alignPanel); + } } diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 3475fe3..c23ad26 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -28,6 +28,7 @@ import jalview.io.JalviewFileChooser; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.GraduatedColor; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.dbsources.das.api.jalviewSourceI; import java.awt.BorderLayout; @@ -1213,7 +1214,7 @@ public class FeatureSettings extends JPanel { SequenceI[] dataset, seqs; int iSize; - AlignViewport vp = af.getViewport(); + AlignmentViewport vp = af.getViewport(); if (vp.getSelectionGroup() != null && vp.getSelectionGroup().getSize() > 0) { diff --git a/src/jalview/gui/Finder.java b/src/jalview/gui/Finder.java index 6f3e7b8..3cc82c5 100755 --- a/src/jalview/gui/Finder.java +++ b/src/jalview/gui/Finder.java @@ -25,6 +25,7 @@ import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.jbgui.GFinder; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.event.ActionEvent; import java.util.Vector; @@ -52,7 +53,7 @@ public class Finder extends GFinder private static final int WIDTH = 340; - AlignViewport av; + AlignmentViewport av; AlignmentPanel ap; @@ -80,7 +81,7 @@ public class Finder extends GFinder * @param viewport * @param alignPanel */ - public Finder(AlignViewport viewport, AlignmentPanel alignPanel) + public Finder(AlignmentViewport viewport, AlignmentPanel alignPanel) { av = viewport; ap = alignPanel; diff --git a/src/jalview/gui/FontChooser.java b/src/jalview/gui/FontChooser.java index 36e4c52..7738e96 100755 --- a/src/jalview/gui/FontChooser.java +++ b/src/jalview/gui/FontChooser.java @@ -20,14 +20,18 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import jalview.bin.*; -import jalview.jbgui.*; +import jalview.bin.Cache; +import jalview.jbgui.GFontChooser; import jalview.util.MessageManager; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.event.ActionEvent; + +import javax.swing.JInternalFrame; +import javax.swing.JLayeredPane; +import javax.swing.JOptionPane; + /** * DOCUMENT ME! * @@ -167,7 +171,7 @@ public class FontChooser extends GFontChooser { if (ap != null) { - ap.av.setFont(oldFont); + ap.av.setFont(oldFont, true); ap.paintAlignment(true); } else if (tp != null) @@ -236,7 +240,7 @@ public class FontChooser extends GFontChooser } else if (ap != null) { - ap.av.setFont(newFont); + ap.av.setFont(newFont, true); ap.fontChanged(); } diff --git a/src/jalview/gui/IdCanvas.java b/src/jalview/gui/IdCanvas.java index 3bc3168..c174a0e 100755 --- a/src/jalview/gui/IdCanvas.java +++ b/src/jalview/gui/IdCanvas.java @@ -20,13 +20,19 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.image.*; +import jalview.datamodel.SequenceI; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; import java.util.List; -import javax.swing.*; - -import jalview.datamodel.*; +import javax.swing.JPanel; /** * DOCUMENT ME! @@ -94,7 +100,7 @@ public class IdCanvas extends JPanel { int xPos = 0; int panelWidth = getWidth(); - int charHeight = av.charHeight; + int charHeight = av.getCharHeight(); if ((searchResults != null) && searchResults.contains(s)) { @@ -128,7 +134,7 @@ public class IdCanvas extends JPanel gg.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos, (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5)); - if (av.hasHiddenRows() && av.showHiddenMarkers) + if (av.hasHiddenRows() && av.getShowHiddenMarkers()) { drawMarker(i, starty, ypos); } @@ -150,7 +156,8 @@ public class IdCanvas extends JPanel return; } - gg.copyArea(0, 0, getWidth(), imgHeight, 0, -vertical * av.charHeight); + gg.copyArea(0, 0, getWidth(), imgHeight, 0, + -vertical * av.getCharHeight()); int ss = av.startSeq; int es = av.endSeq; @@ -166,7 +173,7 @@ public class IdCanvas extends JPanel } else { - transY = imgHeight - (vertical * av.charHeight); + transY = imgHeight - (vertical * av.getCharHeight()); } } else if (vertical < 0) @@ -211,7 +218,7 @@ public class IdCanvas extends JPanel int oldHeight = imgHeight; imgHeight = getHeight(); - imgHeight -= (imgHeight % av.charHeight); + imgHeight -= (imgHeight % av.getCharHeight()); if (imgHeight < 1) { @@ -245,7 +252,7 @@ public class IdCanvas extends JPanel */ void drawIds(int starty, int endy) { - if (av.seqNameItalics) + if (av.isSeqNameItalics()) { setIdfont(new Font(av.getFont().getName(), Font.ITALIC, av.getFont() .getSize())); @@ -293,13 +300,13 @@ public class IdCanvas extends JPanel } } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = alheight * av.charHeight + hgap + annotationHeight; + int cHeight = alheight * av.getCharHeight() + hgap + annotationHeight; int rowSize = av.getEndRes() - av.getStartRes(); @@ -324,9 +331,9 @@ public class IdCanvas extends JPanel if (labels != null && av.isShowAnnotation()) { - gg.translate(0, ypos + (alheight * av.charHeight)); + gg.translate(0, ypos + (alheight * av.getCharHeight())); labels.drawComponent(gg, getWidth()); - gg.translate(0, -ypos - (alheight * av.charHeight)); + gg.translate(0, -ypos - (alheight * av.getCharHeight())); } } } @@ -376,8 +383,8 @@ public class IdCanvas extends JPanel gg.setColor(currentColor); - gg.fillRect(0, (i - starty) * av.charHeight, getWidth(), - av.charHeight); + gg.fillRect(0, (i - starty) * av.getCharHeight(), getWidth(), + av.getCharHeight()); gg.setColor(currentTextColor); @@ -389,10 +396,10 @@ public class IdCanvas extends JPanel } gg.drawString(string, xPos, - (((i - starty) * av.charHeight) + av.charHeight) - - (av.charHeight / 5)); + (((i - starty) * av.getCharHeight()) + av.getCharHeight()) + - (av.getCharHeight() / 5)); - if (av.hasHiddenRows() && av.showHiddenMarkers) + if (av.hasHiddenRows() && av.getShowHiddenMarkers()) { drawMarker(i, starty, 0); } @@ -441,24 +448,27 @@ public class IdCanvas extends JPanel { gg.fillPolygon( new int[] - { getWidth() - av.charHeight, getWidth() - av.charHeight, + { getWidth() - av.getCharHeight(), + getWidth() - av.getCharHeight(), getWidth() }, new int[] { - (i - starty) * av.charHeight + yoffset, - (i - starty) * av.charHeight + yoffset + av.charHeight - / 4, (i - starty) * av.charHeight + yoffset }, 3); + (i - starty) * av.getCharHeight() + yoffset, + (i - starty) * av.getCharHeight() + yoffset + + av.getCharHeight() / 4, + (i - starty) * av.getCharHeight() + yoffset }, 3); } if (above) { gg.fillPolygon( new int[] - { getWidth() - av.charHeight, getWidth() - av.charHeight, + { getWidth() - av.getCharHeight(), + getWidth() - av.getCharHeight(), getWidth() }, new int[] { - (i - starty + 1) * av.charHeight + yoffset, - (i - starty + 1) * av.charHeight + yoffset - - av.charHeight / 4, - (i - starty + 1) * av.charHeight + yoffset }, 3); + (i - starty + 1) * av.getCharHeight() + yoffset, + (i - starty + 1) * av.getCharHeight() + yoffset + - av.getCharHeight() / 4, + (i - starty + 1) * av.getCharHeight() + yoffset }, 3); } } diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index a22e918..9b0d9b9 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -110,7 +110,7 @@ public class IdPanel extends JPanel implements MouseListener, StringBuffer tip = new StringBuffer(64); seqAnnotReport .createSequenceAnnotationReport(tip, sequence, - av.isShowDbRefs(), av.isShowNpFeats(), + av.isShowDBRefs(), av.isShowNPFeats(), sp.seqCanvas.fr.getMinMax()); setToolTipText("" + sequence.getDisplayId(true) + " " + tip.toString() + ""); @@ -363,6 +363,9 @@ public class IdPanel extends JPanel implements MouseListener, { selectSeq(seq); } + // TODO is this addition ok here? + av.isSelectionGroupChanged(true); + alignPanel.paintAlignment(true); } diff --git a/src/jalview/gui/IdwidthAdjuster.java b/src/jalview/gui/IdwidthAdjuster.java index 6c9c400..cbe9c8b 100755 --- a/src/jalview/gui/IdwidthAdjuster.java +++ b/src/jalview/gui/IdwidthAdjuster.java @@ -20,9 +20,14 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +import javax.swing.JPanel; /** * DOCUMENT ME! @@ -119,13 +124,13 @@ public class IdwidthAdjuster extends JPanel implements MouseListener, { active = true; - Dimension d = ap.getIdPanel().getIdCanvas().getPreferredSize(); + int curwidth = ap.getAlignViewport().getIdWidth(); int dif = evt.getX() - oldX; - if (((d.width + dif) > 20) || (dif > 0)) + if (((curwidth + dif) > 20) || (dif > 0)) { - ap.getIdPanel().getIdCanvas().setPreferredSize(new Dimension(d.width + dif, - d.height)); + ap.getAlignViewport().setIdWidth(curwidth + dif); + ap.paintAlignment(true); } diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index a2cd147..f01e775 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -22,6 +22,7 @@ package jalview.gui; import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; @@ -30,7 +31,6 @@ import jalview.datamodel.SequenceI; import jalview.datamodel.StructureViewerModel; import jalview.datamodel.StructureViewerModel.StructureData; import jalview.schemabinding.version2.AlcodMap; -import jalview.schemabinding.version2.Alcodon; import jalview.schemabinding.version2.AlcodonFrame; import jalview.schemabinding.version2.Annotation; import jalview.schemabinding.version2.AnnotationColours; @@ -150,6 +150,12 @@ public class Jalview2XML boolean raiseGUI = true; // whether errors are raised in dialog boxes or not + /* + * Map of reconstructed AlignFrame objects that appear to have come from + * SplitFrame objects (have a dna/protein complement view). + */ + private Map splitFrameCandidates = new HashMap(); + /** * create/return unique hash string for sq * @@ -298,12 +304,12 @@ public class Jalview2XML } /** - * This maintains a list of viewports, the key being the seqSetId. Important - * to set historyItem and redoList for multiple views + * This maintains a map of viewports, the key being the seqSetId. Important to + * set historyItem and redoList for multiple views */ - Hashtable viewportsAdded; + Map viewportsAdded = new HashMap(); - Hashtable annotationIds = new Hashtable(); + Map annotationIds = new HashMap(); String uniqueSetSuffix = ""; @@ -359,7 +365,7 @@ public class Jalview2XML */ public void saveState(JarOutputStream jout) { - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + AlignFrame[] frames = Desktop.getAlignFrames(); // Desktop.desktop.getAllFrames(); if (frames == null) { @@ -379,67 +385,61 @@ public class Jalview2XML // REVERSE ORDER for (int i = frames.length - 1; i > -1; i--) { - if (frames[i] instanceof AlignFrame) + AlignFrame af = frames[i]; + // skip ? + if (skipList != null + && skipList + .containsKey(af.getViewport().getSequenceSetId())) { - AlignFrame af = (AlignFrame) frames[i]; - // skip ? - if (skipList != null - && skipList.containsKey(af.getViewport() - .getSequenceSetId())) - { - continue; - } + continue; + } - String shortName = af.getTitle(); + String shortName = af.getTitle(); - if (shortName.indexOf(File.separatorChar) > -1) + if (shortName.indexOf(File.separatorChar) > -1) + { + shortName = shortName.substring(shortName + .lastIndexOf(File.separatorChar) + 1); + } + + int count = 1; + + while (shortNames.contains(shortName)) + { + if (shortName.endsWith("_" + (count - 1))) { - shortName = shortName.substring(shortName - .lastIndexOf(File.separatorChar) + 1); + shortName = shortName.substring(0, shortName.lastIndexOf("_")); } - int count = 1; + shortName = shortName.concat("_" + count); + count++; + } - while (shortNames.contains(shortName)) - { - if (shortName.endsWith("_" + (count - 1))) - { - shortName = shortName - .substring(0, shortName.lastIndexOf("_")); - } + shortNames.addElement(shortName); - shortName = shortName.concat("_" + count); - count++; - } + if (!shortName.endsWith(".xml")) + { + shortName = shortName + ".xml"; + } - shortNames.addElement(shortName); + int ap, apSize = af.alignPanels.size(); - if (!shortName.endsWith(".xml")) + for (ap = 0; ap < apSize; ap++) + { + AlignmentPanel apanel = af.alignPanels.get(ap); + String fileName = apSize == 1 ? shortName : ap + shortName; + if (!fileName.endsWith(".xml")) { - shortName = shortName + ".xml"; + fileName = fileName + ".xml"; } - int ap, apSize = af.alignPanels.size(); + saveState(apanel, fileName, jout); - for (ap = 0; ap < apSize; ap++) + String dssid = getDatasetIdRef(af.getViewport().getAlignment() + .getDataset()); + if (!dsses.containsKey(dssid)) { - AlignmentPanel apanel = (AlignmentPanel) af.alignPanels - .elementAt(ap); - String fileName = apSize == 1 ? shortName : ap + shortName; - if (!fileName.endsWith(".xml")) - { - fileName = fileName + ".xml"; - } - - saveState(apanel, fileName, jout); - - String dssid = getDatasetIdRef(af.getViewport().getAlignment() - .getDataset()); - if (!dsses.containsKey(dssid)) - { - dsses.put(dssid, af); - } - + dsses.put(dssid, af); } } } @@ -473,15 +473,15 @@ public class Jalview2XML { try { - int ap, apSize = af.alignPanels.size(); + int ap = 0; + int apSize = af.alignPanels.size(); FileOutputStream fos = new FileOutputStream(jarFile); JarOutputStream jout = new JarOutputStream(fos); Hashtable dsses = new Hashtable(); - for (ap = 0; ap < apSize; ap++) + for (AlignmentPanel apanel : af.alignPanels) { - AlignmentPanel apanel = (AlignmentPanel) af.alignPanels - .elementAt(ap); String jfileName = apSize == 1 ? fileName : fileName + ap; + ap++; if (!jfileName.endsWith(".xml")) { jfileName = jfileName + ".xml"; @@ -780,8 +780,7 @@ public class Jalview2XML { byte[] data = new byte[(int) file.length()]; jout.putNextEntry(new JarEntry(entry.getId())); - dis = new DataInputStream( - new FileInputStream(file)); + dis = new DataInputStream(new FileInputStream(file)); dis.readFully(data); DataOutputStream dout = new DataOutputStream(jout); @@ -837,31 +836,18 @@ public class Jalview2XML jal = av.getAlignment(); } // SAVE MAPPINGS - if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0) + if (jal.getCodonFrames() != null) { - jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames(); - for (int i = 0; i < jac.length; i++) + Set jac = jal.getCodonFrames(); + for (AlignedCodonFrame acf : jac) { AlcodonFrame alc = new AlcodonFrame(); vamsasSet.addAlcodonFrame(alc); - for (int p = 0; p < jac[i].aaWidth; p++) + if (acf.getProtMappings() != null + && acf.getProtMappings().length > 0) { - Alcodon cmap = new Alcodon(); - if (jac[i].codons[p] != null) - { - // Null codons indicate a gapped column in the translated peptide - // alignment. - cmap.setPos1(jac[i].codons[p][0]); - cmap.setPos2(jac[i].codons[p][1]); - cmap.setPos3(jac[i].codons[p][2]); - } - alc.addAlcodon(cmap); - } - if (jac[i].getProtMappings() != null - && jac[i].getProtMappings().length > 0) - { - SequenceI[] dnas = jac[i].getdnaSeqs(); - jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings(); + SequenceI[] dnas = acf.getdnaSeqs(); + jalview.datamodel.Mapping[] pmaps = acf.getProtMappings(); for (int m = 0; m < pmaps.length; m++) { AlcodMap alcmap = new AlcodMap(); @@ -871,6 +857,37 @@ public class Jalview2XML alc.addAlcodMap(alcmap); } } + +// { +// AlcodonFrame alc = new AlcodonFrame(); +// vamsasSet.addAlcodonFrame(alc); +// for (int p = 0; p < acf.aaWidth; p++) +// { +// Alcodon cmap = new Alcodon(); +// if (acf.codons[p] != null) +// { +// // Null codons indicate a gapped column in the translated peptide +// // alignment. +// cmap.setPos1(acf.codons[p][0]); +// cmap.setPos2(acf.codons[p][1]); +// cmap.setPos3(acf.codons[p][2]); +// } +// alc.addAlcodon(cmap); +// } +// if (acf.getProtMappings() != null +// && acf.getProtMappings().length > 0) +// { +// SequenceI[] dnas = acf.getdnaSeqs(); +// jalview.datamodel.Mapping[] pmaps = acf.getProtMappings(); +// for (int m = 0; m < pmaps.length; m++) +// { +// AlcodMap alcmap = new AlcodMap(); +// alcmap.setDnasq(seqHash(dnas[m])); +// alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null, +// false)); +// alc.addAlcodMap(alcmap); +// } +// } } } @@ -1031,15 +1048,20 @@ public class Jalview2XML view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), av.getSequenceSetId())); view.setId(av.getViewId()); + if (av.getCodingComplement() != null) + { + view.setComplementId(av.getCodingComplement().getViewId()); + } view.setViewName(av.viewName); - view.setGatheredViews(av.gatherViewsHere); + view.setGatheredViews(av.isGatherViewsHere()); - if (ap.av.explodedPosition != null) + Rectangle position = ap.av.getExplodedGeometry(); + if (position != null) { - view.setXpos(av.explodedPosition.x); - view.setYpos(av.explodedPosition.y); - view.setWidth(av.explodedPosition.width); - view.setHeight(av.explodedPosition.height); + view.setXpos(position.x); + view.setYpos(position.y); + view.setWidth(position.width); + view.setHeight(position.height); } else { @@ -1097,7 +1119,7 @@ public class Jalview2XML view.setFontName(av.font.getName()); view.setFontSize(av.font.getSize()); view.setFontStyle(av.font.getStyle()); - view.setRenderGaps(av.renderGaps); + view.setRenderGaps(av.isRenderGaps()); view.setShowAnnotation(av.isShowAnnotation()); view.setShowBoxes(av.getShowBoxes()); view.setShowColourText(av.getColourText()); @@ -1107,25 +1129,26 @@ public class Jalview2XML view.setShowText(av.getShowText()); view.setShowUnconserved(av.getShowUnconserved()); view.setWrapAlignment(av.getWrapAlignment()); - view.setTextCol1(av.textColour.getRGB()); - view.setTextCol2(av.textColour2.getRGB()); - view.setTextColThreshold(av.thresholdTextColour); + view.setTextCol1(av.getTextColour().getRGB()); + view.setTextCol2(av.getTextColour2().getRGB()); + view.setTextColThreshold(av.getThresholdTextColour()); view.setShowConsensusHistogram(av.isShowConsensusHistogram()); view.setShowSequenceLogo(av.isShowSequenceLogo()); view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo()); view.setShowGroupConsensus(av.isShowGroupConsensus()); view.setShowGroupConservation(av.isShowGroupConservation()); - view.setShowNPfeatureTooltip(av.isShowNpFeats()); - view.setShowDbRefTooltip(av.isShowDbRefs()); + view.setShowNPfeatureTooltip(av.isShowNPFeats()); + view.setShowDbRefTooltip(av.isShowDBRefs()); view.setFollowHighlight(av.followHighlight); view.setFollowSelection(av.followSelection); - view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus()); + view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus()); if (av.getFeaturesDisplayed() != null) { jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings(); - String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer() - .getRenderOrder().toArray(new String[0]); + String[] renderOrder = ap.getSeqPanel().seqCanvas + .getFeatureRenderer().getRenderOrder() + .toArray(new String[0]); Vector settingsAdded = new Vector(); Object gstyle = null; @@ -1152,7 +1175,8 @@ public class Jalview2XML } else { - setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer() + setting.setColour(ap.getSeqPanel().seqCanvas + .getFeatureRenderer() .getColour(renderOrder[ro]).getRGB()); } @@ -1196,8 +1220,8 @@ public class Jalview2XML settingsAdded.addElement(key); } // is groups actually supposed to be a map here ? - en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().getFeatureGroups() - .iterator(); + en = ap.getSeqPanel().seqCanvas.getFeatureRenderer() + .getFeatureGroups().iterator(); Vector groupsAdded = new Vector(); while (en.hasNext()) { @@ -1230,8 +1254,8 @@ public class Jalview2XML for (int c = 0; c < av.getColumnSelection().getHiddenColumns() .size(); c++) { - int[] region = av.getColumnSelection() - .getHiddenColumns().get(c); + int[] region = av.getColumnSelection().getHiddenColumns() + .get(c); HiddenColumns hc = new HiddenColumns(); hc.setStart(region[0]); hc.setEnd(region[1]); @@ -1302,17 +1326,14 @@ public class Jalview2XML Pdbids pdb, PDBEntry entry, List viewIds, String matchedFile, StructureViewerBase viewFrame) { - final AAStructureBindingModel bindingModel = viewFrame - .getBinding(); - for (int peid = 0; peid < bindingModel - .getPdbCount(); peid++) + final AAStructureBindingModel bindingModel = viewFrame.getBinding(); + for (int peid = 0; peid < bindingModel.getPdbCount(); peid++) { final PDBEntry pdbentry = bindingModel.getPdbEntry(peid); final String pdbId = pdbentry.getId(); if (!pdbId.equals(entry.getId()) && !(entry.getId().length() > 4 && entry.getId() - .toLowerCase() - .startsWith(pdbId.toLowerCase()))) + .toLowerCase().startsWith(pdbId.toLowerCase()))) { continue; } @@ -1320,8 +1341,7 @@ public class Jalview2XML { matchedFile = pdbentry.getFile(); } - else if (!matchedFile.equals(pdbentry - .getFile())) + else if (!matchedFile.equals(pdbentry.getFile())) { Cache.log .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): " @@ -1334,8 +1354,7 @@ public class Jalview2XML // 1QIP==1qipA) String statestring = viewFrame.getStateInfo(); - for (int smap = 0; smap < viewFrame.getBinding() - .getSequence()[peid].length; smap++) + for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++) { // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) if (jds == viewFrame.getBinding().getSequence()[peid][smap]) @@ -1349,8 +1368,7 @@ public class Jalview2XML final String viewId = viewFrame.getViewId(); state.setViewId(viewId); state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap)); - state.setColourwithAlignPanel(viewFrame - .isUsedforcolourby(ap)); + state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap)); state.setColourByJmol(viewFrame.isColouredByViewer()); /* * Only store each structure viewer's state once in each XML document. @@ -1645,7 +1663,9 @@ public class Jalview2XML return false; } } - throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()})); + throw new Error(MessageManager.formatMessage( + "error.unsupported_version_calcIdparam", new Object[] + { calcIdParam.toString() })); } /** @@ -1767,20 +1787,20 @@ public class Jalview2XML mp = new Mapping(); jalview.util.MapList mlst = jmp.getMap(); - int r[] = mlst.getFromRanges(); - for (int s = 0; s < r.length; s += 2) + List r = mlst.getFromRanges(); + for (int[] range : r) { MapListFrom mfrom = new MapListFrom(); - mfrom.setStart(r[s]); - mfrom.setEnd(r[s + 1]); + mfrom.setStart(range[0]); + mfrom.setEnd(range[1]); mp.addMapListFrom(mfrom); } r = mlst.getToRanges(); - for (int s = 0; s < r.length; s += 2) + for (int[] range : r) { MapListTo mto = new MapListTo(); - mto.setStart(r[s]); - mto.setEnd(r[s + 1]); + mto.setStart(range[0]); + mto.setEnd(range[1]); mp.addMapListTo(mto); } mp.setMapFromUnit(mlst.getFromRatio()); @@ -1977,7 +1997,7 @@ public class Jalview2XML errorMessage = null; uniqueSetSuffix = null; seqRefIds = null; - viewportsAdded = null; + viewportsAdded.clear(); frefedSequence = null; if (file.startsWith("http://")) @@ -2029,17 +2049,13 @@ public class Jalview2XML { seqRefIds = new HashMap(); } - if (viewportsAdded == null) - { - viewportsAdded = new Hashtable(); - } if (frefedSequence == null) { frefedSequence = new Vector(); } - jalview.gui.AlignFrame af = null, _af = null; - Hashtable gatherToThisFrame = new Hashtable(); + AlignFrame af = null, _af = null; + Map gatherToThisFrame = new HashMap(); final String file = jprovider.getFilename(); try { @@ -2069,7 +2085,7 @@ public class Jalview2XML if (object.getJalviewModelSequence().getViewportCount() > 0) { af = _af; - if (af.viewport.gatherViewsHere) + if (af.viewport.isGatherViewsHere()) { gatherToThisFrame.put(af.viewport.getSequenceSetId(), af); } @@ -2139,11 +2155,20 @@ public class Jalview2XML Desktop.instance.stopLoading(); } - Enumeration en = gatherToThisFrame.elements(); - while (en.hasMoreElements()) + /* + * Regather multiple views (with the same sequence set id) to the frame (if + * any) that is flagged as the one to gather to, i.e. convert them to tabbed + * views instead of separate frames. Note this doesn't restore a state where + * some expanded views in turn have tabbed views - the last "first tab" read + * in will play the role of gatherer for all. + */ + for (AlignFrame fr : gatherToThisFrame.values()) { - Desktop.instance.gatherViews((AlignFrame) en.nextElement()); + Desktop.instance.gatherViews(fr); } + + restoreSplitFrames(); + if (errorMessage != null) { reportErrors(); @@ -2152,6 +2177,99 @@ public class Jalview2XML } /** + * Try to reconstruct and display SplitFrame windows, where each contains + * complementary dna and protein alignments. Done by pairing up AlignFrame + * objects (created earlier) which have complementary viewport ids associated. + */ + protected void restoreSplitFrames() + { + List gatherTo = new ArrayList(); + List addedToSplitFrames = new ArrayList(); + Map dna = new HashMap(); + + /* + * Identify the DNA alignments + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (af.getViewport().getAlignment().isNucleotide()) + { + dna.put(candidate.getKey().getId(), af); + } + } + + /* + * Try to match up the protein complements + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (!af.getViewport().getAlignment().isNucleotide()) + { + String complementId = candidate.getKey().getComplementId(); + // only non-null complements should be in the Map + if (complementId != null && dna.containsKey(complementId)) + { + final AlignFrame dnaFrame = dna.get(complementId); + SplitFrame sf = createSplitFrame(dnaFrame, af); + addedToSplitFrames.add(dnaFrame); + addedToSplitFrames.add(af); + if (af.viewport.isGatherViewsHere()) + { + gatherTo.add(sf); + } + } + } + } + + /* + * Open any that we failed to pair up (which shouldn't happen!) as + * standalone AlignFrame's. + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (!addedToSplitFrames.contains(af)) { + Viewport view = candidate.getKey(); + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + System.err.println("Failed to restore view " + view.getTitle() + + " to split frame"); + } + } + + /* + * Gather back into tabbed views as flagged. + */ + for (SplitFrame sf : gatherTo) + { + Desktop.instance.gatherViews(sf); + } + + splitFrameCandidates.clear(); + } + + /** + * Construct and display one SplitFrame holding DNA and protein alignments. + * + * @param dnaFrame + * @param proteinFrame + * @return + */ + protected SplitFrame createSplitFrame(AlignFrame dnaFrame, + AlignFrame proteinFrame) + { + SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame); + String title = MessageManager.getString("label.linked_view_title"); + Desktop.addInternalFrame(splitFrame, title, -1, -1); + return splitFrame; + } + + /** * check errorMessage for a valid error message and raise an error box in the * GUI or write the current errorMessage to stderr and then clear the error * state. @@ -2188,7 +2306,7 @@ public class Jalview2XML errorMessage = null; } - Hashtable alreadyLoadedPDB; + Map alreadyLoadedPDB = new HashMap(); /** * when set, local views will be updated from view stored in JalviewXML @@ -2199,11 +2317,6 @@ public class Jalview2XML String loadPDBFile(jarInputStreamProvider jprovider, String pdbId) { - if (alreadyLoadedPDB == null) - { - alreadyLoadedPDB = new Hashtable(); - } - if (alreadyLoadedPDB.containsKey(pdbId)) { return alreadyLoadedPDB.get(pdbId).toString(); @@ -2305,10 +2418,10 @@ public class Jalview2XML // //////////////////////////////// // LOAD SEQUENCES - Vector hiddenSeqs = null; + List hiddenSeqs = null; jalview.datamodel.Sequence jseq; - ArrayList tmpseqs = new ArrayList(); + List tmpseqs = new ArrayList(); boolean multipleView = false; @@ -2340,10 +2453,10 @@ public class Jalview2XML { if (hiddenSeqs == null) { - hiddenSeqs = new Vector(); + hiddenSeqs = new ArrayList(); } - hiddenSeqs.addElement(seqRefIds.get(seqId)); + hiddenSeqs.add(seqRefIds.get(seqId)); } } @@ -2351,13 +2464,10 @@ public class Jalview2XML // / // Create the alignment object from the sequence set // /////////////////////////////// - jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs - .size()]; - - tmpseqs.toArray(orderedSeqs); + SequenceI[] orderedSeqs = tmpseqs + .toArray(new SequenceI[tmpseqs.size()]); - jalview.datamodel.Alignment al = new jalview.datamodel.Alignment( - orderedSeqs); + Alignment al = new Alignment(orderedSeqs); // / Add the alignment properties for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++) @@ -2384,7 +2494,7 @@ public class Jalview2XML } // /////////////////////////////// - Hashtable pdbloaded = new Hashtable(); + Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this?? if (!multipleView) { // load sequence features, database references and any associated PDB @@ -2443,8 +2553,7 @@ public class Jalview2XML } } StructureSelectionManager.getStructureSelectionManager( - Desktop.instance) - .registerPDBEntry(entry); + Desktop.instance).registerPDBEntry(entry); al.getSequenceAt(i).getDatasetSequence().addPDBId(entry); } } @@ -2461,35 +2570,13 @@ public class Jalview2XML AlcodonFrame[] alc = vamsasSet.getAlcodonFrame(); for (int i = 0; i < alc.length; i++) { - jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame( - alc[i].getAlcodonCount()); - if (alc[i].getAlcodonCount() > 0) - { - Alcodon[] alcods = alc[i].getAlcodon(); - for (int p = 0; p < cf.codons.length; p++) - { - if (alcods[p].hasPos1() && alcods[p].hasPos2() - && alcods[p].hasPos3()) - { - // translated codons require three valid positions - cf.codons[p] = new int[3]; - cf.codons[p][0] = (int) alcods[p].getPos1(); - cf.codons[p][1] = (int) alcods[p].getPos2(); - cf.codons[p][2] = (int) alcods[p].getPos3(); - } - else - { - cf.codons[p] = null; - } - } - } + AlignedCodonFrame cf = new AlignedCodonFrame(); if (alc[i].getAlcodMapCount() > 0) { AlcodMap[] maps = alc[i].getAlcodMap(); for (int m = 0; m < maps.length; m++) { - SequenceI dnaseq = seqRefIds - .get(maps[m].getDnasq()); + SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq()); // Load Mapping jalview.datamodel.Mapping mapping = null; // attach to dna sequence reference. @@ -2511,12 +2598,11 @@ public class Jalview2XML } al.addCodonFrame(cf); } - } // //////////////////////////////// // LOAD ANNOTATIONS - ArrayList autoAlan = new ArrayList(); + List autoAlan = new ArrayList(); /** * store any annotations which forward reference a group's ID */ @@ -2555,8 +2641,7 @@ public class Jalview2XML if (an[i].getId() != null && annotationIds.containsKey(an[i].getId())) { - jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds - .get(an[i].getId()); + AlignmentAnnotation jda = annotationIds.get(an[i].getId()); // in principle Visible should always be true for annotation displayed // in multiple views if (an[i].hasVisible()) @@ -2766,8 +2851,7 @@ public class Jalview2XML for (int s = 0; s < groups[i].getSeqCount(); s++) { String seqId = groups[i].getSeq(s) + ""; - jalview.datamodel.SequenceI ts = seqRefIds - .get(seqId); + jalview.datamodel.SequenceI ts = seqRefIds.get(seqId); if (ts != null) { @@ -3057,10 +3141,10 @@ public class Jalview2XML for (int s = 0; s < structureStateCount; s++) { // check to see if we haven't already created this structure view - final StructureState structureState = ids[p].getStructureState(s); + final StructureState structureState = ids[p] + .getStructureState(s); String sviewid = (structureState.getViewId() == null) ? null - : structureState.getViewId() - + uniqueSetSuffix; + : structureState.getViewId() + uniqueSetSuffix; jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry(); // Originally : ids[p].getFile() // : TODO: verify external PDB file recovery still works in normal @@ -3077,8 +3161,8 @@ public class Jalview2XML // Desktop.desktop.getComponentAt(x, y); // TODO: NOW: check that this recovers the PDB file correctly. String pdbFile = loadPDBFile(jprovider, ids[p].getId()); - jalview.datamodel.SequenceI seq = seqRefIds - .get(jseqs[i].getId() + ""); + jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i] + .getId() + ""); if (sviewid == null) { sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width @@ -3086,8 +3170,8 @@ public class Jalview2XML } if (!structureViewers.containsKey(sviewid)) { - structureViewers.put(sviewid, new StructureViewerModel(x, y, width, height, - false, false, true)); + structureViewers.put(sviewid, new StructureViewerModel(x, y, + width, height, false, false, true)); // Legacy pre-2.7 conversion JAL-823 : // do not assume any view has to be linked for colour by // sequence @@ -3117,8 +3201,7 @@ public class Jalview2XML * pre-2.7 projects) */ boolean colourByViewer = jmoldat.isColourByViewer(); - colourByViewer &= structureState - .hasColourByJmol() ? structureState + colourByViewer &= structureState.hasColourByJmol() ? structureState .getColourByJmol() : true; jmoldat.setColourByViewer(colourByViewer); @@ -3155,11 +3238,12 @@ public class Jalview2XML } } } - // Instantiate the associated structure views - for (Entry entry : structureViewers.entrySet()) + // Instantiate the associated structure views + for (Entry entry : structureViewers + .entrySet()) { - createOrLinkStructureViewer(entry, af, ap); - } + createOrLinkStructureViewer(entry, af, ap); + } } /** @@ -3206,8 +3290,8 @@ public class Jalview2XML * @param viewerData * @param af */ - protected void createChimeraViewer(Entry viewerData, - AlignFrame af) + protected void createChimeraViewer( + Entry viewerData, AlignFrame af) { final StructureViewerModel data = viewerData.getValue(); String chimeraSession = data.getStateData(); @@ -3232,12 +3316,11 @@ public class Jalview2XML boolean colourBySequence = data.isColourWithAlignPanel(); // TODO can/should this be done via StructureViewer (like Jmol)? - final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs - .size()]); - final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]); + final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]); + final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs + .size()][]); new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray, - seqsArray, - colourByChimera, colourBySequence); + seqsArray, colourByChimera, colourBySequence); } else { @@ -3255,7 +3338,8 @@ public class Jalview2XML * @param af */ protected void createJmolViewer( - final Entry viewerData, AlignFrame af) + final Entry viewerData, + AlignFrame af) { final StructureViewerModel svattrib = viewerData.getValue(); String state = svattrib.getStateData(); @@ -3282,8 +3366,7 @@ public class Jalview2XML newFileLoc.append(Platform.escapeString(filedat.getFilePath())); pdbfilenames.add(filedat.getFilePath()); pdbids.add(filedat.getPdbId()); - seqmaps.add(filedat.getSeqList() - .toArray(new SequenceI[0])); + seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0])); newFileLoc.append("\""); cp = ecp + 1; // advance beyond last \" and set cursor so we can // look for next file statement. @@ -3307,8 +3390,7 @@ public class Jalview2XML newFileLoc.append(filedat.getFilePath()); pdbfilenames.add(filedat.getFilePath()); pdbids.add(filedat.getPdbId()); - seqmaps.add(filedat.getSeqList() - .toArray(new SequenceI[0])); + seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0])); newFileLoc.append(" \""); newFileLoc.append(filedat.getFilePath()); newFileLoc.append("\""); @@ -3414,8 +3496,8 @@ public class Jalview2XML * Post jalview 2.4 schema includes structure view id */ if (sviewid != null - && ((StructureViewerBase) frame).getViewId().equals( - sviewid)) + && ((StructureViewerBase) frame).getViewId() + .equals(sviewid)) { comp = (AppJmol) frame; // todo: break? @@ -3600,10 +3682,10 @@ public class Jalview2XML } } - AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs, - Alignment al, JalviewModelSequence jms, Viewport view, - String uniqueSeqSetId, String viewId, - ArrayList autoAlan) + AlignFrame loadViewport(String file, JSeq[] JSEQ, + List hiddenSeqs, Alignment al, + JalviewModelSequence jms, Viewport view, String uniqueSeqSetId, + String viewId, List autoAlan) { AlignFrame af = null; af = new AlignFrame(al, view.getWidth(), view.getHeight(), @@ -3617,19 +3699,18 @@ public class Jalview2XML .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour())); } - af.viewport.gatherViewsHere = view.getGatheredViews(); + af.viewport.setGatherViewsHere(view.getGatheredViews()); if (view.getSequenceSetId() != null) { - jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded - .get(uniqueSeqSetId); + AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId); af.viewport.setSequenceSetId(uniqueSeqSetId); if (av != null) { // propagate shared settings to this new view - af.viewport.historyList = av.historyList; - af.viewport.redoList = av.redoList; + af.viewport.setHistoryList(av.getHistoryList()); + af.viewport.setRedoList(av.getRedoList()); } else { @@ -3654,14 +3735,17 @@ public class Jalview2XML af.viewport.hideRepSequences(al.getSequenceAt(s), hidden); } - jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs - .size()]; - - for (int s = 0; s < hiddenSeqs.size(); s++) - { - hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); - } + // jalview.datamodel.SequenceI[] hseqs = new + // jalview.datamodel.SequenceI[hiddenSeqs + // .size()]; + // + // for (int s = 0; s < hiddenSeqs.size(); s++) + // { + // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); + // } + SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs + .size()]); af.viewport.hideSequence(hseqs); } @@ -3682,27 +3766,27 @@ public class Jalview2XML af.viewport.setConservationSelected(view.getConservationSelected()); af.viewport.setShowJVSuffix(view.getShowFullId()); af.viewport.setRightAlignIds(view.getRightAlignIds()); - af.viewport.setFont(new java.awt.Font(view.getFontName(), view - .getFontStyle(), view.getFontSize())); - af.alignPanel.fontChanged(); + af.viewport.setFont( + new java.awt.Font(view.getFontName(), view.getFontStyle(), view + .getFontSize()), true); + // TODO: allow custom charWidth/Heights to be restored by updating them + // after setting font - which means set above to false af.viewport.setRenderGaps(view.getRenderGaps()); af.viewport.setWrapAlignment(view.getWrapAlignment()); - af.alignPanel.setWrapAlignment(view.getWrapAlignment()); af.viewport.setShowAnnotation(view.getShowAnnotation()); - af.alignPanel.setAnnotationVisible(view.getShowAnnotation()); af.viewport.setShowBoxes(view.getShowBoxes()); af.viewport.setShowText(view.getShowText()); - af.viewport.textColour = new java.awt.Color(view.getTextCol1()); - af.viewport.textColour2 = new java.awt.Color(view.getTextCol2()); - af.viewport.thresholdTextColour = view.getTextColThreshold(); + af.viewport.setTextColour(new java.awt.Color(view.getTextCol1())); + af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2())); + af.viewport.setThresholdTextColour(view.getTextColThreshold()); af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view .isShowUnconserved() : false); af.viewport.setStartRes(view.getStartRes()); af.viewport.setStartSeq(view.getStartSeq()); - + af.alignPanel.updateLayout(); ColourSchemeI cs = null; // apply colourschemes if (view.getBgColour() != null) @@ -3785,11 +3869,11 @@ public class Jalview2XML } if (view.hasShowDbRefTooltip()) { - af.viewport.setShowDbRefs(view.getShowDbRefTooltip()); + af.viewport.setShowDBRefs(view.getShowDbRefTooltip()); } if (view.hasShowNPfeatureTooltip()) { - af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip()); + af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip()); } if (view.hasShowGroupConsensus()) { @@ -3910,12 +3994,27 @@ public class Jalview2XML } } af.setMenusFromViewport(af.viewport); + // TODO: we don't need to do this if the viewport is aready visible. - Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), - view.getHeight()); - af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation - reorderAutoannotation(af, al, autoAlan); - af.alignPanel.alignmentChanged(); + /* + * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it + * has a 'cdna/protein complement' view, in which case save it in order to + * populate a SplitFrame once all views have been read in. + */ + String complementaryViewId = view.getComplementId(); + if (complementaryViewId == null) + { + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + // recompute any autoannotation + af.alignPanel.updateAnnotation(false, true); + reorderAutoannotation(af, al, autoAlan); + af.alignPanel.alignmentChanged(); + } + else + { + splitFrameCandidates.put(view, af); + } return af; } @@ -4045,7 +4144,7 @@ public class Jalview2XML } private void reorderAutoannotation(AlignFrame af, Alignment al, - ArrayList autoAlan) + List autoAlan) { // copy over visualization settings for autocalculated annotation in the // view @@ -4069,11 +4168,11 @@ public class Jalview2XML + auan.template.getCalcId()), auan); } int hSize = al.getAlignmentAnnotation().length; - ArrayList reorder = new ArrayList(); + List reorder = new ArrayList(); // work through any autoCalculated annotation already on the view // removing it if it should be placed in a different location on the // annotation panel. - List remains = new ArrayList(visan.keySet()); + List remains = new ArrayList(visan.keySet()); for (int h = 0; h < hSize; h++) { jalview.datamodel.AlignmentAnnotation jalan = al @@ -4245,9 +4344,8 @@ public class Jalview2XML { // JBP TODO: Check this is called for AlCodonFrames to support recovery of // xRef Codon Maps - jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds - .get(vamsasSeq.getId()); - jalview.datamodel.SequenceI dsq = null; + SequenceI sq = seqRefIds.get(vamsasSeq.getId()); + SequenceI dsq = null; if (sq != null && sq.getDatasetSequence() != null) { dsq = sq.getDatasetSequence(); @@ -4322,7 +4420,7 @@ public class Jalview2XML // if (pre || post) if (sq != dsq) { - StringBuffer sb = new StringBuffer(); + // StringBuffer sb = new StringBuffer(); String newres = jalview.analysis.AlignSeq.extractGaps( jalview.util.Comparison.GapChars, sq.getSequenceAsString()); if (!newres.equalsIgnoreCase(dsq.getSequenceAsString()) @@ -4472,14 +4570,14 @@ public class Jalview2XML * local sequence definition */ Sequence ms = mc.getSequence(); - jalview.datamodel.Sequence djs = null; + SequenceI djs = null; String sqid = ms.getDsseqid(); if (sqid != null && sqid.length() > 0) { /* * recover dataset sequence */ - djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid); + djs = seqRefIds.get(sqid); } else { @@ -4538,7 +4636,7 @@ public class Jalview2XML frefedSequence = new Vector(); } - viewportsAdded = new Hashtable(); + viewportsAdded.clear(); AlignFrame af = loadFromObject(jm, null, false, null); af.alignPanels.clear(); @@ -4685,13 +4783,9 @@ public class Jalview2XML } else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation) { - if (annotationIds == null) - { - annotationIds = new Hashtable(); - } String anid; - annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj); - jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj; + AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj; + annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann); if (jvann.annotationId == null) { jvann.annotationId = anid; diff --git a/src/jalview/gui/Jalview2XML_V1.java b/src/jalview/gui/Jalview2XML_V1.java index 586e2fa..0d73020 100755 --- a/src/jalview/gui/Jalview2XML_V1.java +++ b/src/jalview/gui/Jalview2XML_V1.java @@ -371,15 +371,14 @@ public class Jalview2XML_V1 af.viewport.setColourText(view.getShowColourText()); af.viewport.setConservationSelected(view.getConservationSelected()); af.viewport.setShowJVSuffix(view.getShowFullId()); - af.viewport.setFont(new java.awt.Font(view.getFontName(), view - .getFontStyle(), view.getFontSize())); - af.alignPanel.fontChanged(); + af.viewport.setFont( + new java.awt.Font(view.getFontName(), view.getFontStyle(), view + .getFontSize()), true); af.viewport.setRenderGaps(view.getRenderGaps()); af.viewport.setWrapAlignment(view.getWrapAlignment()); - af.alignPanel.setWrapAlignment(view.getWrapAlignment()); - af.viewport.setShowAnnotation(view.getShowAnnotation()); - af.alignPanel.setAnnotationVisible(view.getShowAnnotation()); + + af.viewport.setShowAnnotation(view.isShowAnnotation()); af.viewport.setShowBoxes(view.getShowBoxes()); af.viewport.setShowText(view.getShowText()); @@ -405,6 +404,7 @@ public class Jalview2XML_V1 af.viewport.setGlobalColourScheme(cs); af.viewport.setColourAppliesToAllGroups(false); + af.alignPanel.updateLayout(); af.changeColour(cs); if (view.getConservationSelected() && cs != null) { diff --git a/src/jalview/gui/JvSwingUtils.java b/src/jalview/gui/JvSwingUtils.java index b4e0e00..114ce50 100644 --- a/src/jalview/gui/JvSwingUtils.java +++ b/src/jalview/gui/JvSwingUtils.java @@ -22,8 +22,10 @@ package jalview.gui; import jalview.util.MessageManager; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; +import java.awt.GridLayout; import java.awt.Rectangle; import java.awt.event.ActionListener; @@ -34,6 +36,7 @@ import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; +import javax.swing.JScrollBar; import javax.swing.SwingConstants; /** @@ -122,14 +125,16 @@ public final class JvSwingUtils public static JPanel addtoLayout(JPanel panel, String tooltip, JComponent label, JComponent valBox) { - JPanel laypanel = new JPanel(), labPanel = new JPanel(), valPanel = new JPanel(); + JPanel laypanel = new JPanel(new GridLayout(1, 2)); + JPanel labPanel = new JPanel(new BorderLayout()); + JPanel valPanel = new JPanel(); // laypanel.setSize(panel.getPreferredSize()); // laypanel.setLayout(null); labPanel.setBounds(new Rectangle(7, 7, 158, 23)); valPanel.setBounds(new Rectangle(172, 7, 270, 23)); // labPanel.setLayout(new GridLayout(1,1)); // valPanel.setLayout(new GridLayout(1,1)); - labPanel.add(label); + labPanel.add(label, BorderLayout.WEST); valPanel.add(valBox); laypanel.add(labPanel); laypanel.add(valPanel); @@ -212,6 +217,53 @@ public final class JvSwingUtils } } + /** + * Returns the proportion of its range that a scrollbar's position represents, + * as a value between 0 and 1. For example if the whole range is from 0 to + * 200, then a position of 40 gives proportion = 0.2. + * + * @see http://www.javalobby.org/java/forums/t33050.html#91885334 + * + * @param scroll + * @return + */ + public static float getScrollBarProportion(JScrollBar scroll) + { + /* + * The extent (scroll handle width) deduction gives the true operating range + * of possible positions. + */ + int possibleRange = scroll.getMaximum() - scroll.getMinimum() + - scroll.getModel().getExtent(); + float valueInRange = scroll.getValue() + - (scroll.getModel().getExtent() / 2f); + float proportion = valueInRange / possibleRange; + return proportion; + } + + /** + * Returns the scroll bar position in its range that would match the given + * proportion (between 0 and 1) of the whole. For example if the whole range + * is from 0 to 200, then a proportion of 0.25 gives position 50. + * + * @param scrollbar + * @param proportion + * @return + */ + public static int getScrollValueForProportion(JScrollBar scrollbar, + float proportion) + { + /* + * The extent (scroll handle width) deduction gives the true operating range + * of possible positions. + */ + float fraction = proportion + * (scrollbar.getMaximum() - scrollbar.getMinimum() - scrollbar + .getModel().getExtent()) + + (scrollbar.getModel().getExtent() / 2f); + return Math.min(Math.round(fraction), scrollbar.getMaximum()); + } + public static void jvInitComponent(AbstractButton comp, String i18nString) { setColorAndFont(comp); diff --git a/src/jalview/gui/OverviewPanel.java b/src/jalview/gui/OverviewPanel.java index 5df60d2..3ae3cb0 100755 --- a/src/jalview/gui/OverviewPanel.java +++ b/src/jalview/gui/OverviewPanel.java @@ -22,10 +22,17 @@ package jalview.gui; import jalview.renderer.AnnotationRenderer; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import javax.swing.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.image.BufferedImage; + +import javax.swing.JPanel; /** * DOCUMENT ME! @@ -135,7 +142,7 @@ public class OverviewPanel extends JPanel implements Runnable @Override public void mouseDragged(MouseEvent evt) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { // TODO: feature: jv2.5 detect shift drag and update selection from // it. @@ -151,7 +158,7 @@ public class OverviewPanel extends JPanel implements Runnable @Override public void mousePressed(MouseEvent evt) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { boxX = evt.getX(); boxY = evt.getY(); diff --git a/src/jalview/gui/PCAPanel.java b/src/jalview/gui/PCAPanel.java index d2d6a98..412c25a 100644 --- a/src/jalview/gui/PCAPanel.java +++ b/src/jalview/gui/PCAPanel.java @@ -28,6 +28,7 @@ import jalview.datamodel.SequenceI; import jalview.jbgui.GPCAPanel; import jalview.schemes.ResidueProperties; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.PCAModel; import java.awt.BorderLayout; @@ -67,7 +68,7 @@ public class PCAPanel extends GPCAPanel implements Runnable, AlignmentPanel ap; - AlignViewport av; + AlignmentViewport av; PCAModel pcaModel; diff --git a/src/jalview/gui/PaintRefresher.java b/src/jalview/gui/PaintRefresher.java index 01dfa3b..215090b 100755 --- a/src/jalview/gui/PaintRefresher.java +++ b/src/jalview/gui/PaintRefresher.java @@ -20,12 +20,15 @@ */ package jalview.gui; -import java.util.*; -import java.util.List; - -import java.awt.*; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.awt.Component; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; /** * Route datamodel/view update events for a sequence set to any display @@ -36,57 +39,61 @@ import jalview.datamodel.*; */ public class PaintRefresher { - static Hashtable components; + static Map> components = new HashMap>(); /** - * DOCUMENT ME! + * Add the given component to those registered under the given sequence set + * id. Does nothing if already added. * * @param comp - * DOCUMENT ME! * @param al - * DOCUMENT ME! */ public static void Register(Component comp, String seqSetId) { - if (components == null) - { - components = new Hashtable(); - } - if (components.containsKey(seqSetId)) { - Vector comps = (Vector) components.get(seqSetId); + List comps = components.get(seqSetId); if (!comps.contains(comp)) { - comps.addElement(comp); + comps.add(comp); } } else { - Vector vcoms = new Vector(); - vcoms.addElement(comp); + List vcoms = new ArrayList(); + vcoms.add(comp); components.put(seqSetId, vcoms); } } + /** + * Remove this component from all registrations. Also removes a registered + * sequence set id if there are no remaining components registered against it. + * + * @param comp + */ public static void RemoveComponent(Component comp) { - if (components == null) - { - return; - } - - Enumeration en = components.keys(); - while (en.hasMoreElements()) + List emptied = new ArrayList(); + for (Entry> registered : components.entrySet()) { - String id = en.nextElement().toString(); - Vector comps = (Vector) components.get(id); + String id = registered.getKey(); + List comps = components.get(id); comps.remove(comp); - if (comps.size() == 0) + if (comps.isEmpty()) { - components.remove(id); + emptied.add(id); } } + + /* + * Remove now empty ids after the above (to avoid + * ConcurrentModificationException). + */ + for (String id : emptied) + { + components.remove(id); + } } public static void Refresh(Component source, String id) @@ -97,24 +104,15 @@ public class PaintRefresher public static void Refresh(Component source, String id, boolean alignmentChanged, boolean validateSequences) { - if (components == null) - { - return; - } - - Component comp; - Vector comps = (Vector) components.get(id); + List comps = components.get(id); if (comps == null) { return; } - Enumeration e = comps.elements(); - while (e.hasMoreElements()) + for (Component comp : comps) { - comp = (Component) e.nextElement(); - if (comp == source) { continue; @@ -242,30 +240,20 @@ public class PaintRefresher static AlignmentPanel[] getAssociatedPanels(String id) { - if (components == null) - { - return new AlignmentPanel[0]; - } - ; - Vector comps = (Vector) components.get(id); + List comps = components.get(id); if (comps == null) { return new AlignmentPanel[0]; } - ; - Vector tmp = new Vector(); - int i, iSize = comps.size(); - for (i = 0; i < iSize; i++) + List tmp = new ArrayList(); + for (Component comp : comps) { - if (comps.elementAt(i) instanceof AlignmentPanel) + if (comp instanceof AlignmentPanel) { - tmp.addElement(comps.elementAt(i)); + tmp.add((AlignmentPanel) comp); } } - AlignmentPanel[] result = new AlignmentPanel[tmp.size()]; - tmp.toArray(result); - - return result; + return tmp.toArray(new AlignmentPanel[tmp.size()]); } } diff --git a/src/jalview/gui/PairwiseAlignPanel.java b/src/jalview/gui/PairwiseAlignPanel.java index bc2c27c..29d6b71 100755 --- a/src/jalview/gui/PairwiseAlignPanel.java +++ b/src/jalview/gui/PairwiseAlignPanel.java @@ -26,6 +26,7 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.jbgui.GPairwiseAlignPanel; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.event.ActionEvent; import java.util.Vector; @@ -39,7 +40,7 @@ import java.util.Vector; public class PairwiseAlignPanel extends GPairwiseAlignPanel { - AlignViewport av; + AlignmentViewport av; Vector sequences; @@ -49,7 +50,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel * @param av * DOCUMENT ME! */ - public PairwiseAlignPanel(AlignViewport av) + public PairwiseAlignPanel(AlignmentViewport av) { super(); this.av = av; diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 8565f9f..2b1d1a0 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -2190,14 +2190,14 @@ public class PopupMenu extends JPopupMenu int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup() .getName()); - sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus()); SliderPanel.showPIDSlider(); } else // remove PIDColouring { - sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } refresh(); @@ -2548,15 +2548,7 @@ public class PopupMenu extends JPopupMenu } int gsize = sg.getSize(); - SequenceI[] hseqs; - - hseqs = new SequenceI[gsize]; - - int index = 0; - for (int i = 0; i < gsize; i++) - { - hseqs[index++] = sg.getSequenceAt(i); - } + SequenceI[] hseqs = sg.getSequences().toArray(new SequenceI[gsize]); ap.av.hideSequence(hseqs); // refresh(); TODO: ? needed ? @@ -2580,7 +2572,8 @@ public class PopupMenu extends JPopupMenu if (sg != null) { - int[][] startEnd = ap.av.getVisibleRegionBoundaries(sg.getStartRes(), + List startEnd = ap.av.getVisibleRegionBoundaries( + sg.getStartRes(), sg.getEndRes() + 1); String description; diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index c024b1c..881d02b 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -62,6 +62,12 @@ import ext.edu.ucsf.rbvi.strucviz2.StructureManager; public class Preferences extends GPreferences { + public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR"; + + public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT"; + + public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC"; + public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN"; public static final String ADD_SS_ANN = "ADD_SS_ANN"; @@ -267,10 +273,14 @@ public class Preferences extends GPreferences */ for (int i = ColourSchemeProperty.FIRST_COLOUR; i <= ColourSchemeProperty.LAST_COLOUR; i++) { - colour.addItem(ColourSchemeProperty.getColourName(i)); + protColour.addItem(ColourSchemeProperty.getColourName(i)); + nucColour.addItem(ColourSchemeProperty.getColourName(i)); } - String string = Cache.getDefault("DEFAULT_COLOUR", "None"); - colour.setSelectedItem(string); + String oldProp = Cache.getDefault(DEFAULT_COLOUR, "None"); + String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null); + protColour.setSelectedItem(newProp != null ? newProp : oldProp); + newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null); + nucColour.setSelectedItem(newProp != null ? newProp : oldProp); minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange)); maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", @@ -452,7 +462,9 @@ public class Preferences extends GPreferences /* * Save Colours settings */ - Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour + Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT, protColour + .getSelectedItem().toString()); + Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC, nucColour .getSelectedItem().toString()); Cache.setColourProperty("ANNOTATIONCOLOUR_MIN", minColour.getBackground()); diff --git a/src/jalview/gui/RedundancyPanel.java b/src/jalview/gui/RedundancyPanel.java index c8a0ec7..1b5695c 100755 --- a/src/jalview/gui/RedundancyPanel.java +++ b/src/jalview/gui/RedundancyPanel.java @@ -276,10 +276,10 @@ public class RedundancyPanel extends GSliderPanel implements Runnable } CommandI command = historyList.pop(); - if (ap.av.historyList.contains(command)) + if (ap.av.getHistoryList().contains(command)) { command.undoCommand(af.getViewAlignments()); - ap.av.historyList.remove(command); + ap.av.getHistoryList().remove(command); ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences()); af.updateEditMenuBar(); } diff --git a/src/jalview/gui/RotatableCanvas.java b/src/jalview/gui/RotatableCanvas.java index 1ff78b4..6aff578 100755 --- a/src/jalview/gui/RotatableCanvas.java +++ b/src/jalview/gui/RotatableCanvas.java @@ -30,6 +30,7 @@ import jalview.api.RotatableCanvasI; import jalview.datamodel.*; import jalview.math.*; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; /** * DOCUMENT ME! @@ -101,7 +102,7 @@ public class RotatableCanvas extends JPanel implements MouseListener, float scalefactor = 1; - AlignViewport av; + AlignmentViewport av; AlignmentPanel ap; diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index 32773b9..1eede34 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -423,6 +423,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener, // Fill the selected columns ColumnSelection cs = av.getColumnSelection(); + int avCharWidth = av.getCharWidth(), avCharHeight = av.getCharHeight(); + int s; if (cs != null) { @@ -445,7 +447,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, if ((sel >= startx) && (sel <= endx)) { - gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth, + gg.fillRect((sel - startx) * avCharWidth, 0, avCharWidth, getHeight()); } } @@ -456,7 +458,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, int scalestartx = (startx / 10) * 10; FontMetrics fm = gg.getFontMetrics(av.getFont()); - int y = av.charHeight - fm.getDescent(); + int y = avCharHeight - fm.getDescent(); if ((scalestartx % 10) == 0) { @@ -472,26 +474,22 @@ public class ScalePanel extends JPanel implements MouseMotionListener, { string = String.valueOf(av.getColumnSelection() .adjustForHiddenColumns(i)); - if ((i - startx - 1) * av.charWidth > maxX) + if ((i - startx - 1) * avCharWidth > maxX) { - gg.drawString(string, (i - startx - 1) * av.charWidth, y); - maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string); + gg.drawString(string, (i - startx - 1) * avCharWidth, y); + maxX = (i - startx + 1) * avCharWidth + fm.stringWidth(string); } - gg.drawLine( - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + gg.drawLine(((i - startx - 1) * avCharWidth) + (avCharWidth / 2), y + 2, - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + ((i - startx - 1) * avCharWidth) + (avCharWidth / 2), y + (fm.getDescent() * 2)); - } else { - gg.drawLine( - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - y + fm.getDescent(), - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - y + (fm.getDescent() * 2)); + gg.drawLine(((i - startx - 1) * avCharWidth) + (avCharWidth / 2), + y + fm.getDescent(), ((i - startx - 1) * avCharWidth) + + (avCharWidth / 2), y + (fm.getDescent() * 2)); } } @@ -515,10 +513,10 @@ public class ScalePanel extends JPanel implements MouseMotionListener, } gg.fillPolygon(new int[] - { res * av.charWidth - av.charHeight / 4, - res * av.charWidth + av.charHeight / 4, res * av.charWidth }, + { res * avCharWidth - avCharHeight / 4, + res * avCharWidth + avCharHeight / 4, res * avCharWidth }, new int[] - { y - av.charHeight / 2, y - av.charHeight / 2, y + 8 }, + { y - avCharHeight / 2, y - avCharHeight / 2, y + 8 }, 3); } @@ -527,7 +525,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, if (reveal != null && reveal[0] > startx && reveal[0] < endx) { gg.drawString(MessageManager.getString("label.reveal_columns"), - reveal[0] * av.charWidth, 0); + reveal[0] * avCharWidth, 0); } } diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index 5032f69..395e261 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -81,6 +81,7 @@ public class SeqCanvas extends JComponent public SeqCanvas(AlignmentPanel ap) { this.av = ap.av; + updateViewport(); fr = new FeatureRenderer(ap); sr = new SequenceRenderer(av); setLayout(new BorderLayout()); @@ -98,6 +99,13 @@ public class SeqCanvas extends JComponent return fr; } + int charHeight = 0, charWidth = 0; + + private void updateViewport() + { + charHeight = av.getCharHeight(); + charWidth = av.getCharWidth(); + } /** * DOCUMENT ME! * @@ -110,12 +118,12 @@ public class SeqCanvas extends JComponent * @param ypos * DOCUMENT ME! */ - void drawNorthScale(Graphics g, int startx, int endx, int ypos) + private void drawNorthScale(Graphics g, int startx, int endx, int ypos) { + updateViewport(); int scalestartx = startx - (startx % 10) + 10; g.setColor(Color.black); - // NORTH SCALE for (int i = scalestartx; i < endx; i += 10) { @@ -125,12 +133,12 @@ public class SeqCanvas extends JComponent value = av.getColumnSelection().adjustForHiddenColumns(value); } - g.drawString(String.valueOf(value), (i - startx - 1) * av.charWidth, - ypos - (av.charHeight / 2)); + g.drawString(String.valueOf(value), (i - startx - 1) * charWidth, + ypos - (charHeight / 2)); - g.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - (ypos + 2) - (av.charHeight / 2), - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + g.drawLine(((i - startx - 1) * charWidth) + (charWidth / 2), + (ypos + 2) - (charHeight / 2), ((i - startx - 1) * charWidth) + + (charWidth / 2), ypos - 2); } } @@ -150,7 +158,7 @@ public class SeqCanvas extends JComponent void drawWestScale(Graphics g, int startx, int endx, int ypos) { FontMetrics fm = getFontMetrics(av.getFont()); - ypos += av.charHeight; + ypos += charHeight; if (av.hasHiddenColumns()) { @@ -188,9 +196,9 @@ public class SeqCanvas extends JComponent if (value != -1) { int x = LABEL_WEST - fm.stringWidth(String.valueOf(value)) - - av.charWidth / 2; - g.drawString(value + "", x, (ypos + (i * av.charHeight)) - - (av.charHeight / 5)); + - charWidth / 2; + g.drawString(value + "", x, (ypos + (i * charHeight)) + - (charHeight / 5)); } } } @@ -209,7 +217,7 @@ public class SeqCanvas extends JComponent */ void drawEastScale(Graphics g, int startx, int endx, int ypos) { - ypos += av.charHeight; + ypos += charHeight; if (av.hasHiddenColumns()) { @@ -240,8 +248,8 @@ public class SeqCanvas extends JComponent if (value != -1) { - g.drawString(String.valueOf(value), 0, (ypos + (i * av.charHeight)) - - (av.charHeight / 5)); + g.drawString(String.valueOf(value), 0, (ypos + (i * charHeight)) + - (charHeight / 5)); } } } @@ -265,10 +273,9 @@ public class SeqCanvas extends JComponent } fastpainting = true; fastPaint = true; - - gg.copyArea(horizontal * av.charWidth, vertical * av.charHeight, - imgWidth, imgHeight, -horizontal * av.charWidth, -vertical - * av.charHeight); + updateViewport(); + gg.copyArea(horizontal * charWidth, vertical * charHeight, imgWidth, + imgHeight, -horizontal * charWidth, -vertical * charHeight); int sr = av.startRes; int er = av.endRes; @@ -280,7 +287,7 @@ public class SeqCanvas extends JComponent if (horizontal > 0) // scrollbar pulled right, image to the left { er++; - transX = (er - sr - horizontal) * av.charWidth; + transX = (er - sr - horizontal) * charWidth; sr = er - horizontal; } else if (horizontal < 0) @@ -297,7 +304,7 @@ public class SeqCanvas extends JComponent } else { - transY = imgHeight - (vertical * av.charHeight); + transY = imgHeight - (vertical * charHeight); } } else if (vertical < 0) @@ -330,6 +337,7 @@ public class SeqCanvas extends JComponent // Set this to false to force a full panel paint public void paintComponent(Graphics g) { + updateViewport(); BufferedImage lcimg = img; // take reference since other threads may null // img and call later. super.paintComponent(g); @@ -348,8 +356,8 @@ public class SeqCanvas extends JComponent imgWidth = getWidth(); imgHeight = getHeight(); - imgWidth -= (imgWidth % av.charWidth); - imgHeight -= (imgHeight % av.charHeight); + imgWidth -= (imgWidth % charWidth); + imgHeight -= (imgHeight % charHeight); if ((imgWidth < 1) || (imgHeight < 1)) { @@ -412,17 +420,17 @@ public class SeqCanvas extends JComponent LABEL_EAST = 0; LABEL_WEST = 0; - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { LABEL_EAST = fm.stringWidth(getMask()); } - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { LABEL_WEST = fm.stringWidth(getMask()); } - return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth; + return (cwidth - LABEL_EAST - LABEL_WEST) / charWidth; } /** @@ -466,28 +474,29 @@ public class SeqCanvas extends JComponent public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight, int startRes) { + updateViewport(); AlignmentI al = av.getAlignment(); FontMetrics fm = getFontMetrics(av.getFont()); - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { LABEL_EAST = fm.stringWidth(getMask()); } - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { LABEL_WEST = fm.stringWidth(getMask()); } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = charHeight; + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += charHeight; } - int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth; - int cHeight = av.getAlignment().getHeight() * av.charHeight; + int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / charWidth; + int cHeight = av.getAlignment().getHeight() * charHeight; av.setWrappedWidth(cWidth); @@ -514,12 +523,12 @@ public class SeqCanvas extends JComponent g.setFont(av.getFont()); g.setColor(Color.black); - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { drawWestScale(g, startRes, endx, ypos); } - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { g.translate(canvasWidth - LABEL_EAST, 0); drawEastScale(g, startRes, endx, ypos); @@ -528,12 +537,12 @@ public class SeqCanvas extends JComponent g.translate(LABEL_WEST, 0); - if (av.scaleAboveWrapped) + if (av.getScaleAboveWrapped()) { drawNorthScale(g, startRes, endx, ypos); } - if (av.hasHiddenColumns() && av.showHiddenMarkers) + if (av.hasHiddenColumns() && av.getShowHiddenMarkers()) { g.setColor(Color.blue); int res; @@ -549,11 +558,11 @@ public class SeqCanvas extends JComponent } gg.fillPolygon(new int[] - { res * av.charWidth - av.charHeight / 4, - res * av.charWidth + av.charHeight / 4, res * av.charWidth }, + { res * charWidth - charHeight / 4, + res * charWidth + charHeight / 4, res * charWidth }, new int[] - { ypos - (av.charHeight / 2), ypos - (av.charHeight / 2), - ypos - (av.charHeight / 2) + 8 }, 3); + { ypos - (charHeight / 2), ypos - (charHeight / 2), + ypos - (charHeight / 2) + 8 }, 3); } } @@ -564,11 +573,11 @@ public class SeqCanvas extends JComponent if (clip == null) { - g.setClip(0, 0, cWidth * av.charWidth, canvasHeight); + g.setClip(0, 0, cWidth * charWidth, canvasHeight); } else { - g.setClip(0, (int) clip.getBounds().getY(), cWidth * av.charWidth, + g.setClip(0, (int) clip.getBounds().getY(), cWidth * charWidth, (int) clip.getBounds().getHeight()); } @@ -632,6 +641,7 @@ public class SeqCanvas extends JComponent int startSeq, int endSeq, int offset) { + updateViewport(); if (!av.hasHiddenColumns()) { draw(g1, startRes, endRes, startSeq, endSeq, offset); @@ -644,9 +654,8 @@ public class SeqCanvas extends JComponent int blockStart = startRes; int blockEnd = endRes; - for (int i = 0; regions != null && i < regions.size(); i++) + for (int[] region : regions) { - int[] region = regions.get(i); int hideStart = region[0]; int hideEnd = region[1]; @@ -658,7 +667,7 @@ public class SeqCanvas extends JComponent blockEnd = hideStart - 1; - g1.translate(screenY * av.charWidth, 0); + g1.translate(screenY * charWidth, 0); draw(g1, blockStart, blockEnd, startSeq, endSeq, offset); @@ -666,12 +675,12 @@ public class SeqCanvas extends JComponent { g1.setColor(Color.blue); - g1.drawLine((blockEnd - blockStart + 1) * av.charWidth - 1, - 0 + offset, (blockEnd - blockStart + 1) * av.charWidth - - 1, (endSeq - startSeq) * av.charHeight + offset); + g1.drawLine((blockEnd - blockStart + 1) * charWidth - 1, + 0 + offset, (blockEnd - blockStart + 1) * charWidth - 1, + (endSeq - startSeq) * charHeight + offset); } - g1.translate(-screenY * av.charWidth, 0); + g1.translate(-screenY * charWidth, 0); screenY += blockEnd - blockStart + 1; blockStart = hideEnd + 1; } @@ -679,10 +688,10 @@ public class SeqCanvas extends JComponent if (screenY <= (endRes - startRes)) { blockEnd = blockStart + (endRes - startRes) - screenY; - g1.translate(screenY * av.charWidth, 0); + g1.translate(screenY * charWidth, 0); draw(g1, blockStart, blockEnd, startSeq, endSeq, offset); - g1.translate(-screenY * av.charWidth, 0); + g1.translate(-screenY * charWidth, 0); } } @@ -690,11 +699,12 @@ public class SeqCanvas extends JComponent // int startRes, int endRes, int startSeq, int endSeq, int x, int y, // int x1, int x2, int y1, int y2, int startx, int starty, - void draw(Graphics g, int startRes, int endRes, int startSeq, int endSeq, + private void draw(Graphics g, int startRes, int endRes, int startSeq, + int endSeq, int offset) { g.setFont(av.getFont()); - sr.prepare(g, av.renderGaps); + sr.prepare(g, av.isRenderGaps()); SequenceI nextSeq; @@ -710,12 +720,12 @@ public class SeqCanvas extends JComponent continue; } sr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq), - startRes, endRes, offset + ((i - startSeq) * av.charHeight)); + startRes, endRes, offset + ((i - startSeq) * charHeight)); if (av.isShowSequenceFeatures()) { fr.drawSequence(g, nextSeq, startRes, endRes, offset - + ((i - startSeq) * av.charHeight)); + + ((i - startSeq) * charHeight)); } // / Highlight search Results once all sequences have been drawn @@ -730,8 +740,8 @@ public class SeqCanvas extends JComponent { sr.drawHighlightedText(nextSeq, visibleResults[r], visibleResults[r + 1], (visibleResults[r] - startRes) - * av.charWidth, offset - + ((i - startSeq) * av.charHeight)); + * charWidth, offset + + ((i - startSeq) * charHeight)); } } } @@ -739,9 +749,8 @@ public class SeqCanvas extends JComponent if (av.cursorMode && cursorY == i && cursorX >= startRes && cursorX <= endRes) { - sr.drawCursor(nextSeq, cursorX, - (cursorX - startRes) * av.charWidth, offset - + ((i - startSeq) * av.charHeight)); + sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth, + offset + ((i - startSeq) * charHeight)); } } @@ -767,7 +776,7 @@ public class SeqCanvas extends JComponent int sy = -1; int ex = -1; int groupIndex = -1; - int visWidth = (endRes - startRes + 1) * av.charWidth; + int visWidth = (endRes - startRes + 1) * charWidth; if ((group == null) && (av.getAlignment().getGroups().size() > 0)) { @@ -787,16 +796,16 @@ public class SeqCanvas extends JComponent for (i = startSeq; i < endSeq; i++) { - sx = (group.getStartRes() - startRes) * av.charWidth; - sy = offset + ((i - startSeq) * av.charHeight); - ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) - 1; + sx = (group.getStartRes() - startRes) * charWidth; + sy = offset + ((i - startSeq) * charHeight); + ex = (((group.getEndRes() + 1) - group.getStartRes()) * charWidth) - 1; if (sx + ex < 0 || sx > visWidth) { continue; } - if ((sx <= (endRes - startRes) * av.charWidth) + if ((sx <= (endRes - startRes) * charWidth) && group.getSequences(null).contains( av.getAlignment().getSequenceAt(i))) { @@ -804,7 +813,7 @@ public class SeqCanvas extends JComponent && !group.getSequences(null).contains( av.getAlignment().getSequenceAt(i + 1))) { - bottom = sy + av.charHeight; + bottom = sy + charHeight; } if (!inGroup) @@ -858,9 +867,9 @@ public class SeqCanvas extends JComponent ex = visWidth; } - else if (sx + ex >= (endRes - startRes + 1) * av.charWidth) + else if (sx + ex >= (endRes - startRes + 1) * charWidth) { - ex = (endRes - startRes + 1) * av.charWidth; + ex = (endRes - startRes + 1) * charWidth; } if (top != -1) @@ -882,7 +891,7 @@ public class SeqCanvas extends JComponent if (inGroup) { - sy = offset + ((i - startSeq) * av.charHeight); + sy = offset + ((i - startSeq) * charHeight); if (sx >= 0 && sx < visWidth) { g.drawLine(sx, oldY, sx, sy); @@ -903,9 +912,9 @@ public class SeqCanvas extends JComponent { ex = visWidth; } - else if (sx + ex >= (endRes - startRes + 1) * av.charWidth) + else if (sx + ex >= (endRes - startRes + 1) * charWidth) { - ex = (endRes - startRes + 1) * av.charWidth; + ex = (endRes - startRes + 1) * charWidth; } if (top != -1) diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 7c6a202..0c24e2e 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -20,10 +20,13 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; +import jalview.commands.EditCommand.Edit; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; @@ -34,7 +37,11 @@ import jalview.structure.SelectionListener; import jalview.structure.SelectionSource; import jalview.structure.SequenceListener; import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; +import jalview.util.Comparison; +import jalview.util.MappingUtils; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; import java.awt.Color; @@ -165,16 +172,17 @@ public class SeqPanel extends JPanel implements MouseListener, int res = 0; int x = evt.getX(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); int y = evt.getY(); @@ -218,15 +226,16 @@ public class SeqPanel extends JPanel implements MouseListener, int seq = 0; int y = evt.getY(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); y -= hgap; @@ -243,22 +252,33 @@ public class SeqPanel extends JPanel implements MouseListener, return seq; } + /** + * When all of a sequence of edits are complete, put the resulting edit list + * on the history stack (undo list), and reset flags for editing in progress. + */ void endEditing() { - if (editCommand != null && editCommand.getSize() > 0) + try + { + if (editCommand != null && editCommand.getSize() > 0) + { + ap.alignFrame.addHistoryItem(editCommand); + av.firePropertyChange("alignment", null, av.getAlignment() + .getSequences()); + } + } finally { - ap.alignFrame.addHistoryItem(editCommand); - av.firePropertyChange("alignment", null, av.getAlignment() - .getSequences()); + /* + * Tidy up come what may... + */ + startseq = -1; + lastres = -1; + editingSeqs = false; + groupEditing = false; + keyboardNo1 = null; + keyboardNo2 = null; + editCommand = null; } - - startseq = -1; - lastres = -1; - editingSeqs = false; - groupEditing = false; - keyboardNo1 = null; - keyboardNo2 = null; - editCommand = null; } void setCursorRow() @@ -342,7 +362,7 @@ public class SeqPanel extends JPanel implements MouseListener, } endEditing(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { ap.scrollToWrappedVisible(seqCanvas.cursorX); } @@ -356,7 +376,7 @@ public class SeqPanel extends JPanel implements MouseListener, { ap.scrollUp(false); } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { while (seqCanvas.cursorX < av.getColumnSelection() .adjustForHiddenColumns(av.startRes)) @@ -634,10 +654,16 @@ public class SeqPanel extends JPanel implements MouseListener, seqCanvas.revalidate(); } } + setStatusMessage(results); seqCanvas.highlightSearchResults(results); } @Override + public VamsasSource getVamsasSource() + { + return this.ap == null ? null : this.ap.av; + } + @Override public void updateColours(SequenceI seq, int index) { System.out.println("update the seqPanel colours"); @@ -774,42 +800,72 @@ public class SeqPanel extends JPanel implements MouseListener, */ int setStatusMessage(SequenceI sequence, int res, int seq) { - int pos = -1; - StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " - + sequence.getName()); + StringBuilder text = new StringBuilder(32); - Object obj = null; + /* + * Sequence number (if known), and sequence name. + */ + String seqno = seq == -1 ? "" : " " + (seq + 1); + text.append("Sequence" + seqno + " ID: " + sequence.getName()); + + String residue = null; + /* + * Try to translate the display character to residue name (null for gap). + */ + final String displayChar = String.valueOf(sequence.getCharAt(res)); if (av.getAlignment().isNucleotide()) { - obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) - + ""); - if (obj != null) + residue = ResidueProperties.nucleotideName.get(displayChar); + if (residue != null) { - text.append(" Nucleotide: "); + text.append(" Nucleotide: ").append(residue); } } else { - obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + ""); - if (obj != null) + residue = "X".equalsIgnoreCase(displayChar) ? "X" + : ResidueProperties.aa2Triplet.get(displayChar); + if (residue != null) { - text.append(" Residue: "); + text.append(" Residue: ").append(residue); } } - if (obj != null) + int pos = -1; + if (residue != null) { pos = sequence.findPosition(res); - if (obj != "") - { - text.append(obj + " (" + pos + ")"); - } + text.append(" (").append(Integer.toString(pos)).append(")"); } ap.alignFrame.statusBar.setText(text.toString()); return pos; } /** + * Set the status bar message to highlight the first matched position in + * search results. + * + * @param results + */ + private void setStatusMessage(SearchResults results) + { + List matches = results.getResults(); + if (!matches.isEmpty()) + { + Match m = matches.get(0); + SequenceI seq = m.getSequence(); + int sequenceIndex = this.av.getAlignment().findIndex(seq); + + /* + * Convert position in sequence (base 1) to sequence character array index + * (base 0) + */ + int start = m.getStart() - 1; + setStatusMessage(seq, start, sequenceIndex); + } + } + + /** * DOCUMENT ME! * * @param evt @@ -820,7 +876,7 @@ public class SeqPanel extends JPanel implements MouseListener, { if (mouseWheelPressed) { - int oldWidth = av.charWidth; + int oldWidth = av.getCharWidth(); // Which is bigger, left-right or up-down? if (Math.abs(evt.getY() - lastMousePress.getY()) > Math.abs(evt @@ -842,26 +898,28 @@ public class SeqPanel extends JPanel implements MouseListener, fontSize = 1; } - av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize)); - av.charWidth = oldWidth; + av.setFont( + new Font(av.font.getName(), av.font.getStyle(), fontSize), + true); + av.setCharWidth(oldWidth); ap.fontChanged(); } else { - if (evt.getX() < lastMousePress.getX() && av.charWidth > 1) + if (evt.getX() < lastMousePress.getX() && av.getCharWidth() > 1) { - av.charWidth--; + av.setCharWidth(av.getCharWidth() - 1); } else if (evt.getX() > lastMousePress.getX()) { - av.charWidth++; + av.setCharWidth(av.getCharWidth() + 1); } ap.paintAlignment(false); } FontMetrics fm = getFontMetrics(av.getFont()); - av.validCharWidth = fm.charWidth('M') <= av.charWidth; + av.validCharWidth = fm.charWidth('M') <= av.getCharWidth(); lastMousePress = evt.getPoint(); @@ -924,7 +982,7 @@ public class SeqPanel extends JPanel implements MouseListener, } } - StringBuffer message = new StringBuffer(); + StringBuilder message = new StringBuilder(64); if (groupEditing) { message.append("Edit group:"); @@ -1149,8 +1207,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.INSERT_GAP, groupSeqs, - startres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, groupSeqs, startres, startres + - lastres); } } else @@ -1165,8 +1223,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.DELETE_GAP, groupSeqs, - startres, lastres - startres, av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, groupSeqs, startres, lastres + - startres); } } @@ -1187,8 +1245,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[] - { seq }, lastres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, new SequenceI[] + { seq }, lastres, startres - lastres); } } else @@ -1200,7 +1258,7 @@ public class SeqPanel extends JPanel implements MouseListener, { for (int j = lastres; j > startres; j--) { - if (!jalview.util.Comparison.isGap(seq.getCharAt(startres))) + if (!Comparison.isGap(seq.getCharAt(startres))) { endEditing(); break; @@ -1215,7 +1273,7 @@ public class SeqPanel extends JPanel implements MouseListener, int max = 0; for (int m = startres; m < lastres; m++) { - if (!jalview.util.Comparison.isGap(seq.getCharAt(m))) + if (!Comparison.isGap(seq.getCharAt(m))) { break; } @@ -1224,9 +1282,8 @@ public class SeqPanel extends JPanel implements MouseListener, if (max > 0) { - editCommand.appendEdit(Action.DELETE_GAP, - new SequenceI[] - { seq }, startres, max, av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, new SequenceI[] + { seq }, startres, max); } } } @@ -1242,8 +1299,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.INSERT_NUC, new SequenceI[] - { seq }, lastres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_NUC, new SequenceI[] + { seq }, lastres, startres - lastres); } } } @@ -1278,22 +1335,37 @@ public class SeqPanel extends JPanel implements MouseListener, } } - editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1, - av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, seq, blankColumn, 1); - editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1, - av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, seq, j, 1); } + /** + * Helper method to add and perform one edit action. + * + * @param action + * @param seq + * @param pos + * @param count + */ + protected void appendEdit(Action action, SequenceI[] seq, int pos, + int count) + { + + final Edit edit = new EditCommand().new Edit(action, seq, pos, count, + av.getAlignment().getGapCharacter()); + + editCommand.appendEdit(edit, av.getAlignment(), + true, null); + } + void deleteChar(int j, SequenceI[] seq, int fixedColumn) { - editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1, - av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, seq, j, 1); - editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1, - av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1); } /** @@ -1416,7 +1488,7 @@ public class SeqPanel extends JPanel implements MouseListener, startWrapBlock = wrappedBlock; - if (av.wrapAlignment && seq > av.getAlignment().getHeight()) + if (av.getWrapAlignment() && seq > av.getAlignment().getHeight()) { JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager .getString("label.cannot_edit_annotations_in_wrapped_view"), @@ -1799,52 +1871,68 @@ public class SeqPanel extends JPanel implements MouseListener, // handles selection messages... // TODO: extend config options to allow user to control if selections may be // shared between viewports. - if (av == source - || !av.followSelection - || (av.isSelectionGroupChanged(false) || av - .isColSelChanged(false)) - || (source instanceof AlignViewport && ((AlignViewport) source) - .getSequenceSetId().equals(av.getSequenceSetId()))) + boolean iSentTheSelection = (av == source + || (source instanceof AlignViewport && ((AlignmentViewport) source) + .getSequenceSetId().equals(av.getSequenceSetId()))); + if (iSentTheSelection || !av.followSelection) + { + return; + } + + /* + * Ignore the selection if there is one of our own pending. + */ + if (av.isSelectionGroupChanged(false) || av.isColSelChanged(false)) + { + return; + } + + /* + * Check for selection in a view of which this one is a dna/protein + * complement. + */ + if (selectionFromTranslation(seqsel, colsel, source)) { return; } + // do we want to thread this ? (contention with seqsel and colsel locks, I // suspect) // rules are: colsel is copied if there is a real intersection between // sequence selection - boolean repaint = false, copycolsel = true; - // if (!av.isSelectionGroupChanged(false)) + boolean repaint = false; + boolean copycolsel = true; + + SequenceGroup sgroup = null; + if (seqsel != null && seqsel.getSize() > 0) { - SequenceGroup sgroup = null; - if (seqsel != null && seqsel.getSize() > 0) - { - if (av.getAlignment() == null) - { - jalview.bin.Cache.log.warn("alignviewport av SeqSetId=" - + av.getSequenceSetId() + " ViewId=" + av.getViewId() - + " 's alignment is NULL! returning immediatly."); - return; - } - sgroup = seqsel.intersect(av.getAlignment(), - (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); - if ((sgroup == null || sgroup.getSize() == 0) - || (colsel == null || colsel.size() == 0)) - { - // don't copy columns if the region didn't intersect. - copycolsel = false; - } - } - if (sgroup != null && sgroup.getSize() > 0) + if (av.getAlignment() == null) { - av.setSelectionGroup(sgroup); + jalview.bin.Cache.log.warn("alignviewport av SeqSetId=" + + av.getSequenceSetId() + " ViewId=" + av.getViewId() + + " 's alignment is NULL! returning immediately."); + return; } - else + sgroup = seqsel.intersect(av.getAlignment(), + (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); + if ((sgroup == null || sgroup.getSize() == 0) + || (colsel == null || colsel.size() == 0)) { - av.setSelectionGroup(null); + // don't copy columns if the region didn't intersect. + copycolsel = false; } - av.isSelectionGroupChanged(true); - repaint = true; } + if (sgroup != null && sgroup.getSize() > 0) + { + av.setSelectionGroup(sgroup); + } + else + { + av.setSelectionGroup(null); + } + av.isSelectionGroupChanged(true); + repaint = true; + if (copycolsel) { // the current selection is unset or from a previous message @@ -1872,6 +1960,7 @@ public class SeqPanel extends JPanel implements MouseListener, av.isColSelChanged(true); repaint = true; } + if (copycolsel && av.hasHiddenColumns() && (av.getColumnSelection() == null || av.getColumnSelection() @@ -1879,11 +1968,52 @@ public class SeqPanel extends JPanel implements MouseListener, { System.err.println("Bad things"); } - if (repaint) + if (repaint) // always true! { // probably finessing with multiple redraws here PaintRefresher.Refresh(this, av.getSequenceSetId()); // ap.paintAlignment(false); } } + + /** + * If this panel is a cdna/protein translation view of the selection source, + * tries to map the source selection to a local one, and returns true. Else + * returns false. + * + * @param seqsel + * @param colsel + * @param source + */ + protected boolean selectionFromTranslation(SequenceGroup seqsel, + ColumnSelection colsel, SelectionSource source) + { + if (!(source instanceof AlignViewportI)) { + return false; + } + final AlignViewportI sourceAv = (AlignViewportI) source; + if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv) + { + return false; + } + + /* + * Map sequence selection + */ + SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av); + av.setSelectionGroup(sg); + av.isSelectionGroupChanged(true); + + /* + * Map column selection + */ + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv, + av); + av.setColumnSelection(cs); + av.isColSelChanged(true); + + PaintRefresher.Refresh(this, av.getSequenceSetId()); + + return true; + } } diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index 35bc29a..e159d41 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -20,24 +20,42 @@ */ package jalview.gui; -import java.util.*; -import java.util.List; - -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; - -import com.stevesoft.pat.Regex; - -import jalview.datamodel.*; -import jalview.io.*; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceI; +import jalview.io.FormatAdapter; +import jalview.io.IdentifyFile; import jalview.util.DBRefUtils; import jalview.util.MessageManager; import jalview.ws.dbsources.das.api.DasSourceRegistryI; import jalview.ws.seqfetcher.DbSourceProxy; + import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingConstants; +import javax.swing.tree.DefaultMutableTreeNode; + +import com.stevesoft.pat.Regex; public class SequenceFetcher extends JPanel implements Runnable { @@ -283,7 +301,9 @@ public class SequenceFetcher extends JPanel implements Runnable public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) + { ok_actionPerformed(); + } } }); jPanel3.setLayout(borderLayout1); @@ -821,21 +841,7 @@ public class SequenceFetcher extends JPanel implements Runnable } else { - for (int i = 0; i < al.getHeight(); i++) - { - alignFrame.viewport.getAlignment().addSequence( - al.getSequenceAt(i)); // this - // also - // creates - // dataset - // sequence - // entries - } - alignFrame.viewport.setEndSeq(alignFrame.viewport.getAlignment() - .getHeight()); - alignFrame.viewport.getAlignment().getWidth(); - alignFrame.viewport.firePropertyChange("alignment", null, - alignFrame.viewport.getAlignment().getSequences()); + alignFrame.viewport.addAlignment(al, title); } } return al; diff --git a/src/jalview/gui/SequenceRenderer.java b/src/jalview/gui/SequenceRenderer.java index 438ef00..94a4115 100755 --- a/src/jalview/gui/SequenceRenderer.java +++ b/src/jalview/gui/SequenceRenderer.java @@ -21,7 +21,6 @@ package jalview.gui; import jalview.api.FeatureRenderer; -import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeI; @@ -81,7 +80,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer // If EPS graphics, stringWidth will be a double, not an int double dwidth = fm.getStringBounds("M", g).getWidth(); - monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth() && av.charWidth == dwidth); + monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth() && av + .getCharWidth() == dwidth); this.renderGaps = renderGaps; } @@ -222,7 +222,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer int length = seq.getLength(); int curStart = -1; - int curWidth = av.charWidth; + int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(), avHeight = av + .getCharHeight(); Color tempColour = null; @@ -250,26 +251,25 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (tempColour != null) { - graphics.fillRect(av.charWidth * (curStart - start), y1, - curWidth, av.charHeight); + graphics.fillRect(avWidth * (curStart - start), y1, curWidth, + avHeight); } graphics.setColor(resBoxColour); curStart = i; - curWidth = av.charWidth; + curWidth = avWidth; tempColour = resBoxColour; } else { - curWidth += av.charWidth; + curWidth += avWidth; } i++; } - graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, - av.charHeight); + graphics.fillRect(avWidth * (curStart - start), y1, curWidth, avHeight); } @@ -293,7 +293,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer */ public void drawText(SequenceI seq, int start, int end, int y1) { - y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady + y1 += av.getCharHeight() - av.getCharHeight() / 5; // height/5 replaces pady int charOffset = 0; char s; @@ -301,12 +301,12 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { end = seq.getLength() - 1; } - graphics.setColor(av.textColour); + graphics.setColor(av.getTextColour()); - if (monospacedFont && av.showText && allGroups.length == 0 - && !av.getColourText() && av.thresholdTextColour == 0) + if (monospacedFont && av.getShowText() && allGroups.length == 0 + && !av.getColourText() && av.getThresholdTextColour() == 0) { - if (av.renderGaps) + if (av.isRenderGaps()) { graphics.drawString(seq.getSequenceAsString(start, end + 1), 0, y1); } @@ -323,7 +323,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer boolean getboxColour = false; for (int i = start; i <= end; i++) { - graphics.setColor(av.textColour); + graphics.setColor(av.getTextColour()); getboxColour = false; s = seq.getCharAt(i); if (!renderGaps && jalview.util.Comparison.isGap(s)) @@ -393,7 +393,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } } - if (av.thresholdTextColour > 0) + if (av.getThresholdTextColour() > 0) { if (!getboxColour) { @@ -401,9 +401,9 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } if (resBoxColour.getRed() + resBoxColour.getBlue() - + resBoxColour.getGreen() < av.thresholdTextColour) + + resBoxColour.getGreen() < av.getThresholdTextColour()) { - graphics.setColor(av.textColour2); + graphics.setColor(av.getTextColour2()); } } if (av.getShowUnconserved()) @@ -415,8 +415,9 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } - charOffset = (av.charWidth - fm.charWidth(s)) / 2; - graphics.drawString(String.valueOf(s), charOffset + av.charWidth + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; + graphics.drawString(String.valueOf(s), + charOffset + av.getCharWidth() * (i - start), y1); } @@ -487,17 +488,17 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.BLACK); - graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), - av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth() * (end - start + 1), + av.getCharHeight()); graphics.setColor(Color.white); char s = '~'; // Need to find the sequence position here. - if (av.validCharWidth) + if (av.isValidCharWidth()) { for (int i = start; i <= end; i++) { @@ -506,29 +507,30 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer s = seq.getCharAt(i); } - charOffset = (av.charWidth - fm.charWidth(s)) / 2; - graphics.drawString(String.valueOf(s), charOffset + x1 - + (av.charWidth * (i - start)), (y1 + av.charHeight) - pady); + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; + graphics.drawString(String.valueOf(s), + charOffset + x1 + (av.getCharWidth() * (i - start)), + (y1 + av.getCharHeight()) - pady); } } } public void drawCursor(SequenceI seq, int res, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.charWidth, av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); - if (av.validCharWidth) + if (av.isValidCharWidth()) { graphics.setColor(Color.white); char s = seq.getCharAt(res); - charOffset = (av.charWidth - fm.charWidth(s)) / 2; + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; graphics.drawString(String.valueOf(s), charOffset + x1, - (y1 + av.charHeight) - pady); + (y1 + av.getCharHeight()) - pady); } } diff --git a/src/jalview/gui/SliderPanel.java b/src/jalview/gui/SliderPanel.java index cbd0d58..970ca3f 100755 --- a/src/jalview/gui/SliderPanel.java +++ b/src/jalview/gui/SliderPanel.java @@ -20,16 +20,20 @@ */ package jalview.gui; -import java.util.*; +import jalview.datamodel.SequenceGroup; +import jalview.jbgui.GSliderPanel; +import jalview.schemes.ColourSchemeI; +import jalview.util.MessageManager; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Iterator; -import jalview.datamodel.*; -import jalview.jbgui.*; -import jalview.schemes.*; -import jalview.util.MessageManager; +import javax.swing.JInternalFrame; +import javax.swing.JLayeredPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; /** * DOCUMENT ME! @@ -286,13 +290,15 @@ public class SliderPanel extends GSliderPanel } else { - toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus()); + toChange.setThreshold(i, ap.av.isIgnoreGapsConsensus()); } if (allGroups != null && allGroups.hasNext()) { while ((toChange = allGroups.next().cs) == null && allGroups.hasNext()) + { ; + } } else { diff --git a/src/jalview/gui/SplitFrame.java b/src/jalview/gui/SplitFrame.java new file mode 100644 index 0000000..9cbded9 --- /dev/null +++ b/src/jalview/gui/SplitFrame.java @@ -0,0 +1,579 @@ +package jalview.gui; + +import jalview.api.SplitContainerI; +import jalview.api.ViewStyleI; +import jalview.datamodel.AlignmentI; +import jalview.jbgui.GAlignFrame; +import jalview.jbgui.GSplitFrame; +import jalview.structure.StructureSelectionManager; +import jalview.viewmodel.AlignmentViewport; + +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.beans.PropertyVetoException; +import java.util.Map.Entry; + +import javax.swing.AbstractAction; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; +import javax.swing.event.InternalFrameAdapter; +import javax.swing.event.InternalFrameEvent; + +/** + * An internal frame on the desktop that hosts a horizontally split view of + * linked DNA and Protein alignments. Additional views can be created in linked + * pairs, expanded to separate split frames, or regathered into a single frame. + *

+ * (Some) operations on each alignment are automatically mirrored on the other. + * These include mouseover (highlighting), sequence and column selection, + * sequence ordering and sorting, and grouping, colouring and sorting by tree. + * + * @author gmcarstairs + * + */ +public class SplitFrame extends GSplitFrame implements SplitContainerI +{ + private static final long serialVersionUID = 1L; + + public SplitFrame(GAlignFrame top, GAlignFrame bottom) + { + super(top, bottom); + init(); + } + + /** + * Initialise this frame. + */ + protected void init() + { + getTopFrame().setSplitFrame(this); + getBottomFrame().setSplitFrame(this); + getTopFrame().setVisible(true); + getBottomFrame().setVisible(true); + + ((AlignFrame) getTopFrame()).getViewport().setCodingComplement( + ((AlignFrame) getBottomFrame()).getViewport()); + + setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20); + + adjustLayout(); + + addCloseFrameListener(); + + addKeyListener(); + + addKeyBindings(); + + addCommandListeners(); + } + + /** + * Set the top and bottom frames to listen to each others Commands (e.g. Edit, + * Order). + */ + protected void addCommandListeners() + { + // TODO if CommandListener is only ever 1:1 for complementary views, + // may change broadcast pattern to direct messaging (more efficient) + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addCommandListener(((AlignFrame) getTopFrame()).getViewport()); + ssm.addCommandListener(((AlignFrame) getBottomFrame()).getViewport()); + } + + /** + * Do any tweaking and twerking of the layout wanted. + */ + private void adjustLayout() + { + /* + * Ensure sequence ids are the same width for good alignment. + */ + int w1 = ((AlignFrame) getTopFrame()).getViewport().getIdWidth(); + int w2 = ((AlignFrame) getBottomFrame()).getViewport().getIdWidth(); + int w3 = Math.max(w1, w2); + if (w1 != w3) + { + ((AlignFrame) getTopFrame()).getViewport().setIdWidth(w3); + } + if (w2 != w3) + { + ((AlignFrame) getBottomFrame()).getViewport().setIdWidth(w3); + } + + /* + * Set the character width for protein to 3 times that for dna. + */ + final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport; + final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport; + final AlignmentI topAlignment = topViewport.getAlignment(); + final AlignmentI bottomAlignment = bottomViewport.getAlignment(); + AlignmentViewport cdna = topAlignment.isNucleotide() ? topViewport + : (bottomAlignment.isNucleotide() ? bottomViewport : null); + AlignmentViewport protein = !topAlignment.isNucleotide() ? topViewport + : (!bottomAlignment.isNucleotide() ? bottomViewport : null); + if (protein != null && cdna != null) + { + ViewStyleI vs = cdna.getViewStyle(); + vs.setCharWidth(3 * vs.getCharWidth()); + protein.setViewStyle(vs); + } + } + + /** + * Add a listener to tidy up when the frame is closed. + */ + protected void addCloseFrameListener() + { + addInternalFrameListener(new InternalFrameAdapter() + { + @Override + public void internalFrameClosed(InternalFrameEvent evt) + { + if (getTopFrame() instanceof AlignFrame) + { + ((AlignFrame) getTopFrame()) + .closeMenuItem_actionPerformed(true); + } + if (getBottomFrame() instanceof AlignFrame) + { + ((AlignFrame) getBottomFrame()) + .closeMenuItem_actionPerformed(true); + } + }; + }); + } + + /** + * Add a key listener that delegates to whichever split component the mouse is + * in (or does nothing if neither). + */ + protected void addKeyListener() + { + addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) + { + AlignFrame af = (AlignFrame) getFrameAtMouse(); + + /* + * Intercept and override any keys here if wanted. + */ + if (!overrideKey(e, af)) + { + if (af != null) + { + for (KeyListener kl : af.getKeyListeners()) + { + kl.keyPressed(e); + } + } + } + } + + @Override + public void keyReleased(KeyEvent e) + { + Component c = getFrameAtMouse(); + if (c != null) + { + for (KeyListener kl : c.getKeyListeners()) + { + kl.keyReleased(e); + } + } + } + + }); + } + + /** + * Returns true if the key event is overriden and actioned (or ignored) here, + * else returns false, indicating it should be delegated to the AlignFrame's + * usual handler. + *

+ * We can't handle Cmd-Key combinations here, instead this is done by + * overriding key bindings. + * + * @see addKeyOverrides + * @param e + * @param af + * @return + */ + protected boolean overrideKey(KeyEvent e, AlignFrame af) + { + boolean actioned = false; + int keyCode = e.getKeyCode(); + switch (keyCode) + { + case KeyEvent.VK_DOWN: + if (e.isAltDown() || !af.viewport.cursorMode) + { + /* + * Key down (or Alt-key-down in cursor mode) - move selected sequences + */ + ((AlignFrame) getTopFrame()).moveSelectedSequences(false); + ((AlignFrame) getBottomFrame()).moveSelectedSequences(false); + actioned = true; + e.consume(); + } + break; + case KeyEvent.VK_UP: + if (e.isAltDown() || !af.viewport.cursorMode) + { + /* + * Key up (or Alt-key-up in cursor mode) - move selected sequences + */ + ((AlignFrame) getTopFrame()).moveSelectedSequences(true); + ((AlignFrame) getBottomFrame()).moveSelectedSequences(true); + actioned = true; + e.consume(); + } + default: + } + return actioned; + } + + /** + * Set key bindings (recommended for Swing over key accelerators). + */ + private void addKeyBindings() + { + overrideDelegatedKeyBindings(); + + overrideImplementedKeyBindings(); + } + + /** + * Override key bindings with alternative action methods implemented in this + * class. + */ + protected void overrideImplementedKeyBindings() + { + overrideNewView(); + overrideCloseView(); + overrideExpandViews(); + overrideGatherViews(); + } + + /** + * Replace Cmd-W close view action with our version. + */ + protected void overrideCloseView() + { + AbstractAction action; + /* + * Ctrl-W / Cmd-W - close view or window + */ + KeyStroke key_cmdW = KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + closeView_actionPerformed(); + } + }; + overrideKeyBinding(key_cmdW, action); + } + + /** + * Replace Cmd-T new view action with our version. + */ + protected void overrideNewView() + { + /* + * Ctrl-T / Cmd-T open new view + */ + KeyStroke key_cmdT = KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + newView_actionPerformed(); + } + }; + overrideKeyBinding(key_cmdT, action); + } + + /** + * For now, delegates key events to the corresponding key accelerator for the + * AlignFrame that the mouse is in. Hopefully can be simplified in future if + * AlignFrame is changed to use key bindings rather than accelerators. + */ + protected void overrideDelegatedKeyBindings() + { + if (getTopFrame() instanceof AlignFrame) + { + /* + * Get all accelerator keys in the top frame (the bottom should be + * identical) and override each one. + */ + for (Entry acc : ((AlignFrame) getTopFrame()) + .getAccelerators().entrySet()) + { + overrideKeyBinding(acc); + } + } + } + + /** + * Overrides an AlignFrame key accelerator with our version which delegates to + * the action listener in whichever frame has the mouse (and does nothing if + * neither has). + * + * @param acc + */ + private void overrideKeyBinding(Entry acc) + { + final KeyStroke ks = acc.getKey(); + InputMap inputMap = this.getInputMap(JComponent.WHEN_FOCUSED); + inputMap.put(ks, ks); + this.getActionMap().put(ks, new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + Component c = getFrameAtMouse(); + if (c != null && c instanceof AlignFrame) + { + for (ActionListener a : ((AlignFrame) c).getAccelerators() + .get(ks).getActionListeners()) + { + a.actionPerformed(null); + } + } + } + }); + } + + /** + * Replace an accelerator key's action with the specified action. + * + * @param ks + */ + protected void overrideKeyBinding(KeyStroke ks, AbstractAction action) + { + this.getActionMap().put(ks, action); + overrideMenuItem(ks, action); + } + + /** + * Create and link new views (with matching names) in both panes. + *

+ * Note this is _not_ multiple tabs, each hosting a split pane view, rather it + * is a single split pane with each split holding multiple tabs which are + * linked in pairs. + *

+ * TODO implement instead with a tabbed holder in the SplitView, each tab + * holding a single JSplitPane. Would avoid a duplicated tab, at the cost of + * some additional coding. + */ + protected void newView_actionPerformed() + { + AlignFrame topFrame = (AlignFrame) getTopFrame(); + AlignFrame bottomFrame = (AlignFrame) getBottomFrame(); + + AlignmentPanel newTopPanel = topFrame.newView(null, true); + AlignmentPanel newBottomPanel = bottomFrame.newView(null, true); + + /* + * This currently (for the first new view only) leaves the top pane on tab 0 + * but the bottom on tab 1. This results from 'setInitialTabVisible' echoing + * from the bottom back to the first frame. Next line is a fudge to work + * around this. TODO find a better way. + */ + if (topFrame.getTabIndex() != bottomFrame.getTabIndex()) + { + topFrame.setDisplayedView(newTopPanel); + } + + newBottomPanel.av.viewName = newTopPanel.av.viewName; + newTopPanel.av.setCodingComplement(newBottomPanel.av); + + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addCommandListener(newTopPanel.av); + ssm.addCommandListener(newBottomPanel.av); + } + + /** + * Close the currently selected view in both panes. If there is only one view, + * close this split frame. + */ + protected void closeView_actionPerformed() + { + int viewCount = ((AlignFrame) getTopFrame()).getAlignPanels().size(); + if (viewCount < 2) + { + close(); + return; + } + + AlignmentPanel topPanel = ((AlignFrame) getTopFrame()).alignPanel; + AlignmentPanel bottomPanel = ((AlignFrame) getBottomFrame()).alignPanel; + + ((AlignFrame) getTopFrame()).closeView(topPanel); + ((AlignFrame) getBottomFrame()).closeView(bottomPanel); + + } + + /** + * Close child frames and this split frame. + */ + public void close() + { + ((AlignFrame) getTopFrame()).closeMenuItem_actionPerformed(true); + ((AlignFrame) getBottomFrame()).closeMenuItem_actionPerformed(true); + try + { + this.setClosed(true); + } catch (PropertyVetoException e) + { + // ignore + } + } + + /** + * Replace AlignFrame 'expand views' action with SplitFrame version. + */ + protected void overrideExpandViews() + { + KeyStroke key_X = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + expandViews_actionPerformed(); + } + }; + overrideMenuItem(key_X, action); + } + + /** + * Replace AlignFrame 'gather views' action with SplitFrame version. + */ + protected void overrideGatherViews() + { + KeyStroke key_G = KeyStroke.getKeyStroke(KeyEvent.VK_G, 0, false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + gatherViews_actionPerformed(); + } + }; + overrideMenuItem(key_G, action); + } + + /** + * Override the menu action associated with the keystroke in the child frames, + * replacing it with the given action. + * + * @param ks + * @param action + */ + private void overrideMenuItem(KeyStroke ks, AbstractAction action) + { + overrideMenuItem(ks, action, getTopFrame()); + overrideMenuItem(ks, action, getBottomFrame()); + } + + /** + * Override the menu action associated with the keystroke in one child frame, + * replacing it with the given action. Mwahahahaha. + * + * @param key + * @param action + * @param comp + */ + private void overrideMenuItem(KeyStroke key, final AbstractAction action, + JComponent comp) + { + if (comp instanceof AlignFrame) + { + JMenuItem mi = ((AlignFrame) comp).getAccelerators().get(key); + if (mi != null) + { + for (ActionListener al : mi.getActionListeners()) + { + mi.removeActionListener(al); + } + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + action.actionPerformed(e); + } + }); + } + } + } + + /** + * Expand any multiple views (which are always in pairs) into separate split + * frames. + */ + protected void expandViews_actionPerformed() + { + Desktop.instance.explodeViews(this); + } + + /** + * Gather any other SplitFrame views of this alignment back in as multiple + * (pairs of) views in this SplitFrame. + */ + protected void gatherViews_actionPerformed() + { + Desktop.instance.gatherViews(this); + } + + /** + * Returns the alignment in the complementary frame to the one given. + */ + @Override + public AlignmentI getComplement(Object alignFrame) + { + if (alignFrame == this.getTopFrame()) + { + return ((AlignFrame) getBottomFrame()).viewport.getAlignment(); + } + else if (alignFrame == this.getBottomFrame()) + { + return ((AlignFrame) getTopFrame()).viewport.getAlignment(); + } + return null; + } + + /** + * Returns the title of the complementary frame to the one given. + */ + @Override + public String getComplementTitle(Object alignFrame) + { + if (alignFrame == this.getTopFrame()) + { + return ((AlignFrame) getBottomFrame()).getTitle(); + } + else if (alignFrame == this.getBottomFrame()) + { + return ((AlignFrame) getTopFrame()).getTitle(); + } + return null; + } +} + diff --git a/src/jalview/gui/TextColourChooser.java b/src/jalview/gui/TextColourChooser.java index 4315e0b..f88ef5b 100644 --- a/src/jalview/gui/TextColourChooser.java +++ b/src/jalview/gui/TextColourChooser.java @@ -20,14 +20,24 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; - -import jalview.datamodel.*; +import jalview.datamodel.SequenceGroup; import jalview.util.MessageManager; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JColorChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + public class TextColourChooser { AlignmentPanel ap; @@ -42,9 +52,9 @@ public class TextColourChooser int original1, original2, originalThreshold; if (sg == null) { - original1 = ap.av.textColour.getRGB(); - original2 = ap.av.textColour2.getRGB(); - originalThreshold = ap.av.thresholdTextColour; + original1 = ap.av.getTextColour().getRGB(); + original2 = ap.av.getTextColour2().getRGB(); + originalThreshold = ap.av.getThresholdTextColour(); } else { @@ -119,9 +129,9 @@ public class TextColourChooser { if (sg == null) { - ap.av.textColour = new Color(original1); - ap.av.textColour2 = new Color(original2); - ap.av.thresholdTextColour = originalThreshold; + ap.av.setTextColour(new Color(original1)); + ap.av.setTextColour2(new Color(original2)); + ap.av.setThresholdTextColour(originalThreshold); } else { @@ -136,7 +146,7 @@ public class TextColourChooser { if (sg == null) { - ap.av.textColour = col; + ap.av.setTextColour(col); if (ap.av.getColourAppliesToAllGroups()) { setGroupTextColour(); @@ -154,7 +164,7 @@ public class TextColourChooser { if (sg == null) { - ap.av.textColour2 = col; + ap.av.setTextColour2(col); if (ap.av.getColourAppliesToAllGroups()) { setGroupTextColour(); @@ -172,7 +182,7 @@ public class TextColourChooser { if (sg == null) { - ap.av.thresholdTextColour = value; + ap.av.setThresholdTextColour(value); if (ap.av.getColourAppliesToAllGroups()) { setGroupTextColour(); @@ -195,9 +205,9 @@ public class TextColourChooser for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - sg.textColour = ap.av.textColour; - sg.textColour2 = ap.av.textColour2; - sg.thresholdTextColour = ap.av.thresholdTextColour; + sg.textColour = ap.av.getTextColour(); + sg.textColour2 = ap.av.getTextColour2(); + sg.thresholdTextColour = ap.av.getThresholdTextColour(); } } diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java index c5650f5..fc0a758 100755 --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@ -20,17 +20,47 @@ */ package jalview.gui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; -import java.awt.print.*; -import javax.swing.*; - -import jalview.analysis.*; -import jalview.datamodel.*; -import jalview.schemes.*; -import jalview.util.*; +import jalview.analysis.Conservation; +import jalview.analysis.NJTree; +import jalview.api.AlignViewportI; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceNode; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.ColourSchemeProperty; +import jalview.schemes.ResidueProperties; +import jalview.schemes.UserColourScheme; +import jalview.structure.SelectionSource; +import jalview.util.Format; +import jalview.util.MappingUtils; +import jalview.util.MessageManager; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +import javax.swing.JColorChooser; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; /** * DOCUMENT ME! @@ -39,7 +69,7 @@ import jalview.util.*; * @version $Revision$ */ public class TreeCanvas extends JPanel implements MouseListener, Runnable, - Printable, MouseMotionListener + Printable, MouseMotionListener, SelectionSource { /** DOCUMENT ME!! */ public static final String PLACEHOLDER = " * "; @@ -208,7 +238,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, if (node.element() instanceof SequenceI) { - SequenceI seq = (SequenceI) ((SequenceNode) node).element(); + SequenceI seq = (SequenceI) node.element(); if (av.getSequenceColour(seq) == Color.white) { @@ -258,14 +288,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, Rectangle rect = new Rectangle(xend + 10, ypos - charHeight / 2, charWidth, charHeight); - nameHash.put((SequenceI) node.element(), rect); + nameHash.put(node.element(), rect); // Colour selected leaves differently SequenceGroup selected = av.getSelectionGroup(); if ((selected != null) && selected.getSequences(null).contains( - (SequenceI) node.element())) + node.element())) { g.setColor(Color.gray); @@ -290,7 +320,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, int xend = (int) (height * scale) + offx; int ypos = (int) (node.ycount * chunk) + offy; - g.setColor(((SequenceNode) node).color.darker()); + g.setColor(node.color.darker()); // Draw horizontal line g.drawLine(xstart, ypos, xend, ypos); @@ -493,7 +523,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, { for (int a = 0; a < aps.length; a++) { - aps[a].av.setSequenceColour((SequenceI) node.element(), c); + final SequenceI seq = (SequenceI) node.element(); + aps[a].av.setSequenceColour(seq, c); } } } @@ -682,7 +713,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, labelLength = fm.stringWidth(longestName) + 20; // 20 allows for scrollbar - float wscale = (float) (width - labelLength - (offx * 2)) + float wscale = (width - labelLength - (offx * 2)) / tree.getMaxHeight(); SequenceNode top = tree.getTopNode(); @@ -708,7 +739,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, g2.setColor(Color.gray); } - int x = (int) ((threshold * (float) (getWidth() - labelLength - (2 * offx))) + offx); + int x = (int) ((threshold * (getWidth() - labelLength - (2 * offx))) + offx); g2.drawLine(x, 0, x, getHeight()); } @@ -854,12 +885,20 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, AlignmentPanel[] aps = getAssociatedPanels(); + // TODO push calls below into a single AlignViewportI method? + // see also AlignViewController.deleteGroups for (int a = 0; a < aps.length; a++) { aps[a].av.setSelectionGroup(null); aps[a].av.getAlignment().deleteAllGroups(); aps[a].av.clearSequenceColours(); } + if (av.getCodingComplement() != null) + { + av.getCodingComplement().setSelectionGroup(null); + av.getCodingComplement().getAlignment().deleteAllGroups(); + av.getCodingComplement().clearSequenceColours(); + } colourGroups(); } @@ -916,13 +955,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, if (cs != null) { cs.setThreshold(av.getGlobalColourScheme().getThreshold(), - av.getIgnoreGapsConsensus()); + av.isIgnoreGapsConsensus()); } } sg.cs = cs; // sg.recalcConservation(); sg.setName("JTreeGroup:" + sg.hashCode()); sg.setIdColour(col); + for (int a = 0; a < aps.length; a++) { if (aps[a].av.getGlobalColourScheme() != null @@ -939,7 +979,25 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, aps[a].av.getAlignment().addGroup(new SequenceGroup(sg)); } + + // TODO can we push all of the below into AlignViewportI? + av.getAlignment().addGroup(sg); + final AlignViewportI codingComplement = av.getCodingComplement(); + if (codingComplement != null) + { + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av, + codingComplement); + if (mappedGroup.getSequences().size() > 0) + { + codingComplement.getAlignment().addGroup(mappedGroup); + for (SequenceI seq : mappedGroup.getSequences()) + { + codingComplement.setSequenceColour(seq, col.brighter()); + } + } + } } + // notify the panel to redo any group specific stuff. for (int a = 0; a < aps.length; a++) { @@ -948,6 +1006,13 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, // to any Jmols listening in } + if (av.getCodingComplement() != null) + { + ((AlignViewport) av.getCodingComplement()).getAlignPanel().updateAnnotation(); + /* + * idPanel. repaint () + */ + } } /** diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java index 6ce68b3..cde6d5f 100755 --- a/src/jalview/gui/TreePanel.java +++ b/src/jalview/gui/TreePanel.java @@ -43,6 +43,7 @@ import jalview.io.NewickFile; import jalview.jbgui.GTreePanel; import jalview.schemes.ResidueProperties; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.Font; import java.awt.Graphics; @@ -138,7 +139,7 @@ public class TreePanel extends GTreePanel return treeCanvas.av.getAlignment(); } - public AlignViewport getViewPort() + public AlignmentViewport getViewPort() { return treeCanvas.av; } @@ -242,7 +243,8 @@ public class TreePanel extends GTreePanel associateLeavesMenu.add(item); } - final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views"); + final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem( + "label.all_views"); buttonGroup.add(itemf); itemf.setSelected(treeCanvas.applyToAllViews); itemf.addActionListener(new ActionListener() @@ -343,7 +345,7 @@ public class TreePanel extends GTreePanel av.setCurrentTree(tree); if (av.getSortByTree()) { - sortByTree_actionPerformed(null); + sortByTree_actionPerformed(); } } } @@ -531,7 +533,7 @@ public class TreePanel extends GTreePanel // msaorder); Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.original_data_for_params", new String[] + "label.original_data_for_params", new Object[] { this.title }), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } @@ -555,7 +557,8 @@ public class TreePanel extends GTreePanel * * @param e */ - public void sortByTree_actionPerformed(ActionEvent e) + @Override + public void sortByTree_actionPerformed() { if (treeCanvas.applyToAllViews) @@ -617,7 +620,7 @@ public class TreePanel extends GTreePanel public CommandI sortAlignmentIn(AlignmentPanel ap) { - AlignViewport av = ap.av; + AlignmentViewport av = ap.av; SequenceI[] oldOrder = av.getAlignment().getSequencesArray(); AlignmentSorter.sortByTree(av.getAlignment(), tree); CommandI undo; diff --git a/src/jalview/gui/UserDefinedColours.java b/src/jalview/gui/UserDefinedColours.java index 37824fe..3da159f 100755 --- a/src/jalview/gui/UserDefinedColours.java +++ b/src/jalview/gui/UserDefinedColours.java @@ -528,7 +528,7 @@ public class UserDefinedColours extends GUserDefinedColours implements } }else{ for (int i = 0; i < 24; i++){ - JButton button = (JButton) upperCaseButtons.get(i); + JButton button = upperCaseButtons.get(i); newColours[i] = button.getBackground(); } } @@ -547,7 +547,7 @@ public class UserDefinedColours extends GUserDefinedColours implements } }else{ for (int i = 0; i < 23; i++){ - JButton button = (JButton) lowerCaseButtons.get(i); + JButton button = lowerCaseButtons.get(i); newColours[i] = button.getBackground(); } } @@ -556,7 +556,7 @@ public class UserDefinedColours extends GUserDefinedColours implements if (ap != null) { - ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } return ucs; diff --git a/src/jalview/gui/VamsasApplication.java b/src/jalview/gui/VamsasApplication.java index 77a7693..04cc9e3 100644 --- a/src/jalview/gui/VamsasApplication.java +++ b/src/jalview/gui/VamsasApplication.java @@ -32,12 +32,12 @@ import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasListener; import jalview.structure.VamsasSource; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; -import java.util.Enumeration; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; @@ -347,7 +347,9 @@ public class VamsasApplication implements SelectionSource, VamsasSource public void end_session(boolean promptUser) { if (!inSession()) + { throw new Error(MessageManager.getString("error.jalview_no_connected_vamsas_session")); + } Cache.log.info("Jalview disconnecting from the Vamsas Session."); try { @@ -958,11 +960,14 @@ public class VamsasApplication implements SelectionSource, VamsasSource int i = -1; - public void mouseOver(SequenceI seq, int index, + @Override + public void mouseOverSequence(SequenceI seq, int index, VamsasSource source) { if (jv2vobj == null) + { return; + } if (seq != last || i != index) { VorbaId v = (VorbaId) jv2vobj.get(seq); @@ -998,7 +1003,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource AlignmentI visal = null; if (source instanceof AlignViewport) { - visal = ((AlignViewport) source).getAlignment(); + visal = ((AlignmentViewport) source).getAlignment(); } SelectionMessage sm = null; if ((seqsel == null || seqsel.getSize() == 0) @@ -1009,7 +1014,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource { // the empty selection. sm = new SelectionMessage("jalview", new String[] - { ((AlignViewport) source).getSequenceSetId() }, null, + { ((AlignmentViewport) source).getSequenceSetId() }, null, true); } else @@ -1050,10 +1055,9 @@ public class VamsasApplication implements SelectionSource, VamsasSource { // gather selected columns outwith the sequence positions // too - Enumeration cols = colsel.getSelected().elements(); - while (cols.hasMoreElements()) + for (Object obj : colsel.getSelected()) { - int ival = ((Integer) cols.nextElement()).intValue(); + int ival = ((Integer) obj).intValue(); Pos p = new Pos(); p.setI(ival + 1); range.addPos(p); diff --git a/src/jalview/gui/WsJobParameters.java b/src/jalview/gui/WsJobParameters.java index 4a74c9c..0772781 100644 --- a/src/jalview/gui/WsJobParameters.java +++ b/src/jalview/gui/WsJobParameters.java @@ -1306,7 +1306,7 @@ public class WsJobParameters extends JPanel implements ItemListener, */ protected void updateWebServiceMenus() { - for (AlignFrame alignFrame : Desktop.getAlignframes()) + for (AlignFrame alignFrame : Desktop.getAlignFrames()) { alignFrame.BuildWebServiceMenu(); } diff --git a/src/jalview/io/AppletFormatAdapter.java b/src/jalview/io/AppletFormatAdapter.java index 89adead..f316a7e 100755 --- a/src/jalview/io/AppletFormatAdapter.java +++ b/src/jalview/io/AppletFormatAdapter.java @@ -46,10 +46,24 @@ public class AppletFormatAdapter * List of valid format strings used in the isValidFormat method */ public static final String[] READABLE_FORMATS = new String[] - { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", - "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" }; // , - // "SimpleBLAST" - // }; + { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", + "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" }; + + /** + * List of readable format file extensions by application in order + * corresponding to READABLE_FNAMES + */ + public static final String[] READABLE_EXTENSIONS = new String[] + { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", + "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, "jar,jvp", "html" }; + + /** + * List of readable formats by application in order corresponding to + * READABLE_EXTENSIONS + */ + public static final String[] READABLE_FNAMES = new String[] + { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Stockholm", + "RNAML", PhylipFile.FILE_DESC, "Jalview", "HTML" }; /** * List of valid format strings for use by callers of the formatSequences @@ -75,26 +89,6 @@ public class AppletFormatAdapter { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH", PhylipFile.FILE_DESC, "Jalview" }; - /** - * List of readable format file extensions by application in order - * corresponding to READABLE_FNAMES - */ - public static final String[] READABLE_EXTENSIONS = new String[] - { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", - "jar,jvp", "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, - "html" }; // ".blast" - - /** - * List of readable formats by application in order corresponding to - * READABLE_EXTENSIONS - */ - public static final String[] READABLE_FNAMES = new String[] - { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview", - "Stockholm", "RNAML", PhylipFile.FILE_DESC, "HTML" };// , - - // "SimpleBLAST" - // }; - public static String INVALID_CHARACTERS = "Contains invalid characters"; // TODO: make these messages dynamic diff --git a/src/jalview/io/BioJsHTMLOutput.java b/src/jalview/io/BioJsHTMLOutput.java index db43a3f..ad3b79f 100644 --- a/src/jalview/io/BioJsHTMLOutput.java +++ b/src/jalview/io/BioJsHTMLOutput.java @@ -5,7 +5,6 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.exceptions.NoFileSelectedException; -import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; import jalview.gui.FeatureRenderer; import jalview.json.binding.v1.BioJsAlignmentPojo; @@ -13,6 +12,7 @@ import jalview.json.binding.v1.BioJsFeaturePojo; import jalview.json.binding.v1.BioJsSeqPojo; import jalview.schemes.ColourSchemeProperty; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.Color; import java.io.BufferedReader; @@ -26,7 +26,7 @@ import com.json.JSONException; public class BioJsHTMLOutput { - private AlignViewport av; + private AlignmentViewport av; private jalview.api.FeatureRenderer fr; diff --git a/src/jalview/io/FileLoader.java b/src/jalview/io/FileLoader.java index 0285bf0..906e823 100755 --- a/src/jalview/io/FileLoader.java +++ b/src/jalview/io/FileLoader.java @@ -332,13 +332,7 @@ public class FileLoader implements Runnable } if (viewport != null) { - // TODO: create undo object for this JAL-1101 - for (int i = 0; i < al.getHeight(); i++) - { - viewport.getAlignment().addSequence(al.getSequenceAt(i)); - } - viewport.firePropertyChange("alignment", null, viewport - .getAlignment().getSequences()); + viewport.addAlignment(al, title); } else { diff --git a/src/jalview/io/MSFfile.java b/src/jalview/io/MSFfile.java index 05765e3..621122c 100755 --- a/src/jalview/io/MSFfile.java +++ b/src/jalview/io/MSFfile.java @@ -20,11 +20,14 @@ */ package jalview.io; -import java.io.*; -import java.util.*; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.util.Format; -import jalview.datamodel.*; -import jalview.util.*; +import java.io.IOException; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; /** * DOCUMENT ME! @@ -63,10 +66,6 @@ public class MSFfile extends AlignFile super(source); } - { - // TODO Auto-generated constructor stub - } - /** * DOCUMENT ME! */ diff --git a/src/jalview/io/VamsasAppDatastore.java b/src/jalview/io/VamsasAppDatastore.java index 90447db..d00f0b1 100644 --- a/src/jalview/io/VamsasAppDatastore.java +++ b/src/jalview/io/VamsasAppDatastore.java @@ -34,6 +34,7 @@ import jalview.io.vamsas.DatastoreItem; import jalview.io.vamsas.DatastoreRegistry; import jalview.io.vamsas.Rangetype; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.io.IOException; import java.util.Enumeration; @@ -42,12 +43,35 @@ import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.Vector; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; -import uk.ac.vamsas.client.*; -import uk.ac.vamsas.objects.core.*; +import uk.ac.vamsas.client.IClientAppdata; +import uk.ac.vamsas.client.IClientDocument; +import uk.ac.vamsas.client.Vobject; +import uk.ac.vamsas.client.VorbaId; +import uk.ac.vamsas.objects.core.Alignment; +import uk.ac.vamsas.objects.core.AlignmentSequence; +import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation; +import uk.ac.vamsas.objects.core.AnnotationElement; +import uk.ac.vamsas.objects.core.DataSet; +import uk.ac.vamsas.objects.core.DataSetAnnotations; +import uk.ac.vamsas.objects.core.DbRef; +import uk.ac.vamsas.objects.core.Entry; +import uk.ac.vamsas.objects.core.Glyph; +import uk.ac.vamsas.objects.core.Local; +import uk.ac.vamsas.objects.core.MapType; +import uk.ac.vamsas.objects.core.Mapped; +import uk.ac.vamsas.objects.core.Property; +import uk.ac.vamsas.objects.core.Provenance; +import uk.ac.vamsas.objects.core.RangeAnnotation; +import uk.ac.vamsas.objects.core.RangeType; +import uk.ac.vamsas.objects.core.Seg; +import uk.ac.vamsas.objects.core.Sequence; +import uk.ac.vamsas.objects.core.SequenceType; +import uk.ac.vamsas.objects.core.VAMSAS; import uk.ac.vamsas.objects.utils.Properties; /* @@ -127,7 +151,7 @@ public class VamsasAppDatastore private void buildSkipList() { skipList = new Hashtable(); - AlignFrame[] al = Desktop.getAlignframes(); + AlignFrame[] al = Desktop.getAlignFrames(); for (int f = 0; al != null && f < al.length; f++) { skipList.put(al[f].getViewport().getSequenceSetId(), al[f]); @@ -728,12 +752,12 @@ public class VamsasAppDatastore * @return true if alignment associated with this view will be stored in * document. */ - public boolean alignmentWillBeSkipped(AlignViewport av) + public boolean alignmentWillBeSkipped(AlignmentViewport av) { return (!av.getAlignment().isAligned()); } - private void addToSkipList(AlignViewport av) + private void addToSkipList(AlignmentViewport av) { if (skipList == null) { @@ -1068,8 +1092,10 @@ public class VamsasAppDatastore an.addProperty(Properties.newProperty(THRESHOLD, Properties.FLOATTYPE, "" + alan.getThreshold().value)); if (alan.getThreshold().label != null) + { an.addProperty(Properties.newProperty(THRESHOLD + "Name", Properties.STRINGTYPE, "" + alan.getThreshold().label)); + } } ((DataSet) sref.getV_parent()).addDataSetAnnotations(an); bindjvvobj(alan, an); @@ -1381,12 +1407,12 @@ public class VamsasAppDatastore // sync, // and if any contain more than one view, then remove the one generated by // document update. - AlignViewport views[], av = null; + AlignmentViewport views[], av = null; AlignFrame af = null; Iterator newviews = newAlignmentViews.iterator(); while (newviews.hasNext()) { - av = (AlignViewport) newviews.next(); + av = (AlignmentViewport) newviews.next(); af = Desktop.getAlignFrameFor(av); // TODO implement this : af.getNumberOfViews String seqsetidobj = av.getSequenceSetId(); @@ -1403,7 +1429,8 @@ public class VamsasAppDatastore // to the align frames. boolean gathered = false; String newviewid = null; - AlignedCodonFrame[] mappings = av.getAlignment().getCodonFrames(); + Set mappings = av.getAlignment() + .getCodonFrames(); for (int i = 0; i < views.length; i++) { if (views[i] != av) @@ -1438,7 +1465,7 @@ public class VamsasAppDatastore { // ensure sequence mappings from vamsas document view still // active - if (mappings != null && mappings.length > 0) + if (mappings != null) { jalview.structure.StructureSelectionManager .getStructureSelectionManager(Desktop.instance) @@ -1682,7 +1709,7 @@ public class VamsasAppDatastore uk.ac.vamsas.objects.core.Alignment alignment = dataset .getAlignment(al); // TODO check this handles multiple views properly - AlignViewport av = findViewport(alignment); + AlignmentViewport av = findViewport(alignment); jalview.datamodel.AlignmentI jal = null; if (av != null) @@ -1956,10 +1983,10 @@ public class VamsasAppDatastore return newAlignmentViews.size(); } - public AlignViewport findViewport(Alignment alignment) + public AlignmentViewport findViewport(Alignment alignment) { - AlignViewport av = null; - AlignViewport[] avs = Desktop + AlignmentViewport av = null; + AlignmentViewport[] avs = Desktop .getViewports((String) getvObj2jv(alignment)); if (avs != null) { @@ -2207,6 +2234,7 @@ public class VamsasAppDatastore Cache.log.warn("Failed to parse threshold property"); } if (val != null) + { if (gl == null) { gl = new GraphLine(val.floatValue(), "", java.awt.Color.black); @@ -2215,11 +2243,14 @@ public class VamsasAppDatastore { gl.value = val.floatValue(); } + } } else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name")) { if (gl == null) + { gl = new GraphLine(0, "", java.awt.Color.black); + } gl.label = props[p].getContent(); } } @@ -2539,15 +2570,15 @@ public class VamsasAppDatastore * initialise a range type object from a set of start/end inclusive intervals * * @param mrt - * @param range + * @param ranges */ - private void initRangeType(RangeType mrt, int[] range) + private void initRangeType(RangeType mrt, List ranges) { - for (int i = 0; i < range.length; i += 2) + for (int[] range : ranges) { Seg vSeg = new Seg(); - vSeg.setStart(range[i]); - vSeg.setEnd(range[i + 1]); + vSeg.setStart(range[0]); + vSeg.setEnd(range[1]); mrt.addSeg(vSeg); } } @@ -2670,10 +2701,10 @@ public class VamsasAppDatastore return vobj2jv; } - public void storeSequenceMappings(AlignViewport viewport, String title) + public void storeSequenceMappings(AlignmentViewport viewport, String title) throws Exception { - AlignViewport av = viewport; + AlignmentViewport av = viewport; try { jalview.datamodel.AlignmentI jal = av.getAlignment(); @@ -2695,18 +2726,15 @@ public class VamsasAppDatastore } // Store any sequence mappings. - if (av.getAlignment().getCodonFrames() != null - && av.getAlignment().getCodonFrames().length > 0) + Set cframes = av.getAlignment().getCodonFrames(); + if (cframes != null) { - jalview.datamodel.AlignedCodonFrame[] cframes = av.getAlignment() - .getCodonFrames(); - for (int cf = 0; cf < cframes.length; cf++) + for (AlignedCodonFrame acf : cframes) { - if (cframes[cf].getdnaSeqs() != null - && cframes[cf].getdnaSeqs().length > 0) + if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0) { - jalview.datamodel.SequenceI[] dmps = cframes[cf].getdnaSeqs(); - jalview.datamodel.Mapping[] mps = cframes[cf].getProtMappings(); + jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs(); + jalview.datamodel.Mapping[] mps = acf.getProtMappings(); for (int smp = 0; smp < mps.length; smp++) { uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj(dmps[smp]); diff --git a/src/jalview/io/vamsas/Rangetype.java b/src/jalview/io/vamsas/Rangetype.java index 3cc977f..49227fd 100644 --- a/src/jalview/io/vamsas/Rangetype.java +++ b/src/jalview/io/vamsas/Rangetype.java @@ -20,6 +20,10 @@ */ package jalview.io.vamsas; +import jalview.io.VamsasAppDatastore; +import jalview.util.MessageManager; + +import java.util.List; import java.util.Vector; import uk.ac.vamsas.client.Vobject; @@ -28,8 +32,6 @@ import uk.ac.vamsas.objects.core.MapType; import uk.ac.vamsas.objects.core.Mapped; import uk.ac.vamsas.objects.core.RangeType; import uk.ac.vamsas.objects.core.Seg; -import jalview.io.VamsasAppDatastore; -import jalview.util.MessageManager; /** * Enhances DatastoreItem objects with additional functions to do with RangeType @@ -221,15 +223,15 @@ public abstract class Rangetype extends DatastoreItem * initialise a range type object from a set of start/end inclusive intervals * * @param mrt - * @param range + * @param ranges */ - protected void initRangeType(RangeType mrt, int[] range) + protected void initRangeType(RangeType mrt, List ranges) { - for (int i = 0; i < range.length; i += 2) + for (int[] range : ranges) { Seg vSeg = new Seg(); - vSeg.setStart(range[i]); - vSeg.setEnd(range[i + 1]); + vSeg.setStart(range[0]); + vSeg.setEnd(range[1]); vSeg.setInclusive(true); mrt.addSeg(vSeg); } diff --git a/src/jalview/io/vamsas/Sequencemapping.java b/src/jalview/io/vamsas/Sequencemapping.java index 3878a0a..3e20dcd 100644 --- a/src/jalview/io/vamsas/Sequencemapping.java +++ b/src/jalview/io/vamsas/Sequencemapping.java @@ -20,14 +20,15 @@ */ package jalview.io.vamsas; -import java.util.Vector; - import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.AlignmentI; import jalview.datamodel.Mapping; import jalview.datamodel.SequenceI; import jalview.gui.Desktop; import jalview.io.VamsasAppDatastore; -import uk.ac.vamsas.client.Vobject; + +import java.util.Vector; + import uk.ac.vamsas.objects.core.AlignmentSequence; import uk.ac.vamsas.objects.core.DataSet; import uk.ac.vamsas.objects.core.Sequence; @@ -283,12 +284,12 @@ public class Sequencemapping extends Rangetype jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping"); return; } - mobj = this.getvObj2jv((Vobject) sdloc); + mobj = this.getvObj2jv(sdloc); if (mobj instanceof SequenceI) { from = (SequenceI) mobj; } - mobj = this.getvObj2jv((Vobject) sdmap); + mobj = this.getvObj2jv(sdmap); if (mobj instanceof SequenceI) { to = (SequenceI) mobj; @@ -325,19 +326,17 @@ public class Sequencemapping extends Rangetype } // create mapping storage object and make each dataset alignment reference // it. - jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc - .getV_parent()); - jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap - .getV_parent()); - AlignedCodonFrame afc = new AlignedCodonFrame(0); + AlignmentI dsLoc = (AlignmentI) getvObj2jv(sdloc.getV_parent()); + AlignmentI dsMap = (AlignmentI) getvObj2jv(sdmap.getV_parent()); + AlignedCodonFrame acf = new AlignedCodonFrame(); if (dsLoc != null && dsLoc != dsMap) { - dsLoc.addCodonFrame(afc); + dsLoc.addCodonFrame(acf); } if (dsMap != null) { - dsMap.addCodonFrame(afc); + dsMap.addCodonFrame(acf); } // create and add the new mapping to (each) dataset's codonFrame @@ -350,24 +349,22 @@ public class Sequencemapping extends Rangetype mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio()); - afc.addMap(to, from, mapping); + acf.addMap(to, from, mapping); } else { mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense - afc.addMap(from, to, mapping); + acf.addMap(from, to, mapping); } } else { mapping = this.parsemapType(sequenceMapping, 1, 1); // correct sense - afc.addMap(from, to, mapping); + acf.addMap(from, to, mapping); } bindjvvobj(mapping, sequenceMapping); jalview.structure.StructureSelectionManager - .getStructureSelectionManager(Desktop.instance).addMappings( - new AlignedCodonFrame[] - { afc }); + .getStructureSelectionManager(Desktop.instance).addMapping(acf); // Try to link up any conjugate database references in the two sequences // matchConjugateDBRefs(from, to, mapping); // Try to propagate any dbrefs across this mapping. diff --git a/src/jalview/io/vamsas/Tree.java b/src/jalview/io/vamsas/Tree.java index dbfaf37..40d9f7c 100644 --- a/src/jalview/io/vamsas/Tree.java +++ b/src/jalview/io/vamsas/Tree.java @@ -35,10 +35,10 @@ import jalview.datamodel.SeqCigar; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.datamodel.SequenceNode; -import jalview.gui.AlignViewport; import jalview.gui.TreePanel; import jalview.io.NewickFile; import jalview.io.VamsasAppDatastore; +import jalview.viewmodel.AlignmentViewport; import uk.ac.vamsas.client.Vobject; import uk.ac.vamsas.objects.core.AlignmentSequence; import uk.ac.vamsas.objects.core.Entry; @@ -510,7 +510,7 @@ public class Tree extends DatastoreItem */ public Object[] recoverInputData(Provenance tp) { - AlignViewport javport = null; + AlignmentViewport javport = null; jalview.datamodel.AlignmentI jal = null; jalview.datamodel.CigarArray view = null; for (int pe = 0; pe < tp.getEntryCount(); pe++) @@ -604,7 +604,7 @@ public class Tree extends DatastoreItem return null; } - private AlignViewport getViewport(Vobject v_parent) + private AlignmentViewport getViewport(Vobject v_parent) { if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment) { diff --git a/src/jalview/javascript/MouseOverListener.java b/src/jalview/javascript/MouseOverListener.java index 19f7b11..2b0aab2 100644 --- a/src/jalview/javascript/MouseOverListener.java +++ b/src/jalview/javascript/MouseOverListener.java @@ -37,7 +37,9 @@ public class MouseOverListener extends JSFunctionExec implements int i = -1; - public void mouseOver(SequenceI seq, int index, VamsasSource source) + @Override + public void mouseOverSequence(SequenceI seq, int index, + VamsasSource source) { if (seq != last || i != index) { diff --git a/src/jalview/javascript/MouseOverStructureListener.java b/src/jalview/javascript/MouseOverStructureListener.java index 2ecaf6c..cd70291 100644 --- a/src/jalview/javascript/MouseOverStructureListener.java +++ b/src/jalview/javascript/MouseOverStructureListener.java @@ -20,9 +20,6 @@ */ package jalview.javascript; -import java.awt.Color; -import java.util.ArrayList; - import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; @@ -30,11 +27,15 @@ import jalview.appletgui.AlignFrame; import jalview.bin.JalviewLite; import jalview.datamodel.SequenceI; import jalview.ext.jmol.JmolCommands; +import jalview.structure.AtomSpec; import jalview.structure.StructureListener; import jalview.structure.StructureMapping; import jalview.structure.StructureMappingcommandSet; import jalview.structure.StructureSelectionManager; +import java.util.ArrayList; +import java.util.List; + /** * Propagate events involving PDB structures associated with sequences to a * javascript function. Generally, the javascript handler is called with a @@ -133,7 +134,6 @@ public class MouseOverStructureListener extends JSFunctionExec implements return modelSet; } - @Override public void mouseOverStructure(int atomIndex, String strInfo) { @@ -144,24 +144,27 @@ public class MouseOverStructureListener extends JSFunctionExec implements } @Override - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbId) + public void highlightAtoms(List atoms) { - String[] st = new String[0]; - try - { - executeJavascriptFunction(_listenerfn, st = new String[] - { "mouseover", "" + pdbId, "" + chain, "" + (pdbResNum), - "" + atomIndex }); - } catch (Exception ex) + for (AtomSpec atom : atoms) { - System.err.println("Couldn't execute callback with " + _listenerfn - + " using args { " + st[0] + ", " + st[1] + ", " + st[2] - + "," + st[3] + "\n"); - ex.printStackTrace(); - + try + { + // TODO is this right? StructureSelectionManager passes pdbFile as the + // field that is interpreted (in 2.8.2) as pdbId? + // JBPComment: yep - this is right! the Javascript harness uses the + // absolute pdbFile URI to locate the PDB file in the external viewer + executeJavascriptFunction(_listenerfn, new String[] + { "mouseover", "" + atom.getPdbFile(), + "" + atom.getChain(), + "" + (atom.getPdbResNum()), "" + atom.getAtomIndex() }); + } catch (Exception ex) + { + System.err.println("Couldn't execute callback with " + _listenerfn + + " for atomSpec: " + atom); + ex.printStackTrace(); + } } - } @Override @@ -283,13 +286,6 @@ public class MouseOverStructureListener extends JSFunctionExec implements } @Override - public Color getColour(int atomIndex, int pdbResNum, String chain, - String pdbId) - { - return null; - } - - @Override public AlignFrame getAlignFrame() { // associated with all alignframes, always. diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 4ecedaf..d9c87cb 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -21,6 +21,7 @@ package jalview.jbgui; import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; +import jalview.api.SplitContainerI; import jalview.bin.Cache; import jalview.gui.JvSwingUtils; import jalview.gui.Preferences; @@ -35,8 +36,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.Map; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; @@ -50,6 +54,7 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.MenuEvent; @@ -296,7 +301,7 @@ public class GAlignFrame extends JInternalFrame GridLayout gridLayout1 = new GridLayout(); - JMenu jMenu3 = new JMenu(); + JMenu showMenu = new JMenu(); JMenuItem showAllSeqs = new JMenuItem(); @@ -322,6 +327,8 @@ public class GAlignFrame extends JInternalFrame protected JMenuItem hideAllAlAnnotations = new JMenuItem(); + protected JCheckBoxMenuItem showComplementMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem sortAnnBySequence = new JCheckBoxMenuItem(); protected JCheckBoxMenuItem sortAnnByLabel = new JCheckBoxMenuItem(); @@ -340,7 +347,7 @@ public class GAlignFrame extends JInternalFrame JMenuItem textColour = new JMenuItem(); - JMenu formatMenu = new JMenu(); + protected JMenu formatMenu = new JMenu(); JMenu selectMenu = new JMenu(); @@ -388,6 +395,10 @@ public class GAlignFrame extends JInternalFrame private boolean showAutoCalculatedAbove = false; + private Map accelerators = new HashMap(); + + private SplitContainerI splitFrame; + public GAlignFrame() { try @@ -401,7 +412,7 @@ public class GAlignFrame extends JInternalFrame JMenuItem item = new JMenuItem( jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]); - item.addActionListener(new java.awt.event.ActionListener() + item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -505,9 +516,8 @@ public class GAlignFrame extends JInternalFrame // colours.add(covariationColour); colours.add(tcoffeeColour); colours.add(RNAInteractionColour); - setColourSelected(jalview.bin.Cache - .getDefault("DEFAULT_COLOUR", "None")); - + setColourSelected(jalview.bin.Cache.getDefault( + Preferences.DEFAULT_COLOUR, "None")); } public void setColourSelected(String defaultColour) @@ -610,81 +620,85 @@ public class GAlignFrame extends JInternalFrame private void jbInit() throws Exception { fileMenu.setText(MessageManager.getString("action.file")); + saveAs.setText(MessageManager.getString("action.save_as") + "..."); - saveAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - saveAs.addActionListener(new ActionListener() + ActionListener al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { saveAs_actionPerformed(e); } - }); + }; + KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + addMenuActionAndAccelerator(keyStroke, saveAs, al); + closeMenuItem.setText(MessageManager.getString("action.close")); - closeMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_W, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - closeMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { closeMenuItem_actionPerformed(false); } - }); + }; + addMenuActionAndAccelerator(keyStroke, closeMenuItem, al); + editMenu.setText(MessageManager.getString("action.edit")); viewMenu.setText(MessageManager.getString("action.view")); annotationsMenu.setText(MessageManager.getString("action.annotations")); colourMenu.setText(MessageManager.getString("action.colour")); calculateMenu.setText(MessageManager.getString("action.calculate")); webService.setText(MessageManager.getString("action.web_service")); + selectAllSequenceMenuItem.setText(MessageManager .getString("action.select_all")); - selectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_A, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - selectAllSequenceMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - selectAllSequenceMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + selectAllSequenceMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, selectAllSequenceMenuItem, al); + deselectAllSequenceMenuItem.setText(MessageManager .getString("action.deselect_all")); - deselectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0, false)); - deselectAllSequenceMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - deselectAllSequenceMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + deselectAllSequenceMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, deselectAllSequenceMenuItem, al); + invertSequenceMenuItem.setText(MessageManager .getString("action.invert_sequence_selection")); - invertSequenceMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - invertSequenceMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - invertSequenceMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + invertSequenceMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, invertSequenceMenuItem, al); + grpsFromSelection.setText(MessageManager .getString("action.make_groups_selection")); - grpsFromSelection.addActionListener(new java.awt.event.ActionListener() + grpsFromSelection.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -696,7 +710,7 @@ public class GAlignFrame extends JInternalFrame .getString("action.view_flanking_regions")); expandAlignment.setToolTipText(MessageManager .getString("label.view_flanking_regions")); - expandAlignment.addActionListener(new java.awt.event.ActionListener() + expandAlignment.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -706,86 +720,84 @@ public class GAlignFrame extends JInternalFrame }); remove2LeftMenuItem.setText(MessageManager .getString("action.remove_left")); - remove2LeftMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_L, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - remove2LeftMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - remove2LeftMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_L, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + remove2LeftMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, remove2LeftMenuItem, al); + remove2RightMenuItem.setText(MessageManager .getString("action.remove_right")); - remove2RightMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_R, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - remove2RightMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - remove2RightMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + remove2RightMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, remove2RightMenuItem, al); + removeGappedColumnMenuItem.setText(MessageManager .getString("action.remove_empty_columns")); - removeGappedColumnMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_E, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - removeGappedColumnMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - removeGappedColumnMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + removeGappedColumnMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, removeGappedColumnMenuItem, al); + removeAllGapsMenuItem.setText(MessageManager .getString("action.remove_all_gaps")); - removeAllGapsMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_E, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - removeAllGapsMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - removeAllGapsMenuItem_actionPerformed(e); - } - }); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + removeAllGapsMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, removeAllGapsMenuItem, al); + justifyLeftMenuItem.setText(MessageManager .getString("action.left_justify_alignment")); - justifyLeftMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - justifyLeftMenuItem_actionPerformed(e); - } - }); + justifyLeftMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + justifyLeftMenuItem_actionPerformed(e); + } + }); justifyRightMenuItem.setText(MessageManager .getString("action.right_justify_alignment")); - justifyRightMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - justifyRightMenuItem_actionPerformed(e); - } - }); + justifyRightMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + justifyRightMenuItem_actionPerformed(e); + } + }); viewBoxesMenuItem.setText(MessageManager.getString("action.boxes")); viewBoxesMenuItem.setState(true); - viewBoxesMenuItem.addActionListener(new java.awt.event.ActionListener() + viewBoxesMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -795,7 +807,7 @@ public class GAlignFrame extends JInternalFrame }); viewTextMenuItem.setText(MessageManager.getString("action.text")); viewTextMenuItem.setState(true); - viewTextMenuItem.addActionListener(new java.awt.event.ActionListener() + viewTextMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -806,28 +818,26 @@ public class GAlignFrame extends JInternalFrame showNonconservedMenuItem.setText(MessageManager .getString("label.show_non_conversed")); showNonconservedMenuItem.setState(false); - showNonconservedMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - showUnconservedMenuItem_actionPerformed(e); - } - }); + showNonconservedMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + showUnconservedMenuItem_actionPerformed(e); + } + }); sortPairwiseMenuItem.setText(MessageManager .getString("action.by_pairwise_id")); - sortPairwiseMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - sortPairwiseMenuItem_actionPerformed(e); - } - }); + sortPairwiseMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + sortPairwiseMenuItem_actionPerformed(e); + } + }); sortIDMenuItem.setText(MessageManager.getString("action.by_id")); - sortIDMenuItem.addActionListener(new java.awt.event.ActionListener() + sortIDMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -837,17 +847,16 @@ public class GAlignFrame extends JInternalFrame }); sortLengthMenuItem .setText(MessageManager.getString("action.by_length")); - sortLengthMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - sortLengthMenuItem_actionPerformed(e); - } - }); + sortLengthMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + sortLengthMenuItem_actionPerformed(e); + } + }); sortGroupMenuItem.setText(MessageManager.getString("action.by_group")); - sortGroupMenuItem.addActionListener(new java.awt.event.ActionListener() + sortGroupMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -855,34 +864,34 @@ public class GAlignFrame extends JInternalFrame sortGroupMenuItem_actionPerformed(e); } }); - removeRedundancyMenuItem.setText(MessageManager - .getString("action.remove_redundancy").concat("...")); - removeRedundancyMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_D, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - removeRedundancyMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - removeRedundancyMenuItem_actionPerformed(e); - } - }); + + removeRedundancyMenuItem.setText(MessageManager.getString( + "action.remove_redundancy").concat("...")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + removeRedundancyMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, removeRedundancyMenuItem, al); + pairwiseAlignmentMenuItem.setText(MessageManager .getString("action.pairwise_alignment")); - pairwiseAlignmentMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - pairwiseAlignmentMenuItem_actionPerformed(e); - } - }); + pairwiseAlignmentMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + pairwiseAlignmentMenuItem_actionPerformed(e); + } + }); PCAMenuItem.setText(MessageManager .getString("label.principal_component_analysis")); - PCAMenuItem.addActionListener(new java.awt.event.ActionListener() + PCAMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -892,26 +901,24 @@ public class GAlignFrame extends JInternalFrame }); averageDistanceTreeMenuItem.setText(MessageManager .getString("label.average_distance_identity")); - averageDistanceTreeMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - averageDistanceTreeMenuItem_actionPerformed(e); - } - }); + averageDistanceTreeMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + averageDistanceTreeMenuItem_actionPerformed(e); + } + }); neighbourTreeMenuItem.setText(MessageManager .getString("label.neighbour_joining_identity")); - neighbourTreeMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - neighbourTreeMenuItem_actionPerformed(e); - } - }); + neighbourTreeMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + neighbourTreeMenuItem_actionPerformed(e); + } + }); this.getContentPane().setLayout(borderLayout1); alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11)); statusBar.setBackground(Color.white); @@ -922,7 +929,7 @@ public class GAlignFrame extends JInternalFrame .getString("label.out_to_textbox")); clustalColour.setText(MessageManager.getString("label.clustalx")); - clustalColour.addActionListener(new java.awt.event.ActionListener() + clustalColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -931,7 +938,7 @@ public class GAlignFrame extends JInternalFrame } }); zappoColour.setText(MessageManager.getString("label.zappo")); - zappoColour.addActionListener(new java.awt.event.ActionListener() + zappoColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -940,7 +947,7 @@ public class GAlignFrame extends JInternalFrame } }); taylorColour.setText(MessageManager.getString("label.taylor")); - taylorColour.addActionListener(new java.awt.event.ActionListener() + taylorColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -950,17 +957,16 @@ public class GAlignFrame extends JInternalFrame }); hydrophobicityColour.setText(MessageManager .getString("label.hydrophobicity")); - hydrophobicityColour - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - hydrophobicityColour_actionPerformed(e); - } - }); + hydrophobicityColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + hydrophobicityColour_actionPerformed(e); + } + }); helixColour.setText(MessageManager.getString("label.helix_propensity")); - helixColour.addActionListener(new java.awt.event.ActionListener() + helixColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -970,7 +976,7 @@ public class GAlignFrame extends JInternalFrame }); strandColour.setText(MessageManager .getString("label.strand_propensity")); - strandColour.addActionListener(new java.awt.event.ActionListener() + strandColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -979,7 +985,7 @@ public class GAlignFrame extends JInternalFrame } }); turnColour.setText(MessageManager.getString("label.turn_propensity")); - turnColour.addActionListener(new java.awt.event.ActionListener() + turnColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -988,7 +994,7 @@ public class GAlignFrame extends JInternalFrame } }); buriedColour.setText(MessageManager.getString("label.buried_index")); - buriedColour.addActionListener(new java.awt.event.ActionListener() + buriedColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -998,7 +1004,7 @@ public class GAlignFrame extends JInternalFrame }); userDefinedColour.setText(MessageManager .getString("action.user_defined")); - userDefinedColour.addActionListener(new java.awt.event.ActionListener() + userDefinedColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1008,7 +1014,7 @@ public class GAlignFrame extends JInternalFrame }); PIDColour .setText(MessageManager.getString("label.percentage_identity")); - PIDColour.addActionListener(new java.awt.event.ActionListener() + PIDColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1018,7 +1024,7 @@ public class GAlignFrame extends JInternalFrame }); BLOSUM62Colour .setText(MessageManager.getString("label.blosum62_score")); - BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener() + BLOSUM62Colour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1027,7 +1033,7 @@ public class GAlignFrame extends JInternalFrame } }); nucleotideColour.setText(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(new java.awt.event.ActionListener() + nucleotideColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1038,55 +1044,51 @@ public class GAlignFrame extends JInternalFrame purinePyrimidineColour.setText(MessageManager .getString("label.purine_pyrimidine")); - purinePyrimidineColour - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - purinePyrimidineColour_actionPerformed(e); - } - }); + purinePyrimidineColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + purinePyrimidineColour_actionPerformed(e); + } + }); RNAInteractionColour.setText("RNA Interaction type"); - RNAInteractionColour - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - RNAInteractionColour_actionPerformed(e); - } - }); + RNAInteractionColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + RNAInteractionColour_actionPerformed(e); + } + }); /* * covariationColour.setText("Covariation"); - * covariationColour.addActionListener(new java.awt.event.ActionListener() { - * public void actionPerformed(ActionEvent e) { - * covariationColour_actionPerformed(e); } }); + * covariationColour.addActionListener(new ActionListener() { public void + * actionPerformed(ActionEvent e) { covariationColour_actionPerformed(e); } + * }); */ avDistanceTreeBlosumMenuItem.setText(MessageManager .getString("label.average_distance_bloslum62")); - avDistanceTreeBlosumMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - avTreeBlosumMenuItem_actionPerformed(e); - } - }); + avDistanceTreeBlosumMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + avTreeBlosumMenuItem_actionPerformed(e); + } + }); njTreeBlosumMenuItem.setText(MessageManager .getString("label.neighbour_blosum62")); - njTreeBlosumMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - njTreeBlosumMenuItem_actionPerformed(e); - } - }); + njTreeBlosumMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + njTreeBlosumMenuItem_actionPerformed(e); + } + }); annotationPanelMenuItem.setActionCommand(""); annotationPanelMenuItem.setText(MessageManager .getString("label.show_annotations")); @@ -1183,17 +1185,16 @@ public class GAlignFrame extends JInternalFrame }); colourTextMenuItem.setText(MessageManager .getString("label.colour_text")); - colourTextMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - colourTextMenuItem_actionPerformed(e); - } - }); + colourTextMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + colourTextMenuItem_actionPerformed(e); + } + }); htmlMenuItem.setText(MessageManager.getString("label.html")); - htmlMenuItem.addActionListener(new java.awt.event.ActionListener() + htmlMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1216,7 +1217,7 @@ public class GAlignFrame extends JInternalFrame overviewMenuItem.setText(MessageManager .getString("label.overview_window")); - overviewMenuItem.addActionListener(new java.awt.event.ActionListener() + overviewMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1224,45 +1225,47 @@ public class GAlignFrame extends JInternalFrame overviewMenuItem_actionPerformed(e); } }); + undoMenuItem.setEnabled(false); undoMenuItem.setText(MessageManager.getString("action.undo")); - undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_Z, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - undoMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { undoMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, undoMenuItem, al); + redoMenuItem.setEnabled(false); redoMenuItem.setText(MessageManager.getString("action.redo")); - redoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_Y, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - redoMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { redoMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, redoMenuItem, al); + conservationMenuItem.setText(MessageManager .getString("action.by_conservation")); - conservationMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - conservationMenuItem_actionPerformed(e); - } - }); + conservationMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + conservationMenuItem_actionPerformed(e); + } + }); noColourmenuItem.setText(MessageManager.getString("label.none")); - noColourmenuItem.addActionListener(new java.awt.event.ActionListener() + noColourmenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1271,7 +1274,7 @@ public class GAlignFrame extends JInternalFrame } }); wrapMenuItem.setText(MessageManager.getString("label.wrap")); - wrapMenuItem.addActionListener(new java.awt.event.ActionListener() + wrapMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1279,47 +1282,50 @@ public class GAlignFrame extends JInternalFrame wrapMenuItem_actionPerformed(e); } }); + printMenuItem.setText(MessageManager.getString("action.print") + "..."); - printMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_P, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - printMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { printMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, printMenuItem, al); + renderGapsMenuItem .setText(MessageManager.getString("action.show_gaps")); renderGapsMenuItem.setState(true); - renderGapsMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - renderGapsMenuItem_actionPerformed(e); - } - }); + renderGapsMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + renderGapsMenuItem_actionPerformed(e); + } + }); + findMenuItem.setText(MessageManager.getString("action.find")); - findMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_F, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); findMenuItem.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.find_tip"))); - findMenuItem.addActionListener(new java.awt.event.ActionListener() + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { findMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, findMenuItem, al); + abovePIDThreshold.setText(MessageManager .getString("label.above_identity_threshold")); - abovePIDThreshold.addActionListener(new java.awt.event.ActionListener() + abovePIDThreshold.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1446,8 +1452,7 @@ public class GAlignFrame extends JInternalFrame buttonGroup.add(showAutoLast); showAutoFirst.setText(MessageManager.getString("label.show_first")); showAutoFirst.setSelected(Cache.getDefault( - Preferences.SHOW_AUTOCALC_ABOVE, - false)); + Preferences.SHOW_AUTOCALC_ABOVE, false)); showAutoFirst.addActionListener(new ActionListener() { @Override @@ -1470,7 +1475,7 @@ public class GAlignFrame extends JInternalFrame }); nucleotideColour.setText(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(new java.awt.event.ActionListener() + nucleotideColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1493,69 +1498,74 @@ public class GAlignFrame extends JInternalFrame deleteGroups .setText(MessageManager.getString("action.undefine_groups")); - deleteGroups.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_U, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - deleteGroups.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { deleteGroups_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, deleteGroups, al); + createGroup.setText(MessageManager.getString("action.create_groups")); - createGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - createGroup.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createGroup_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, createGroup, al); + unGroup.setText(MessageManager.getString("action.remove_group")); - unGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - unGroup.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { unGroup_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, unGroup, al); + copy.setText(MessageManager.getString("action.copy")); - copy.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_C, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); - copy.addActionListener(new java.awt.event.ActionListener() + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { copy_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, copy, al); + cut.setText(MessageManager.getString("action.cut")); - cut.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_X, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - cut.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cut_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, cut, al); + delete.setText(MessageManager.getString("action.delete")); - delete.addActionListener(new java.awt.event.ActionListener() + delete.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1563,35 +1573,38 @@ public class GAlignFrame extends JInternalFrame delete_actionPerformed(e); } }); + pasteMenu.setText(MessageManager.getString("action.paste")); pasteNew.setText(MessageManager.getString("label.to_new_alignment")); - pasteNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_V, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - pasteNew.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { pasteNew_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, pasteNew, al); + pasteThis.setText(MessageManager.getString("label.to_this_alignment")); - pasteThis.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_V, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - pasteThis.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { pasteThis_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, pasteThis, al); + applyToAllGroups.setText(MessageManager .getString("label.apply_colour_to_all_groups")); - applyToAllGroups.addActionListener(new java.awt.event.ActionListener() + applyToAllGroups.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1599,7 +1612,7 @@ public class GAlignFrame extends JInternalFrame applyToAllGroups_actionPerformed(e); } }); - createPNG.addActionListener(new java.awt.event.ActionListener() + createPNG.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1612,7 +1625,7 @@ public class GAlignFrame extends JInternalFrame createPNG.setText("PNG"); font.setText(MessageManager.getString("action.font")); - font.addActionListener(new java.awt.event.ActionListener() + font.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1623,7 +1636,7 @@ public class GAlignFrame extends JInternalFrame seqLimits.setText(MessageManager .getString("label.show_sequence_limits")); seqLimits.setState(jalview.bin.Cache.getDefault("SHOW_JVSUFFIX", true)); - seqLimits.addActionListener(new java.awt.event.ActionListener() + seqLimits.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1632,7 +1645,7 @@ public class GAlignFrame extends JInternalFrame } }); epsFile.setText("EPS"); - epsFile.addActionListener(new java.awt.event.ActionListener() + epsFile.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1642,7 +1655,7 @@ public class GAlignFrame extends JInternalFrame }); createSVG.setText("SVG"); - createSVG.addActionListener(new java.awt.event.ActionListener() + createSVG.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1655,7 +1668,7 @@ public class GAlignFrame extends JInternalFrame .getString("label.load_tree_for_sequence_set")); LoadtreeMenuItem.setText(MessageManager .getString("label.load_associated_tree")); - LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener() + LoadtreeMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1666,7 +1679,7 @@ public class GAlignFrame extends JInternalFrame scaleAbove.setVisible(false); scaleAbove.setText(MessageManager.getString("action.scale_above")); - scaleAbove.addActionListener(new java.awt.event.ActionListener() + scaleAbove.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1677,7 +1690,7 @@ public class GAlignFrame extends JInternalFrame scaleLeft.setVisible(false); scaleLeft.setSelected(true); scaleLeft.setText(MessageManager.getString("action.scale_left")); - scaleLeft.addActionListener(new java.awt.event.ActionListener() + scaleLeft.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1688,7 +1701,7 @@ public class GAlignFrame extends JInternalFrame scaleRight.setVisible(false); scaleRight.setSelected(true); scaleRight.setText(MessageManager.getString("action.scale_right")); - scaleRight.addActionListener(new java.awt.event.ActionListener() + scaleRight.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1700,15 +1713,14 @@ public class GAlignFrame extends JInternalFrame centreColumnLabelsMenuItem.setState(false); centreColumnLabelsMenuItem.setText(MessageManager .getString("label.centre_column_labels")); - centreColumnLabelsMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - centreColumnLabels_actionPerformed(e); - } - }); + centreColumnLabelsMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + centreColumnLabels_actionPerformed(e); + } + }); followHighlightMenuItem.setVisible(true); followHighlightMenuItem.setState(true); followHighlightMenuItem.setText(MessageManager @@ -1726,7 +1738,7 @@ public class GAlignFrame extends JInternalFrame modifyPID.setText(MessageManager .getString("label.modify_identity_thereshold")); - modifyPID.addActionListener(new java.awt.event.ActionListener() + modifyPID.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1736,15 +1748,14 @@ public class GAlignFrame extends JInternalFrame }); modifyConservation.setText(MessageManager .getString("label.modify_conservation_thereshold")); - modifyConservation - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - modifyConservation_actionPerformed(e); - } - }); + modifyConservation.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + modifyConservation_actionPerformed(e); + } + }); sortByTreeMenu .setText(MessageManager.getString("action.by_tree_order")); sort.setText(MessageManager.getString("action.sort")); @@ -1825,6 +1836,7 @@ public class GAlignFrame extends JInternalFrame showTranslation_actionPerformed(e); } }); + extractScores.setText(MessageManager.getString("label.extract_scores") + "..."); extractScores.addActionListener(new ActionListener() @@ -1835,15 +1847,11 @@ public class GAlignFrame extends JInternalFrame extractScores_actionPerformed(e); } }); - extractScores.setVisible(true); // JBPNote: TODO: make gui for regex based - // score extraction + extractScores.setVisible(true); + // JBPNote: TODO: make gui for regex based score extraction + + // for show products actions see AlignFrame.canShowProducts showProducts.setText(MessageManager.getString("label.get_cross_refs")); - /* - * showProducts.addActionListener(new ActionListener() { - * - * public void actionPerformed(ActionEvent e) { - * showProducts_actionPerformed(e); } }); - */ openFeatureSettings.setText(MessageManager .getString("label.feature_settings")); openFeatureSettings.addActionListener(new ActionListener() @@ -2003,7 +2011,7 @@ public class GAlignFrame extends JInternalFrame } }); statusPanel.setLayout(gridLayout1); - jMenu3.setText(MessageManager.getString("action.show")); + showMenu.setText(MessageManager.getString("action.show")); showAllSeqs.setText(MessageManager.getString("label.all_sequences")); showAllSeqs.setToolTipText(MessageManager .getString("label.toggle_sequence_visibility")); @@ -2094,20 +2102,32 @@ public class GAlignFrame extends JInternalFrame hiddenMarkers_actionPerformed(e); } }); + invertColSel.setText(MessageManager .getString("action.invert_column_selection")); - invertColSel.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_I, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.ALT_MASK, false)); - invertColSel.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.ALT_MASK, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { invertColSel_actionPerformed(e); } + }; + addMenuActionAndAccelerator(keyStroke, invertColSel, al); + + showComplementMenuItem.setVisible(false); + showComplementMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + showComplement_actionPerformed(showComplementMenuItem.getState()); + } }); + tabbedPane.addChangeListener(new javax.swing.event.ChangeListener() { @Override @@ -2134,18 +2154,20 @@ public class GAlignFrame extends JInternalFrame tabbedPane_focusGained(e); } }); + save.setText(MessageManager.getString("action.save")); - save.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - save.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { save_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, save, al); + reload.setEnabled(false); reload.setText(MessageManager.getString("action.reload")); reload.addActionListener(new ActionListener() @@ -2156,18 +2178,20 @@ public class GAlignFrame extends JInternalFrame reload_actionPerformed(e); } }); + newView.setText(MessageManager.getString("action.new_view")); - newView.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_T, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - newView.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { newView_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, newView, al); + tabbedPane.setToolTipText("" + MessageManager.getString("label.rename_tab_eXpand_reGroup") + ""); @@ -2193,30 +2217,33 @@ public class GAlignFrame extends JInternalFrame idRightAlign_actionPerformed(e); } }); + gatherViews.setEnabled(false); gatherViews.setText(MessageManager.getString("action.gather_views")); - gatherViews.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_G, 0, false)); - gatherViews.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, 0, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { gatherViews_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, gatherViews, al); + expandViews.setEnabled(false); expandViews.setText(MessageManager.getString("action.expand_views")); - expandViews.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_X, 0, false)); - expandViews.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { expandViews_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, expandViews, al); + pageSetup .setText(MessageManager.getString("action.page_setup") + "..."); pageSetup.addActionListener(new ActionListener() @@ -2291,8 +2318,9 @@ public class GAlignFrame extends JInternalFrame viewMenu.add(expandViews); viewMenu.add(gatherViews); viewMenu.addSeparator(); - viewMenu.add(jMenu3); + viewMenu.add(showMenu); viewMenu.add(hideMenu); + viewMenu.add(showComplementMenuItem); viewMenu.addSeparator(); viewMenu.add(followHighlightMenuItem); annotationsMenu.add(annotationPanelMenuItem); @@ -2388,9 +2416,9 @@ public class GAlignFrame extends JInternalFrame this.getContentPane().add(statusPanel, java.awt.BorderLayout.SOUTH); statusPanel.add(statusBar, null); this.getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER); - jMenu3.add(showAllColumns); - jMenu3.add(showAllSeqs); - jMenu3.add(showAllhidden); + showMenu.add(showAllColumns); + showMenu.add(showAllSeqs); + showMenu.add(showAllhidden); hideMenu.add(hideSelColumns); hideMenu.add(hideSelSequences); hideMenu.add(hideAllSelection); @@ -2430,6 +2458,22 @@ public class GAlignFrame extends JInternalFrame } /** + * Adds the given action listener and key accelerator to the given menu item. + * Also saves in a lookup table to support lookup of action by key stroke. + * + * @param keyStroke + * @param menuItem + * @param actionListener + */ + protected void addMenuActionAndAccelerator(KeyStroke keyStroke, + JMenuItem menuItem, ActionListener actionListener) + { + menuItem.setAccelerator(keyStroke); + accelerators.put(keyStroke, menuItem); + menuItem.addActionListener(actionListener); + } + + /** * Action on clicking sort annotations by type. * * @param sortOrder @@ -2595,10 +2639,6 @@ public class GAlignFrame extends JInternalFrame { } - protected void showProducts_actionPerformed(ActionEvent e) - { - } - protected void buildSortByAnnotationScoresMenu() { } @@ -3160,4 +3200,50 @@ public class GAlignFrame extends JInternalFrame { this.annotationSortOrder = annotationSortOrder; } + + public Map getAccelerators() + { + return this.accelerators; + } + + /** + * Returns the selected index of the tabbed pane, or -1 if none selected + * (including the case where the tabbed pane has not been made visible). + * + * @return + */ + public int getTabIndex() + { + return tabbedPane.getSelectedIndex(); + } + + public JPanel getStatusPanel() + { + return statusPanel; + } + + /** + * Sets a reference to the containing split frame. Also makes the 'toggle + * split view' menu item visible and checked. + * + * @param sf + */ + public void setSplitFrame(SplitContainerI sf) + { + this.splitFrame = sf; + if (sf != null) + { + this.showComplementMenuItem.setVisible(true); + this.showComplementMenuItem.setState(true); + } + } + + public SplitContainerI getSplitViewContainer() + { + return this.splitFrame; + } + + protected void showComplement_actionPerformed(boolean state) + { + } } diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 3596619..071745c 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -156,7 +156,9 @@ public class GPreferences extends JPanel protected JPanel maxColour = new JPanel(); - protected JComboBox colour = new JComboBox(); + protected JComboBox protColour = new JComboBox(); + + protected JComboBox nucColour = new JComboBox(); /* * Connections tab components @@ -692,16 +694,30 @@ public class GPreferences extends JPanel maxColour_actionPerformed(maxColour); } }); - colour.setFont(verdana11); - colour.setBounds(new Rectangle(172, 225, 155, 21)); - JLabel colourLabel = new JLabel(); - colourLabel.setFont(verdana11); - colourLabel.setHorizontalAlignment(SwingConstants.RIGHT); - colourLabel.setText(MessageManager.getString("label.alignment_colour") + + protColour.setFont(verdana11); + protColour.setBounds(new Rectangle(172, 225, 155, 21)); + JLabel protColourLabel = new JLabel(); + protColourLabel.setFont(verdana11); + protColourLabel.setHorizontalAlignment(SwingConstants.LEFT); + protColourLabel.setText(MessageManager + .getString("label.prot_alignment_colour") + " "); + JvSwingUtils.addtoLayout(coloursTab, MessageManager + .getString("label.default_colour_scheme_for_alignment"), + protColourLabel, protColour); + + nucColour.setFont(verdana11); + nucColour.setBounds(new Rectangle(172, 240, 155, 21)); + JLabel nucColourLabel = new JLabel(); + nucColourLabel.setFont(verdana11); + nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT); + nucColourLabel.setText(MessageManager + .getString("label.nuc_alignment_colour") + " "); JvSwingUtils.addtoLayout(coloursTab, MessageManager .getString("label.default_colour_scheme_for_alignment"), - colourLabel, colour); + nucColourLabel, nucColour); + JPanel annotationShding = new JPanel(); annotationShding.setBorder(new TitledBorder(MessageManager .getString("label.annotation_shading_default"))); diff --git a/src/jalview/jbgui/GSplitFrame.java b/src/jalview/jbgui/GSplitFrame.java new file mode 100644 index 0000000..2eefde8 --- /dev/null +++ b/src/jalview/jbgui/GSplitFrame.java @@ -0,0 +1,139 @@ +package jalview.jbgui; + +import jalview.util.Platform; + +import java.awt.Component; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; + +import javax.swing.JInternalFrame; +import javax.swing.JSplitPane; +import javax.swing.plaf.basic.BasicInternalFrameUI; + +public class GSplitFrame extends JInternalFrame +{ + private static final long serialVersionUID = 1L; + + private GAlignFrame topFrame; + + private GAlignFrame bottomFrame; + + private JSplitPane splitPane; + + /** + * Constructor + * + * @param top + * @param bottom + */ + public GSplitFrame(GAlignFrame top, GAlignFrame bottom) + { + this.topFrame = top; + this.bottomFrame = bottom; + + hideTitleBars(); + + addSplitPane(); + } + + /** + * Create and add the split pane containing the top and bottom components. + */ + protected void addSplitPane() + { + splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame, + bottomFrame); + splitPane.setVisible(true); + splitPane.setDividerLocation(0.5d); + splitPane.setResizeWeight(0.5d); + splitPane.setDividerSize(0); + add(splitPane); + } + + /** + * Try to hide the title bars as a waste of precious space. + * + * @see http + * ://stackoverflow.com/questions/7218971/java-method-works-on-windows + * -but-not-macintosh -java + */ + protected void hideTitleBars() + { + if (new Platform().isAMac()) + { + // this saves some space - but doesn't hide the title bar + topFrame.putClientProperty("JInternalFrame.isPalette", true); + // topFrame.getRootPane().putClientProperty("Window.style", "small"); + bottomFrame.putClientProperty("JInternalFrame.isPalette", true); + } + else + { + ((BasicInternalFrameUI) topFrame.getUI()).setNorthPane(null); + ((BasicInternalFrameUI) bottomFrame.getUI()).setNorthPane(null); + } + } + + public GAlignFrame getTopFrame() + { + return topFrame; + } + + public GAlignFrame getBottomFrame() + { + return bottomFrame; + } + + /** + * Returns the split pane component the mouse is in, or null if neither. + * + * @return + */ + protected GAlignFrame getFrameAtMouse() + { + Point loc = MouseInfo.getPointerInfo().getLocation(); + + if (isIn(loc, splitPane.getTopComponent())) + { + return getTopFrame(); + } + else if (isIn(loc, splitPane.getBottomComponent())) + { + return getBottomFrame(); + } + return null; + } + + private boolean isIn(Point loc, Component comp) + { + if (!comp.isVisible()) + { + return false; + } + Point p = comp.getLocationOnScreen(); + Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight()); + return r.contains(loc); + } + + /** + * Make the complement of the specified split component visible or hidden, + * adjusting the position of the split divide. + */ + public void setComplementVisible(Object alignFrame, boolean show) + { + if (alignFrame == this.topFrame) + { + this.bottomFrame.setVisible(show); + } + else if (alignFrame == this.bottomFrame) + { + this.topFrame.setVisible(show); + } + if (show) + { + // SplitPane needs nudging to restore 50-50 split + splitPane.setDividerLocation(0.5d); + } + validate(); + } +} diff --git a/src/jalview/jbgui/GTreePanel.java b/src/jalview/jbgui/GTreePanel.java index b492c21..83a9866 100755 --- a/src/jalview/jbgui/GTreePanel.java +++ b/src/jalview/jbgui/GTreePanel.java @@ -22,10 +22,19 @@ package jalview.jbgui; import jalview.util.MessageManager; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JInternalFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JScrollPane; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; public class GTreePanel extends JInternalFrame { @@ -124,7 +133,7 @@ public class GTreePanel extends JInternalFrame { public void actionPerformed(ActionEvent e) { - sortByTree_actionPerformed(e); + sortByTree_actionPerformed(); } }); font.setText(MessageManager.getString("action.font")); @@ -282,7 +291,7 @@ public class GTreePanel extends JInternalFrame { } - public void sortByTree_actionPerformed(ActionEvent e) + public void sortByTree_actionPerformed() { } diff --git a/src/jalview/renderer/AnnotationRenderer.java b/src/jalview/renderer/AnnotationRenderer.java index d5b2f49..448bcd2 100644 --- a/src/jalview/renderer/AnnotationRenderer.java +++ b/src/jalview/renderer/AnnotationRenderer.java @@ -302,7 +302,7 @@ public class AnnotationRenderer columnSelection = av.getColumnSelection(); hconsensus = av.getSequenceConsensusHash();// hconsensus; hStrucConsensus = av.getRnaStructureConsensusHash(); // hStrucConsensus; - av_ignoreGapsConsensus = av.getIgnoreGapsConsensus(); + av_ignoreGapsConsensus = av.isIgnoreGapsConsensus(); } public int[] getProfileFor(AlignmentAnnotation aa, int column) @@ -400,8 +400,7 @@ public class AnnotationRenderer boolean validRes = false; boolean validEnd = false; boolean labelAllCols = false; - boolean centreColLabels, centreColLabelsDef = av - .getCentreColumnLabels(); + boolean centreColLabels, centreColLabelsDef = av.isCentreColumnLabels(); boolean scaleColLabel = false; AlignmentAnnotation consensusAnnot = av .getAlignmentConsensusAnnotation(), structConsensusAnnot = av diff --git a/src/jalview/renderer/AwtRenderPanelI.java b/src/jalview/renderer/AwtRenderPanelI.java index ab601da..80c60e4 100644 --- a/src/jalview/renderer/AwtRenderPanelI.java +++ b/src/jalview/renderer/AwtRenderPanelI.java @@ -24,6 +24,14 @@ import java.awt.FontMetrics; import java.awt.Image; import java.awt.image.ImageObserver; +/** + * semi-insulated interface for rendering a faded image whilst a calculation is + * in progress on annotation panel. Will need to remove java.awt dependencies + * for Android/etc + * + * @author jprocter + * + */ public interface AwtRenderPanelI extends ImageObserver { /** diff --git a/src/jalview/renderer/seqfeatures/FeatureRenderer.java b/src/jalview/renderer/seqfeatures/FeatureRenderer.java index 5e6ac29..fa91342 100644 --- a/src/jalview/renderer/seqfeatures/FeatureRenderer.java +++ b/src/jalview/renderer/seqfeatures/FeatureRenderer.java @@ -188,12 +188,11 @@ public class FeatureRenderer extends return initialCol; } - final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq - .getDatasetSequence() : seq; + SequenceFeature[] sf = seq.getSequenceFeatures(); if (seq != lastSeq) { lastSeq = seq; - sequenceFeatures = aseq.getSequenceFeatures(); + sequenceFeatures = sf; if (sequenceFeatures != null) { sfSize = sequenceFeatures.length; @@ -201,9 +200,9 @@ public class FeatureRenderer extends } else { - if (sequenceFeatures != aseq.getSequenceFeatures()) + if (sequenceFeatures != sf) { - sequenceFeatures = aseq.getSequenceFeatures(); + sequenceFeatures = sf; if (sequenceFeatures != null) { sfSize = sequenceFeatures.length; @@ -268,10 +267,8 @@ public class FeatureRenderer extends public synchronized void drawSequence(Graphics g, final SequenceI seq, int start, int end, int y1) { - final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq - .getDatasetSequence() : seq; - if (aseq.getSequenceFeatures() == null - || aseq.getSequenceFeatures().length == 0) + SequenceFeature[] sf = seq.getSequenceFeatures(); + if (sf == null || sf.length == 0) { return; } @@ -284,10 +281,10 @@ public class FeatureRenderer extends updateFeatures(); if (lastSeq == null || seq != lastSeq - || aseq.getSequenceFeatures() != sequenceFeatures) + || sf != sequenceFeatures) { lastSeq = seq; - sequenceFeatures = aseq.getSequenceFeatures(); + sequenceFeatures = sf; } if (transparency != 1 && g != null) diff --git a/src/jalview/schemabinding/version2/Viewport.java b/src/jalview/schemabinding/version2/Viewport.java index 1faf480..97d2ea4 100644 --- a/src/jalview/schemabinding/version2/Viewport.java +++ b/src/jalview/schemabinding/version2/Viewport.java @@ -20,11 +20,9 @@ */ package jalview.schemabinding.version2; + //---------------------------------/ + //- Imported classes and packages -/ //---------------------------------/ -//- Imported classes and packages -/ -//---------------------------------/ - -import jalview.util.MessageManager; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; @@ -34,2701 +32,2670 @@ import org.exolab.castor.xml.Unmarshaller; * * @version $Revision$ $Date$ */ -public class Viewport implements java.io.Serializable -{ - - // --------------------------/ - // - Class/Member Variables -/ - // --------------------------/ - - /** - * Field _conservationSelected. - */ - private boolean _conservationSelected; - - /** - * keeps track of state for field: _conservationSelected - */ - private boolean _has_conservationSelected; - - /** - * Field _pidSelected. - */ - private boolean _pidSelected; - - /** - * keeps track of state for field: _pidSelected - */ - private boolean _has_pidSelected; - - /** - * Field _bgColour. - */ - private java.lang.String _bgColour; - - /** - * Field _consThreshold. - */ - private int _consThreshold; - - /** - * keeps track of state for field: _consThreshold - */ - private boolean _has_consThreshold; - - /** - * Field _pidThreshold. - */ - private int _pidThreshold; - - /** - * keeps track of state for field: _pidThreshold - */ - private boolean _has_pidThreshold; - - /** - * Field _title. - */ - private java.lang.String _title; - - /** - * Field _showFullId. - */ - private boolean _showFullId; - - /** - * keeps track of state for field: _showFullId - */ - private boolean _has_showFullId; - - /** - * Field _rightAlignIds. - */ - private boolean _rightAlignIds; - - /** - * keeps track of state for field: _rightAlignIds - */ - private boolean _has_rightAlignIds; - - /** - * Field _showText. - */ - private boolean _showText; - - /** - * keeps track of state for field: _showText - */ - private boolean _has_showText; - - /** - * Field _showColourText. - */ - private boolean _showColourText; - - /** - * keeps track of state for field: _showColourText - */ - private boolean _has_showColourText; - - /** - * Field _showUnconserved. - */ - private boolean _showUnconserved = false; - - /** - * keeps track of state for field: _showUnconserved - */ - private boolean _has_showUnconserved; - - /** - * Field _showBoxes. - */ - private boolean _showBoxes; - - /** - * keeps track of state for field: _showBoxes - */ - private boolean _has_showBoxes; - - /** - * Field _wrapAlignment. - */ - private boolean _wrapAlignment; - - /** - * keeps track of state for field: _wrapAlignment - */ - private boolean _has_wrapAlignment; - - /** - * Field _renderGaps. - */ - private boolean _renderGaps; - - /** - * keeps track of state for field: _renderGaps - */ - private boolean _has_renderGaps; - - /** - * Field _showSequenceFeatures. - */ - private boolean _showSequenceFeatures; - - /** - * keeps track of state for field: _showSequenceFeatures - */ - private boolean _has_showSequenceFeatures; - - /** - * Field _showNPfeatureTooltip. - */ - private boolean _showNPfeatureTooltip; - - /** - * keeps track of state for field: _showNPfeatureTooltip - */ - private boolean _has_showNPfeatureTooltip; - - /** - * Field _showDbRefTooltip. - */ - private boolean _showDbRefTooltip; - - /** - * keeps track of state for field: _showDbRefTooltip - */ - private boolean _has_showDbRefTooltip; - - /** - * Field _followHighlight. - */ - private boolean _followHighlight = true; - - /** - * keeps track of state for field: _followHighlight - */ - private boolean _has_followHighlight; - - /** - * Field _followSelection. - */ - private boolean _followSelection = true; - - /** - * keeps track of state for field: _followSelection - */ - private boolean _has_followSelection; - - /** - * Field _showAnnotation. - */ - private boolean _showAnnotation; - - /** - * keeps track of state for field: _showAnnotation - */ - private boolean _has_showAnnotation; - - /** - * Field _centreColumnLabels. - */ - private boolean _centreColumnLabels = false; - - /** - * keeps track of state for field: _centreColumnLabels - */ - private boolean _has_centreColumnLabels; - - /** - * Field _showGroupConservation. - */ - private boolean _showGroupConservation = false; - - /** - * keeps track of state for field: _showGroupConservation - */ - private boolean _has_showGroupConservation; - - /** - * Field _showGroupConsensus. - */ - private boolean _showGroupConsensus = false; - - /** - * keeps track of state for field: _showGroupConsensus - */ - private boolean _has_showGroupConsensus; - - /** - * Field _showConsensusHistogram. - */ - private boolean _showConsensusHistogram = true; - - /** - * keeps track of state for field: _showConsensusHistogram - */ - private boolean _has_showConsensusHistogram; - - /** - * Field _showSequenceLogo. - */ - private boolean _showSequenceLogo = false; - - /** - * keeps track of state for field: _showSequenceLogo - */ - private boolean _has_showSequenceLogo; - - /** - * Field _normaliseSequenceLogo. - */ - private boolean _normaliseSequenceLogo = false; - - /** - * keeps track of state for field: _normaliseSequenceLogo - */ - private boolean _has_normaliseSequenceLogo; - - /** - * Field _ignoreGapsinConsensus. - */ - private boolean _ignoreGapsinConsensus = true; - - /** - * keeps track of state for field: _ignoreGapsinConsensus - */ - private boolean _has_ignoreGapsinConsensus; - - /** - * Field _startRes. - */ - private int _startRes; - - /** - * keeps track of state for field: _startRes - */ - private boolean _has_startRes; - - /** - * Field _startSeq. - */ - private int _startSeq; - - /** - * keeps track of state for field: _startSeq - */ - private boolean _has_startSeq; - - /** - * Field _fontName. - */ - private java.lang.String _fontName; - - /** - * Field _fontSize. - */ - private int _fontSize; - - /** - * keeps track of state for field: _fontSize - */ - private boolean _has_fontSize; - - /** - * Field _fontStyle. - */ - private int _fontStyle; - - /** - * keeps track of state for field: _fontStyle - */ - private boolean _has_fontStyle; - - /** - * Field _viewName. - */ - private java.lang.String _viewName; - - /** - * Field _sequenceSetId. - */ - private java.lang.String _sequenceSetId; - - /** - * Field _gatheredViews. - */ - private boolean _gatheredViews; - - /** - * keeps track of state for field: _gatheredViews - */ - private boolean _has_gatheredViews; - - /** - * Field _textCol1. - */ - private int _textCol1; - - /** - * keeps track of state for field: _textCol1 - */ - private boolean _has_textCol1; - - /** - * Field _textCol2. - */ - private int _textCol2; - - /** - * keeps track of state for field: _textCol2 - */ - private boolean _has_textCol2; - - /** - * Field _textColThreshold. - */ - private int _textColThreshold; - - /** - * keeps track of state for field: _textColThreshold - */ - private boolean _has_textColThreshold; - - /** - * unique id used by jalview to synchronize between stored and instantiated - * views - * - */ - private java.lang.String _id; - - /** - * Field _width. - */ - private int _width; - - /** - * keeps track of state for field: _width - */ - private boolean _has_width; - - /** - * Field _height. - */ - private int _height; - - /** - * keeps track of state for field: _height - */ - private boolean _has_height; - - /** - * Field _xpos. - */ - private int _xpos; - - /** - * keeps track of state for field: _xpos - */ - private boolean _has_xpos; - - /** - * Field _ypos. - */ - private int _ypos; - - /** - * keeps track of state for field: _ypos - */ - private boolean _has_ypos; - - /** - * Field _annotationColours. - */ - private jalview.schemabinding.version2.AnnotationColours _annotationColours; - - /** - * Field _hiddenColumnsList. - */ - private java.util.Vector _hiddenColumnsList; - - /** - * Field _calcIdParamList. - */ - private java.util.Vector _calcIdParamList; - - // ----------------/ - // - Constructors -/ - // ----------------/ - - public Viewport() - { - super(); - this._hiddenColumnsList = new java.util.Vector(); - this._calcIdParamList = new java.util.Vector(); - } - - // -----------/ - // - Methods -/ - // -----------/ - - /** - * - * - * @param vCalcIdParam - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addCalcIdParam( - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - throws java.lang.IndexOutOfBoundsException - { - this._calcIdParamList.addElement(vCalcIdParam); - } - - /** - * - * - * @param index - * @param vCalcIdParam - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addCalcIdParam(final int index, - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - throws java.lang.IndexOutOfBoundsException - { - this._calcIdParamList.add(index, vCalcIdParam); - } - - /** - * - * - * @param vHiddenColumns - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addHiddenColumns( - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - throws java.lang.IndexOutOfBoundsException - { - this._hiddenColumnsList.addElement(vHiddenColumns); - } - - /** - * - * - * @param index - * @param vHiddenColumns - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addHiddenColumns(final int index, - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - throws java.lang.IndexOutOfBoundsException - { - this._hiddenColumnsList.add(index, vHiddenColumns); - } - - /** - */ - public void deleteCentreColumnLabels() - { - this._has_centreColumnLabels = false; - } - - /** - */ - public void deleteConsThreshold() - { - this._has_consThreshold = false; - } - - /** - */ - public void deleteConservationSelected() - { - this._has_conservationSelected = false; - } - - /** - */ - public void deleteFollowHighlight() - { - this._has_followHighlight = false; - } - - /** - */ - public void deleteFollowSelection() - { - this._has_followSelection = false; - } - - /** - */ - public void deleteFontSize() - { - this._has_fontSize = false; - } - - /** - */ - public void deleteFontStyle() - { - this._has_fontStyle = false; - } - - /** - */ - public void deleteGatheredViews() - { - this._has_gatheredViews = false; - } - - /** - */ - public void deleteHeight() - { - this._has_height = false; - } +public class Viewport implements java.io.Serializable { + + + //--------------------------/ + //- Class/Member Variables -/ + //--------------------------/ + + /** + * Field _conservationSelected. + */ + private boolean _conservationSelected; + + /** + * keeps track of state for field: _conservationSelected + */ + private boolean _has_conservationSelected; + + /** + * Field _pidSelected. + */ + private boolean _pidSelected; + + /** + * keeps track of state for field: _pidSelected + */ + private boolean _has_pidSelected; + + /** + * Field _bgColour. + */ + private java.lang.String _bgColour; + + /** + * Field _consThreshold. + */ + private int _consThreshold; + + /** + * keeps track of state for field: _consThreshold + */ + private boolean _has_consThreshold; + + /** + * Field _pidThreshold. + */ + private int _pidThreshold; + + /** + * keeps track of state for field: _pidThreshold + */ + private boolean _has_pidThreshold; + + /** + * Field _title. + */ + private java.lang.String _title; + + /** + * Field _showFullId. + */ + private boolean _showFullId; + + /** + * keeps track of state for field: _showFullId + */ + private boolean _has_showFullId; + + /** + * Field _rightAlignIds. + */ + private boolean _rightAlignIds; + + /** + * keeps track of state for field: _rightAlignIds + */ + private boolean _has_rightAlignIds; + + /** + * Field _showText. + */ + private boolean _showText; + + /** + * keeps track of state for field: _showText + */ + private boolean _has_showText; + + /** + * Field _showColourText. + */ + private boolean _showColourText; + + /** + * keeps track of state for field: _showColourText + */ + private boolean _has_showColourText; + + /** + * Field _showUnconserved. + */ + private boolean _showUnconserved = false; + + /** + * keeps track of state for field: _showUnconserved + */ + private boolean _has_showUnconserved; + + /** + * Field _showBoxes. + */ + private boolean _showBoxes; + + /** + * keeps track of state for field: _showBoxes + */ + private boolean _has_showBoxes; + + /** + * Field _wrapAlignment. + */ + private boolean _wrapAlignment; + + /** + * keeps track of state for field: _wrapAlignment + */ + private boolean _has_wrapAlignment; + + /** + * Field _renderGaps. + */ + private boolean _renderGaps; + + /** + * keeps track of state for field: _renderGaps + */ + private boolean _has_renderGaps; + + /** + * Field _showSequenceFeatures. + */ + private boolean _showSequenceFeatures; + + /** + * keeps track of state for field: _showSequenceFeatures + */ + private boolean _has_showSequenceFeatures; + + /** + * Field _showNPfeatureTooltip. + */ + private boolean _showNPfeatureTooltip; + + /** + * keeps track of state for field: _showNPfeatureTooltip + */ + private boolean _has_showNPfeatureTooltip; + + /** + * Field _showDbRefTooltip. + */ + private boolean _showDbRefTooltip; + + /** + * keeps track of state for field: _showDbRefTooltip + */ + private boolean _has_showDbRefTooltip; + + /** + * Field _followHighlight. + */ + private boolean _followHighlight = true; + + /** + * keeps track of state for field: _followHighlight + */ + private boolean _has_followHighlight; + + /** + * Field _followSelection. + */ + private boolean _followSelection = true; + + /** + * keeps track of state for field: _followSelection + */ + private boolean _has_followSelection; + + /** + * Field _showAnnotation. + */ + private boolean _showAnnotation; + + /** + * keeps track of state for field: _showAnnotation + */ + private boolean _has_showAnnotation; + + /** + * Field _centreColumnLabels. + */ + private boolean _centreColumnLabels = false; + + /** + * keeps track of state for field: _centreColumnLabels + */ + private boolean _has_centreColumnLabels; + + /** + * Field _showGroupConservation. + */ + private boolean _showGroupConservation = false; + + /** + * keeps track of state for field: _showGroupConservation + */ + private boolean _has_showGroupConservation; + + /** + * Field _showGroupConsensus. + */ + private boolean _showGroupConsensus = false; + + /** + * keeps track of state for field: _showGroupConsensus + */ + private boolean _has_showGroupConsensus; + + /** + * Field _showConsensusHistogram. + */ + private boolean _showConsensusHistogram = true; + + /** + * keeps track of state for field: _showConsensusHistogram + */ + private boolean _has_showConsensusHistogram; + + /** + * Field _showSequenceLogo. + */ + private boolean _showSequenceLogo = false; + + /** + * keeps track of state for field: _showSequenceLogo + */ + private boolean _has_showSequenceLogo; + + /** + * Field _normaliseSequenceLogo. + */ + private boolean _normaliseSequenceLogo = false; + + /** + * keeps track of state for field: _normaliseSequenceLogo + */ + private boolean _has_normaliseSequenceLogo; + + /** + * Field _ignoreGapsinConsensus. + */ + private boolean _ignoreGapsinConsensus = true; + + /** + * keeps track of state for field: _ignoreGapsinConsensus + */ + private boolean _has_ignoreGapsinConsensus; + + /** + * Field _startRes. + */ + private int _startRes; + + /** + * keeps track of state for field: _startRes + */ + private boolean _has_startRes; + + /** + * Field _startSeq. + */ + private int _startSeq; + + /** + * keeps track of state for field: _startSeq + */ + private boolean _has_startSeq; + + /** + * Field _fontName. + */ + private java.lang.String _fontName; + + /** + * Field _fontSize. + */ + private int _fontSize; + + /** + * keeps track of state for field: _fontSize + */ + private boolean _has_fontSize; + + /** + * Field _fontStyle. + */ + private int _fontStyle; + + /** + * keeps track of state for field: _fontStyle + */ + private boolean _has_fontStyle; + + /** + * Field _viewName. + */ + private java.lang.String _viewName; - /** + /** + * Field _sequenceSetId. */ - public void deleteIgnoreGapsinConsensus() - { - this._has_ignoreGapsinConsensus = false; - } + private java.lang.String _sequenceSetId; - /** + /** + * Field _gatheredViews. */ - public void deleteNormaliseSequenceLogo() - { - this._has_normaliseSequenceLogo = false; - } + private boolean _gatheredViews; - /** + /** + * keeps track of state for field: _gatheredViews */ - public void deletePidSelected() - { - this._has_pidSelected = false; - } + private boolean _has_gatheredViews; - /** + /** + * Field _textCol1. */ - public void deletePidThreshold() - { - this._has_pidThreshold = false; - } + private int _textCol1; - /** + /** + * keeps track of state for field: _textCol1 */ - public void deleteRenderGaps() - { - this._has_renderGaps = false; - } + private boolean _has_textCol1; - /** + /** + * Field _textCol2. */ - public void deleteRightAlignIds() - { - this._has_rightAlignIds = false; - } + private int _textCol2; - /** + /** + * keeps track of state for field: _textCol2 */ - public void deleteShowAnnotation() - { - this._has_showAnnotation = false; - } + private boolean _has_textCol2; - /** + /** + * Field _textColThreshold. */ - public void deleteShowBoxes() - { - this._has_showBoxes = false; - } + private int _textColThreshold; - /** + /** + * keeps track of state for field: _textColThreshold */ - public void deleteShowColourText() - { - this._has_showColourText = false; - } + private boolean _has_textColThreshold; - /** + /** + * unique id used by jalview to + * synchronize between stored and + * instantiated views + * */ - public void deleteShowConsensusHistogram() - { - this._has_showConsensusHistogram = false; - } + private java.lang.String _id; - /** + /** + * The viewport id of this viewport's (cdna/protein) coding + * complement, if any + * */ - public void deleteShowDbRefTooltip() - { - this._has_showDbRefTooltip = false; - } + private java.lang.String _complementId; - /** + /** + * Field _width. */ - public void deleteShowFullId() - { - this._has_showFullId = false; - } + private int _width; - /** + /** + * keeps track of state for field: _width */ - public void deleteShowGroupConsensus() - { - this._has_showGroupConsensus = false; - } + private boolean _has_width; - /** + /** + * Field _height. */ - public void deleteShowGroupConservation() - { - this._has_showGroupConservation = false; - } + private int _height; - /** + /** + * keeps track of state for field: _height */ - public void deleteShowNPfeatureTooltip() - { - this._has_showNPfeatureTooltip = false; - } + private boolean _has_height; - /** + /** + * Field _xpos. */ - public void deleteShowSequenceFeatures() - { - this._has_showSequenceFeatures = false; - } + private int _xpos; - /** + /** + * keeps track of state for field: _xpos */ - public void deleteShowSequenceLogo() - { - this._has_showSequenceLogo = false; - } + private boolean _has_xpos; - /** + /** + * Field _ypos. */ - public void deleteShowText() - { - this._has_showText = false; - } + private int _ypos; - /** + /** + * keeps track of state for field: _ypos */ - public void deleteShowUnconserved() - { - this._has_showUnconserved = false; - } + private boolean _has_ypos; - /** + /** + * Field _annotationColours. */ - public void deleteStartRes() - { - this._has_startRes = false; - } - - /** - */ - public void deleteStartSeq() - { - this._has_startSeq = false; - } - - /** - */ - public void deleteTextCol1() - { - this._has_textCol1 = false; - } - - /** - */ - public void deleteTextCol2() - { - this._has_textCol2 = false; - } - - /** - */ - public void deleteTextColThreshold() - { - this._has_textColThreshold = false; - } - - /** - */ - public void deleteWidth() - { - this._has_width = false; - } - - /** - */ - public void deleteWrapAlignment() - { - this._has_wrapAlignment = false; - } - - /** - */ - public void deleteXpos() - { - this._has_xpos = false; - } - - /** - */ - public void deleteYpos() - { - this._has_ypos = false; - } - - /** - * Method enumerateCalcIdParam. - * - * @return an Enumeration over all jalview.schemabinding.version2.CalcIdParam - * elements - */ - public java.util.Enumeration enumerateCalcIdParam() - { - return this._calcIdParamList.elements(); - } - - /** - * Method enumerateHiddenColumns. - * - * @return an Enumeration over all - * jalview.schemabinding.version2.HiddenColumns elements - */ - public java.util.Enumeration enumerateHiddenColumns() - { - return this._hiddenColumnsList.elements(); - } - - /** - * Returns the value of field 'annotationColours'. - * - * @return the value of field 'AnnotationColours'. - */ - public jalview.schemabinding.version2.AnnotationColours getAnnotationColours() - { - return this._annotationColours; - } - - /** - * Returns the value of field 'bgColour'. - * - * @return the value of field 'BgColour'. - */ - public java.lang.String getBgColour() - { - return this._bgColour; - } - - /** - * Method getCalcIdParam. - * - * @param index - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - * @return the value of the jalview.schemabinding.version2.CalcIdParam at the - * given index - */ - public jalview.schemabinding.version2.CalcIdParam getCalcIdParam( - final int index) throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._calcIdParamList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "getCalcIdParam", - Integer.valueOf(index).toString(), - Integer.valueOf((this._calcIdParamList.size() - 1)).toString() - })); - } - - return (jalview.schemabinding.version2.CalcIdParam) _calcIdParamList - .get(index); - } - - /** - * Method getCalcIdParam.Returns the contents of the collection in an Array. - *

- * Note: Just in case the collection contents are changing in another thread, - * we pass a 0-length Array of the correct type into the API call. This way we - * know that the Array returned is of exactly the correct length. - * - * @return this collection as an Array - */ - public jalview.schemabinding.version2.CalcIdParam[] getCalcIdParam() - { - jalview.schemabinding.version2.CalcIdParam[] array = new jalview.schemabinding.version2.CalcIdParam[0]; - return (jalview.schemabinding.version2.CalcIdParam[]) this._calcIdParamList - .toArray(array); - } - - /** - * Method getCalcIdParamCount. - * - * @return the size of this collection - */ - public int getCalcIdParamCount() - { - return this._calcIdParamList.size(); - } - - /** - * Returns the value of field 'centreColumnLabels'. - * - * @return the value of field 'CentreColumnLabels'. - */ - public boolean getCentreColumnLabels() - { - return this._centreColumnLabels; - } - - /** - * Returns the value of field 'consThreshold'. - * - * @return the value of field 'ConsThreshold'. - */ - public int getConsThreshold() - { - return this._consThreshold; - } - - /** - * Returns the value of field 'conservationSelected'. - * - * @return the value of field 'ConservationSelected'. - */ - public boolean getConservationSelected() - { - return this._conservationSelected; - } - - /** - * Returns the value of field 'followHighlight'. - * - * @return the value of field 'FollowHighlight'. - */ - public boolean getFollowHighlight() - { - return this._followHighlight; - } - - /** - * Returns the value of field 'followSelection'. - * - * @return the value of field 'FollowSelection'. - */ - public boolean getFollowSelection() - { - return this._followSelection; - } - - /** - * Returns the value of field 'fontName'. - * - * @return the value of field 'FontName'. - */ - public java.lang.String getFontName() - { - return this._fontName; - } - - /** - * Returns the value of field 'fontSize'. - * - * @return the value of field 'FontSize'. - */ - public int getFontSize() - { - return this._fontSize; - } - - /** - * Returns the value of field 'fontStyle'. - * - * @return the value of field 'FontStyle'. - */ - public int getFontStyle() - { - return this._fontStyle; - } - - /** - * Returns the value of field 'gatheredViews'. - * - * @return the value of field 'GatheredViews'. - */ - public boolean getGatheredViews() - { - return this._gatheredViews; - } - - /** - * Returns the value of field 'height'. - * - * @return the value of field 'Height'. - */ - public int getHeight() - { - return this._height; - } - - /** - * Method getHiddenColumns. - * - * @param index - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - * @return the value of the jalview.schemabinding.version2.HiddenColumns at - * the given index - */ - public jalview.schemabinding.version2.HiddenColumns getHiddenColumns( - final int index) throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._hiddenColumnsList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "getHiddenColumns", - Integer.valueOf(index).toString(), - Integer.valueOf((this._hiddenColumnsList.size() - 1)).toString() - })); - } - - return (jalview.schemabinding.version2.HiddenColumns) _hiddenColumnsList - .get(index); - } - - /** - * Method getHiddenColumns.Returns the contents of the collection in an Array. - *

- * Note: Just in case the collection contents are changing in another thread, - * we pass a 0-length Array of the correct type into the API call. This way we - * know that the Array returned is of exactly the correct length. - * - * @return this collection as an Array - */ - public jalview.schemabinding.version2.HiddenColumns[] getHiddenColumns() - { - jalview.schemabinding.version2.HiddenColumns[] array = new jalview.schemabinding.version2.HiddenColumns[0]; - return (jalview.schemabinding.version2.HiddenColumns[]) this._hiddenColumnsList - .toArray(array); - } - - /** - * Method getHiddenColumnsCount. - * - * @return the size of this collection - */ - public int getHiddenColumnsCount() - { - return this._hiddenColumnsList.size(); - } - - /** - * Returns the value of field 'id'. The field 'id' has the following - * description: unique id used by jalview to synchronize between stored and - * instantiated views - * - * - * @return the value of field 'Id'. - */ - public java.lang.String getId() - { - return this._id; - } - - /** - * Returns the value of field 'ignoreGapsinConsensus'. - * - * @return the value of field 'IgnoreGapsinConsensus'. - */ - public boolean getIgnoreGapsinConsensus() - { - return this._ignoreGapsinConsensus; - } - - /** - * Returns the value of field 'normaliseSequenceLogo'. - * - * @return the value of field 'NormaliseSequenceLogo'. - */ - public boolean getNormaliseSequenceLogo() - { - return this._normaliseSequenceLogo; - } - - /** - * Returns the value of field 'pidSelected'. - * - * @return the value of field 'PidSelected'. - */ - public boolean getPidSelected() - { - return this._pidSelected; - } - - /** - * Returns the value of field 'pidThreshold'. - * - * @return the value of field 'PidThreshold'. - */ - public int getPidThreshold() - { - return this._pidThreshold; - } - - /** - * Returns the value of field 'renderGaps'. - * - * @return the value of field 'RenderGaps'. - */ - public boolean getRenderGaps() - { - return this._renderGaps; - } - - /** - * Returns the value of field 'rightAlignIds'. - * - * @return the value of field 'RightAlignIds'. - */ - public boolean getRightAlignIds() - { - return this._rightAlignIds; - } - - /** - * Returns the value of field 'sequenceSetId'. - * - * @return the value of field 'SequenceSetId'. - */ - public java.lang.String getSequenceSetId() - { - return this._sequenceSetId; - } - - /** - * Returns the value of field 'showAnnotation'. - * - * @return the value of field 'ShowAnnotation'. - */ - public boolean getShowAnnotation() - { - return this._showAnnotation; - } - - /** - * Returns the value of field 'showBoxes'. - * - * @return the value of field 'ShowBoxes'. - */ - public boolean getShowBoxes() - { - return this._showBoxes; - } - - /** - * Returns the value of field 'showColourText'. - * - * @return the value of field 'ShowColourText'. - */ - public boolean getShowColourText() - { - return this._showColourText; - } - - /** - * Returns the value of field 'showConsensusHistogram'. - * - * @return the value of field 'ShowConsensusHistogram'. - */ - public boolean getShowConsensusHistogram() - { - return this._showConsensusHistogram; - } - - /** - * Returns the value of field 'showDbRefTooltip'. - * - * @return the value of field 'ShowDbRefTooltip'. - */ - public boolean getShowDbRefTooltip() - { - return this._showDbRefTooltip; - } - - /** - * Returns the value of field 'showFullId'. - * - * @return the value of field 'ShowFullId'. - */ - public boolean getShowFullId() - { - return this._showFullId; - } - - /** - * Returns the value of field 'showGroupConsensus'. - * - * @return the value of field 'ShowGroupConsensus'. - */ - public boolean getShowGroupConsensus() - { - return this._showGroupConsensus; - } - - /** - * Returns the value of field 'showGroupConservation'. - * - * @return the value of field 'ShowGroupConservation'. - */ - public boolean getShowGroupConservation() - { - return this._showGroupConservation; - } - - /** - * Returns the value of field 'showNPfeatureTooltip'. - * - * @return the value of field 'ShowNPfeatureTooltip'. - */ - public boolean getShowNPfeatureTooltip() - { - return this._showNPfeatureTooltip; - } - - /** - * Returns the value of field 'showSequenceFeatures'. - * - * @return the value of field 'ShowSequenceFeatures'. - */ - public boolean getShowSequenceFeatures() - { - return this._showSequenceFeatures; - } - - /** - * Returns the value of field 'showSequenceLogo'. - * - * @return the value of field 'ShowSequenceLogo'. - */ - public boolean getShowSequenceLogo() - { - return this._showSequenceLogo; - } - - /** - * Returns the value of field 'showText'. - * - * @return the value of field 'ShowText'. - */ - public boolean getShowText() - { - return this._showText; - } - - /** - * Returns the value of field 'showUnconserved'. - * - * @return the value of field 'ShowUnconserved'. - */ - public boolean getShowUnconserved() - { - return this._showUnconserved; - } - - /** - * Returns the value of field 'startRes'. - * - * @return the value of field 'StartRes'. - */ - public int getStartRes() - { - return this._startRes; - } - - /** - * Returns the value of field 'startSeq'. - * - * @return the value of field 'StartSeq'. - */ - public int getStartSeq() - { - return this._startSeq; - } - - /** - * Returns the value of field 'textCol1'. - * - * @return the value of field 'TextCol1'. - */ - public int getTextCol1() - { - return this._textCol1; - } - - /** - * Returns the value of field 'textCol2'. - * - * @return the value of field 'TextCol2'. - */ - public int getTextCol2() - { - return this._textCol2; - } - - /** - * Returns the value of field 'textColThreshold'. - * - * @return the value of field 'TextColThreshold'. - */ - public int getTextColThreshold() - { - return this._textColThreshold; - } - - /** - * Returns the value of field 'title'. - * - * @return the value of field 'Title'. - */ - public java.lang.String getTitle() - { - return this._title; - } - - /** - * Returns the value of field 'viewName'. - * - * @return the value of field 'ViewName'. - */ - public java.lang.String getViewName() - { - return this._viewName; - } - - /** - * Returns the value of field 'width'. - * - * @return the value of field 'Width'. - */ - public int getWidth() - { - return this._width; - } - - /** - * Returns the value of field 'wrapAlignment'. - * - * @return the value of field 'WrapAlignment'. - */ - public boolean getWrapAlignment() - { - return this._wrapAlignment; - } - - /** - * Returns the value of field 'xpos'. - * - * @return the value of field 'Xpos'. - */ - public int getXpos() - { - return this._xpos; - } - - /** - * Returns the value of field 'ypos'. - * - * @return the value of field 'Ypos'. - */ - public int getYpos() - { - return this._ypos; - } - - /** - * Method hasCentreColumnLabels. - * - * @return true if at least one CentreColumnLabels has been adde - */ - public boolean hasCentreColumnLabels() - { - return this._has_centreColumnLabels; - } - - /** - * Method hasConsThreshold. - * - * @return true if at least one ConsThreshold has been added - */ - public boolean hasConsThreshold() - { - return this._has_consThreshold; - } - - /** - * Method hasConservationSelected. - * - * @return true if at least one ConservationSelected has been added - */ - public boolean hasConservationSelected() - { - return this._has_conservationSelected; - } - - /** - * Method hasFollowHighlight. - * - * @return true if at least one FollowHighlight has been added - */ - public boolean hasFollowHighlight() - { - return this._has_followHighlight; - } - - /** - * Method hasFollowSelection. - * - * @return true if at least one FollowSelection has been added - */ - public boolean hasFollowSelection() - { - return this._has_followSelection; - } - - /** - * Method hasFontSize. - * - * @return true if at least one FontSize has been added - */ - public boolean hasFontSize() - { - return this._has_fontSize; - } - - /** - * Method hasFontStyle. - * - * @return true if at least one FontStyle has been added - */ - public boolean hasFontStyle() - { - return this._has_fontStyle; - } - - /** - * Method hasGatheredViews. - * - * @return true if at least one GatheredViews has been added - */ - public boolean hasGatheredViews() - { - return this._has_gatheredViews; - } - - /** - * Method hasHeight. - * - * @return true if at least one Height has been added - */ - public boolean hasHeight() - { - return this._has_height; - } - - /** - * Method hasIgnoreGapsinConsensus. - * - * @return true if at least one IgnoreGapsinConsensus has been added - */ - public boolean hasIgnoreGapsinConsensus() - { - return this._has_ignoreGapsinConsensus; - } - - /** - * Method hasNormaliseSequenceLogo. - * - * @return true if at least one NormaliseSequenceLogo has been added - */ - public boolean hasNormaliseSequenceLogo() - { - return this._has_normaliseSequenceLogo; - } - - /** - * Method hasPidSelected. - * - * @return true if at least one PidSelected has been added - */ - public boolean hasPidSelected() - { - return this._has_pidSelected; - } - - /** - * Method hasPidThreshold. - * - * @return true if at least one PidThreshold has been added - */ - public boolean hasPidThreshold() - { - return this._has_pidThreshold; - } - - /** - * Method hasRenderGaps. - * - * @return true if at least one RenderGaps has been added - */ - public boolean hasRenderGaps() - { - return this._has_renderGaps; - } - - /** - * Method hasRightAlignIds. - * - * @return true if at least one RightAlignIds has been added - */ - public boolean hasRightAlignIds() - { - return this._has_rightAlignIds; - } - - /** - * Method hasShowAnnotation. - * - * @return true if at least one ShowAnnotation has been added - */ - public boolean hasShowAnnotation() - { - return this._has_showAnnotation; - } - - /** - * Method hasShowBoxes. - * - * @return true if at least one ShowBoxes has been added - */ - public boolean hasShowBoxes() - { - return this._has_showBoxes; - } - - /** - * Method hasShowColourText. - * - * @return true if at least one ShowColourText has been added - */ - public boolean hasShowColourText() - { - return this._has_showColourText; - } - - /** - * Method hasShowConsensusHistogram. - * - * @return true if at least one ShowConsensusHistogram has been added - */ - public boolean hasShowConsensusHistogram() - { - return this._has_showConsensusHistogram; - } - - /** - * Method hasShowDbRefTooltip. - * - * @return true if at least one ShowDbRefTooltip has been added - */ - public boolean hasShowDbRefTooltip() - { - return this._has_showDbRefTooltip; - } - - /** - * Method hasShowFullId. - * - * @return true if at least one ShowFullId has been added - */ - public boolean hasShowFullId() - { - return this._has_showFullId; - } - - /** - * Method hasShowGroupConsensus. - * - * @return true if at least one ShowGroupConsensus has been adde - */ - public boolean hasShowGroupConsensus() - { - return this._has_showGroupConsensus; - } - - /** - * Method hasShowGroupConservation. - * - * @return true if at least one ShowGroupConservation has been added - */ - public boolean hasShowGroupConservation() - { - return this._has_showGroupConservation; - } - - /** - * Method hasShowNPfeatureTooltip. - * - * @return true if at least one ShowNPfeatureTooltip has been added - */ - public boolean hasShowNPfeatureTooltip() - { - return this._has_showNPfeatureTooltip; - } - - /** - * Method hasShowSequenceFeatures. - * - * @return true if at least one ShowSequenceFeatures has been added - */ - public boolean hasShowSequenceFeatures() - { - return this._has_showSequenceFeatures; - } - - /** - * Method hasShowSequenceLogo. - * - * @return true if at least one ShowSequenceLogo has been added - */ - public boolean hasShowSequenceLogo() - { - return this._has_showSequenceLogo; - } - - /** - * Method hasShowText. - * - * @return true if at least one ShowText has been added - */ - public boolean hasShowText() - { - return this._has_showText; - } - - /** - * Method hasShowUnconserved. - * - * @return true if at least one ShowUnconserved has been added - */ - public boolean hasShowUnconserved() - { - return this._has_showUnconserved; - } - - /** - * Method hasStartRes. - * - * @return true if at least one StartRes has been added - */ - public boolean hasStartRes() - { - return this._has_startRes; - } - - /** - * Method hasStartSeq. - * - * @return true if at least one StartSeq has been added - */ - public boolean hasStartSeq() - { - return this._has_startSeq; - } - - /** - * Method hasTextCol1. - * - * @return true if at least one TextCol1 has been added - */ - public boolean hasTextCol1() - { - return this._has_textCol1; - } - - /** - * Method hasTextCol2. - * - * @return true if at least one TextCol2 has been added - */ - public boolean hasTextCol2() - { - return this._has_textCol2; - } - - /** - * Method hasTextColThreshold. - * - * @return true if at least one TextColThreshold has been added - */ - public boolean hasTextColThreshold() - { - return this._has_textColThreshold; - } - - /** - * Method hasWidth. - * - * @return true if at least one Width has been added - */ - public boolean hasWidth() - { - return this._has_width; - } - - /** - * Method hasWrapAlignment. - * - * @return true if at least one WrapAlignment has been added - */ - public boolean hasWrapAlignment() - { - return this._has_wrapAlignment; - } - - /** - * Method hasXpos. - * - * @return true if at least one Xpos has been added - */ - public boolean hasXpos() - { - return this._has_xpos; - } - - /** - * Method hasYpos. - * - * @return true if at least one Ypos has been added - */ - public boolean hasYpos() - { - return this._has_ypos; - } - - /** - * Returns the value of field 'centreColumnLabels'. - * - * @return the value of field 'CentreColumnLabels'. - */ - public boolean isCentreColumnLabels() - { - return this._centreColumnLabels; - } - - /** - * Returns the value of field 'conservationSelected'. - * - * @return the value of field 'ConservationSelected'. - */ - public boolean isConservationSelected() - { - return this._conservationSelected; - } - - /** - * Returns the value of field 'followHighlight'. - * - * @return the value of field 'FollowHighlight'. - */ - public boolean isFollowHighlight() - { - return this._followHighlight; - } - - /** - * Returns the value of field 'followSelection'. - * - * @return the value of field 'FollowSelection'. - */ - public boolean isFollowSelection() - { - return this._followSelection; - } - - /** - * Returns the value of field 'gatheredViews'. - * - * @return the value of field 'GatheredViews'. - */ - public boolean isGatheredViews() - { - return this._gatheredViews; - } - - /** - * Returns the value of field 'ignoreGapsinConsensus'. - * - * @return the value of field 'IgnoreGapsinConsensus'. - */ - public boolean isIgnoreGapsinConsensus() - { - return this._ignoreGapsinConsensus; - } - - /** - * Returns the value of field 'normaliseSequenceLogo'. - * - * @return the value of field 'NormaliseSequenceLogo'. - */ - public boolean isNormaliseSequenceLogo() - { - return this._normaliseSequenceLogo; - } - - /** - * Returns the value of field 'pidSelected'. - * - * @return the value of field 'PidSelected'. - */ - public boolean isPidSelected() - { - return this._pidSelected; - } - - /** - * Returns the value of field 'renderGaps'. - * - * @return the value of field 'RenderGaps'. - */ - public boolean isRenderGaps() - { - return this._renderGaps; - } - - /** - * Returns the value of field 'rightAlignIds'. - * - * @return the value of field 'RightAlignIds'. - */ - public boolean isRightAlignIds() - { - return this._rightAlignIds; - } - - /** - * Returns the value of field 'showAnnotation'. - * - * @return the value of field 'ShowAnnotation'. - */ - public boolean isShowAnnotation() - { - return this._showAnnotation; - } - - /** - * Returns the value of field 'showBoxes'. - * - * @return the value of field 'ShowBoxes'. - */ - public boolean isShowBoxes() - { - return this._showBoxes; - } - - /** - * Returns the value of field 'showColourText'. - * - * @return the value of field 'ShowColourText'. - */ - public boolean isShowColourText() - { - return this._showColourText; - } - - /** - * Returns the value of field 'showConsensusHistogram'. - * - * @return the value of field 'ShowConsensusHistogram'. - */ - public boolean isShowConsensusHistogram() - { - return this._showConsensusHistogram; - } - - /** - * Returns the value of field 'showDbRefTooltip'. - * - * @return the value of field 'ShowDbRefTooltip'. - */ - public boolean isShowDbRefTooltip() - { - return this._showDbRefTooltip; - } - - /** - * Returns the value of field 'showFullId'. - * - * @return the value of field 'ShowFullId'. - */ - public boolean isShowFullId() - { - return this._showFullId; - } - - /** - * Returns the value of field 'showGroupConsensus'. - * - * @return the value of field 'ShowGroupConsensus'. - */ - public boolean isShowGroupConsensus() - { - return this._showGroupConsensus; - } - - /** - * Returns the value of field 'showGroupConservation'. - * - * @return the value of field 'ShowGroupConservation'. - */ - public boolean isShowGroupConservation() - { - return this._showGroupConservation; - } - - /** - * Returns the value of field 'showNPfeatureTooltip'. - * - * @return the value of field 'ShowNPfeatureTooltip'. - */ - public boolean isShowNPfeatureTooltip() - { - return this._showNPfeatureTooltip; - } - - /** - * Returns the value of field 'showSequenceFeatures'. - * - * @return the value of field 'ShowSequenceFeatures'. - */ - public boolean isShowSequenceFeatures() - { - return this._showSequenceFeatures; - } - - /** - * Returns the value of field 'showSequenceLogo'. - * - * @return the value of field 'ShowSequenceLogo'. - */ - public boolean isShowSequenceLogo() - { - return this._showSequenceLogo; - } - - /** - * Returns the value of field 'showText'. - * - * @return the value of field 'ShowText'. - */ - public boolean isShowText() - { - return this._showText; - } - - /** - * Returns the value of field 'showUnconserved'. - * - * @return the value of field 'ShowUnconserved'. - */ - public boolean isShowUnconserved() - { - return this._showUnconserved; - } - - /** - * Method isValid. - * - * @return true if this object is valid according to the schema - */ - public boolean isValid() - { - try - { - validate(); - } catch (org.exolab.castor.xml.ValidationException vex) - { - return false; - } - return true; - } - - /** - * Returns the value of field 'wrapAlignment'. - * - * @return the value of field 'WrapAlignment'. - */ - public boolean isWrapAlignment() - { - return this._wrapAlignment; - } - - /** - * - * - * @param out - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - */ - public void marshal(final java.io.Writer out) - throws org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - Marshaller.marshal(this, out); - } - - /** - * - * - * @param handler - * @throws java.io.IOException - * if an IOException occurs during marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - */ - public void marshal(final org.xml.sax.ContentHandler handler) - throws java.io.IOException, - org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - Marshaller.marshal(this, handler); - } - - /** - */ - public void removeAllCalcIdParam() - { - this._calcIdParamList.clear(); - } - - /** - */ - public void removeAllHiddenColumns() - { - this._hiddenColumnsList.clear(); - } - - /** - * Method removeCalcIdParam. - * - * @param vCalcIdParam - * @return true if the object was removed from the collection. - */ - public boolean removeCalcIdParam( - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - { - boolean removed = _calcIdParamList.remove(vCalcIdParam); - return removed; - } - - /** - * Method removeCalcIdParamAt. - * - * @param index - * @return the element removed from the collection - */ - public jalview.schemabinding.version2.CalcIdParam removeCalcIdParamAt( - final int index) - { - java.lang.Object obj = this._calcIdParamList.remove(index); - return (jalview.schemabinding.version2.CalcIdParam) obj; - } - - /** - * Method removeHiddenColumns. - * - * @param vHiddenColumns - * @return true if the object was removed from the collection. - */ - public boolean removeHiddenColumns( - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - { - boolean removed = _hiddenColumnsList.remove(vHiddenColumns); - return removed; - } - - /** - * Method removeHiddenColumnsAt. - * - * @param index - * @return the element removed from the collection - */ - public jalview.schemabinding.version2.HiddenColumns removeHiddenColumnsAt( - final int index) - { - java.lang.Object obj = this._hiddenColumnsList.remove(index); - return (jalview.schemabinding.version2.HiddenColumns) obj; - } - - /** - * Sets the value of field 'annotationColours'. - * - * @param annotationColours - * the value of field 'annotationColours'. - */ - public void setAnnotationColours( - final jalview.schemabinding.version2.AnnotationColours annotationColours) - { - this._annotationColours = annotationColours; - } - - /** - * Sets the value of field 'bgColour'. - * - * @param bgColour - * the value of field 'bgColour'. - */ - public void setBgColour(final java.lang.String bgColour) - { - this._bgColour = bgColour; - } - - /** - * - * - * @param index - * @param vCalcIdParam - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void setCalcIdParam(final int index, - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._calcIdParamList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "setCalcIdParam", - Integer.valueOf(index).toString(), - Integer.valueOf((this._calcIdParamList.size() - 1)).toString() - })); - } - - this._calcIdParamList.set(index, vCalcIdParam); - } - - /** - * - * - * @param vCalcIdParamArray - */ - public void setCalcIdParam( - final jalview.schemabinding.version2.CalcIdParam[] vCalcIdParamArray) - { - // -- copy array - _calcIdParamList.clear(); - - for (int i = 0; i < vCalcIdParamArray.length; i++) - { - this._calcIdParamList.add(vCalcIdParamArray[i]); - } - } - - /** - * Sets the value of field 'centreColumnLabels'. - * - * @param centreColumnLabels - * the value of field 'centreColumnLabels'. - */ - public void setCentreColumnLabels(final boolean centreColumnLabels) - { - this._centreColumnLabels = centreColumnLabels; - this._has_centreColumnLabels = true; - } - - /** - * Sets the value of field 'consThreshold'. - * - * @param consThreshold - * the value of field 'consThreshold'. - */ - public void setConsThreshold(final int consThreshold) - { - this._consThreshold = consThreshold; - this._has_consThreshold = true; - } - - /** - * Sets the value of field 'conservationSelected'. - * - * @param conservationSelected - * the value of field 'conservationSelected'. - */ - public void setConservationSelected(final boolean conservationSelected) - { - this._conservationSelected = conservationSelected; - this._has_conservationSelected = true; - } - - /** - * Sets the value of field 'followHighlight'. - * - * @param followHighlight - * the value of field 'followHighlight'. - */ - public void setFollowHighlight(final boolean followHighlight) - { - this._followHighlight = followHighlight; - this._has_followHighlight = true; - } - - /** - * Sets the value of field 'followSelection'. - * - * @param followSelection - * the value of field 'followSelection'. - */ - public void setFollowSelection(final boolean followSelection) - { - this._followSelection = followSelection; - this._has_followSelection = true; - } - - /** - * Sets the value of field 'fontName'. - * - * @param fontName - * the value of field 'fontName'. - */ - public void setFontName(final java.lang.String fontName) - { - this._fontName = fontName; - } - - /** - * Sets the value of field 'fontSize'. - * - * @param fontSize - * the value of field 'fontSize'. - */ - public void setFontSize(final int fontSize) - { - this._fontSize = fontSize; - this._has_fontSize = true; - } - - /** - * Sets the value of field 'fontStyle'. - * - * @param fontStyle - * the value of field 'fontStyle'. - */ - public void setFontStyle(final int fontStyle) - { - this._fontStyle = fontStyle; - this._has_fontStyle = true; - } - - /** - * Sets the value of field 'gatheredViews'. - * - * @param gatheredViews - * the value of field 'gatheredViews'. - */ - public void setGatheredViews(final boolean gatheredViews) - { - this._gatheredViews = gatheredViews; - this._has_gatheredViews = true; - } - - /** - * Sets the value of field 'height'. - * - * @param height - * the value of field 'height'. - */ - public void setHeight(final int height) - { - this._height = height; - this._has_height = true; - } - - /** - * - * - * @param index - * @param vHiddenColumns - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void setHiddenColumns(final int index, - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._hiddenColumnsList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "setHiddenColumns", - Integer.valueOf(index).toString(), - Integer.valueOf((this._hiddenColumnsList.size() - 1)).toString() - })); - } - - this._hiddenColumnsList.set(index, vHiddenColumns); - } - - /** - * - * - * @param vHiddenColumnsArray - */ - public void setHiddenColumns( - final jalview.schemabinding.version2.HiddenColumns[] vHiddenColumnsArray) - { - // -- copy array - _hiddenColumnsList.clear(); - - for (int i = 0; i < vHiddenColumnsArray.length; i++) - { - this._hiddenColumnsList.add(vHiddenColumnsArray[i]); - } - } - - /** - * Sets the value of field 'id'. The field 'id' has the following description: - * unique id used by jalview to synchronize between stored and instantiated - * views - * - * - * @param id - * the value of field 'id'. - */ - public void setId(final java.lang.String id) - { - this._id = id; - } - - /** - * Sets the value of field 'ignoreGapsinConsensus'. - * - * @param ignoreGapsinConsensus - * the value of field 'ignoreGapsinConsensus'. - */ - public void setIgnoreGapsinConsensus(final boolean ignoreGapsinConsensus) - { - this._ignoreGapsinConsensus = ignoreGapsinConsensus; - this._has_ignoreGapsinConsensus = true; - } - - /** - * Sets the value of field 'normaliseSequenceLogo'. - * - * @param normaliseSequenceLogo - * the value of field 'normaliseSequenceLogo'. - */ - public void setNormaliseSequenceLogo(final boolean normaliseSequenceLogo) - { - this._normaliseSequenceLogo = normaliseSequenceLogo; - this._has_normaliseSequenceLogo = true; - } - - /** - * Sets the value of field 'pidSelected'. - * - * @param pidSelected - * the value of field 'pidSelected'. - */ - public void setPidSelected(final boolean pidSelected) - { - this._pidSelected = pidSelected; - this._has_pidSelected = true; - } - - /** - * Sets the value of field 'pidThreshold'. - * - * @param pidThreshold - * the value of field 'pidThreshold'. - */ - public void setPidThreshold(final int pidThreshold) - { - this._pidThreshold = pidThreshold; - this._has_pidThreshold = true; - } - - /** - * Sets the value of field 'renderGaps'. - * - * @param renderGaps - * the value of field 'renderGaps'. - */ - public void setRenderGaps(final boolean renderGaps) - { - this._renderGaps = renderGaps; - this._has_renderGaps = true; - } - - /** - * Sets the value of field 'rightAlignIds'. - * - * @param rightAlignIds - * the value of field 'rightAlignIds'. - */ - public void setRightAlignIds(final boolean rightAlignIds) - { - this._rightAlignIds = rightAlignIds; - this._has_rightAlignIds = true; - } - - /** - * Sets the value of field 'sequenceSetId'. - * - * @param sequenceSetId - * the value of field 'sequenceSetId'. - */ - public void setSequenceSetId(final java.lang.String sequenceSetId) - { - this._sequenceSetId = sequenceSetId; - } - - /** - * Sets the value of field 'showAnnotation'. - * - * @param showAnnotation - * the value of field 'showAnnotation'. - */ - public void setShowAnnotation(final boolean showAnnotation) - { - this._showAnnotation = showAnnotation; - this._has_showAnnotation = true; - } - - /** - * Sets the value of field 'showBoxes'. - * - * @param showBoxes - * the value of field 'showBoxes'. - */ - public void setShowBoxes(final boolean showBoxes) - { - this._showBoxes = showBoxes; - this._has_showBoxes = true; - } - - /** - * Sets the value of field 'showColourText'. - * - * @param showColourText - * the value of field 'showColourText'. - */ - public void setShowColourText(final boolean showColourText) - { - this._showColourText = showColourText; - this._has_showColourText = true; - } - - /** - * Sets the value of field 'showConsensusHistogram'. - * - * @param showConsensusHistogram - * the value of field 'showConsensusHistogram'. - */ - public void setShowConsensusHistogram(final boolean showConsensusHistogram) - { - this._showConsensusHistogram = showConsensusHistogram; - this._has_showConsensusHistogram = true; - } - - /** - * Sets the value of field 'showDbRefTooltip'. - * - * @param showDbRefTooltip - * the value of field 'showDbRefTooltip' - */ - public void setShowDbRefTooltip(final boolean showDbRefTooltip) - { - this._showDbRefTooltip = showDbRefTooltip; - this._has_showDbRefTooltip = true; - } - - /** - * Sets the value of field 'showFullId'. - * - * @param showFullId - * the value of field 'showFullId'. - */ - public void setShowFullId(final boolean showFullId) - { - this._showFullId = showFullId; - this._has_showFullId = true; - } - - /** - * Sets the value of field 'showGroupConsensus'. - * - * @param showGroupConsensus - * the value of field 'showGroupConsensus'. - */ - public void setShowGroupConsensus(final boolean showGroupConsensus) - { - this._showGroupConsensus = showGroupConsensus; - this._has_showGroupConsensus = true; - } - - /** - * Sets the value of field 'showGroupConservation'. - * - * @param showGroupConservation - * the value of field 'showGroupConservation'. - */ - public void setShowGroupConservation(final boolean showGroupConservation) - { - this._showGroupConservation = showGroupConservation; - this._has_showGroupConservation = true; - } - - /** - * Sets the value of field 'showNPfeatureTooltip'. - * - * @param showNPfeatureTooltip - * the value of field 'showNPfeatureTooltip'. - */ - public void setShowNPfeatureTooltip(final boolean showNPfeatureTooltip) - { - this._showNPfeatureTooltip = showNPfeatureTooltip; - this._has_showNPfeatureTooltip = true; - } - - /** - * Sets the value of field 'showSequenceFeatures'. - * - * @param showSequenceFeatures - * the value of field 'showSequenceFeatures'. - */ - public void setShowSequenceFeatures(final boolean showSequenceFeatures) - { - this._showSequenceFeatures = showSequenceFeatures; - this._has_showSequenceFeatures = true; - } - - /** - * Sets the value of field 'showSequenceLogo'. - * - * @param showSequenceLogo - * the value of field 'showSequenceLogo' - */ - public void setShowSequenceLogo(final boolean showSequenceLogo) - { - this._showSequenceLogo = showSequenceLogo; - this._has_showSequenceLogo = true; - } - - /** - * Sets the value of field 'showText'. - * - * @param showText - * the value of field 'showText'. - */ - public void setShowText(final boolean showText) - { - this._showText = showText; - this._has_showText = true; - } - - /** - * Sets the value of field 'showUnconserved'. - * - * @param showUnconserved - * the value of field 'showUnconserved'. - */ - public void setShowUnconserved(final boolean showUnconserved) - { - this._showUnconserved = showUnconserved; - this._has_showUnconserved = true; - } - - /** - * Sets the value of field 'startRes'. - * - * @param startRes - * the value of field 'startRes'. - */ - public void setStartRes(final int startRes) - { - this._startRes = startRes; - this._has_startRes = true; - } - - /** - * Sets the value of field 'startSeq'. - * - * @param startSeq - * the value of field 'startSeq'. - */ - public void setStartSeq(final int startSeq) - { - this._startSeq = startSeq; - this._has_startSeq = true; - } - - /** - * Sets the value of field 'textCol1'. - * - * @param textCol1 - * the value of field 'textCol1'. - */ - public void setTextCol1(final int textCol1) - { - this._textCol1 = textCol1; - this._has_textCol1 = true; - } - - /** - * Sets the value of field 'textCol2'. - * - * @param textCol2 - * the value of field 'textCol2'. - */ - public void setTextCol2(final int textCol2) - { - this._textCol2 = textCol2; - this._has_textCol2 = true; - } - - /** - * Sets the value of field 'textColThreshold'. - * - * @param textColThreshold - * the value of field 'textColThreshold' - */ - public void setTextColThreshold(final int textColThreshold) - { - this._textColThreshold = textColThreshold; - this._has_textColThreshold = true; - } - - /** - * Sets the value of field 'title'. - * - * @param title - * the value of field 'title'. - */ - public void setTitle(final java.lang.String title) - { - this._title = title; - } - - /** - * Sets the value of field 'viewName'. - * - * @param viewName - * the value of field 'viewName'. - */ - public void setViewName(final java.lang.String viewName) - { - this._viewName = viewName; - } - - /** - * Sets the value of field 'width'. - * - * @param width - * the value of field 'width'. - */ - public void setWidth(final int width) - { - this._width = width; - this._has_width = true; - } - - /** - * Sets the value of field 'wrapAlignment'. - * - * @param wrapAlignment - * the value of field 'wrapAlignment'. - */ - public void setWrapAlignment(final boolean wrapAlignment) - { - this._wrapAlignment = wrapAlignment; - this._has_wrapAlignment = true; - } - - /** - * Sets the value of field 'xpos'. - * - * @param xpos - * the value of field 'xpos'. - */ - public void setXpos(final int xpos) - { - this._xpos = xpos; - this._has_xpos = true; - } - - /** - * Sets the value of field 'ypos'. - * - * @param ypos - * the value of field 'ypos'. - */ - public void setYpos(final int ypos) - { - this._ypos = ypos; - this._has_ypos = true; - } - - /** - * Method unmarshal. - * - * @param reader - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - * @return the unmarshaled jalview.schemabinding.version2.Viewport - */ - public static jalview.schemabinding.version2.Viewport unmarshal( - final java.io.Reader reader) - throws org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - return (jalview.schemabinding.version2.Viewport) Unmarshaller - .unmarshal(jalview.schemabinding.version2.Viewport.class, - reader); - } - - /** - * - * - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - */ - public void validate() throws org.exolab.castor.xml.ValidationException - { - org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator(); - validator.validate(this); - } + private jalview.schemabinding.version2.AnnotationColours _annotationColours; + + /** + * Field _hiddenColumnsList. + */ + private java.util.Vector _hiddenColumnsList; + + /** + * Field _calcIdParamList. + */ + private java.util.Vector _calcIdParamList; + + + //----------------/ + //- Constructors -/ + //----------------/ + + public Viewport() { + super(); + this._hiddenColumnsList = new java.util.Vector(); + this._calcIdParamList = new java.util.Vector(); + } + + + //-----------/ + //- Methods -/ + //-----------/ + + /** + * + * + * @param vCalcIdParam + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addCalcIdParam( + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) + throws java.lang.IndexOutOfBoundsException { + this._calcIdParamList.addElement(vCalcIdParam); + } + + /** + * + * + * @param index + * @param vCalcIdParam + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addCalcIdParam( + final int index, + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) + throws java.lang.IndexOutOfBoundsException { + this._calcIdParamList.add(index, vCalcIdParam); + } + + /** + * + * + * @param vHiddenColumns + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addHiddenColumns( + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) + throws java.lang.IndexOutOfBoundsException { + this._hiddenColumnsList.addElement(vHiddenColumns); + } + + /** + * + * + * @param index + * @param vHiddenColumns + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addHiddenColumns( + final int index, + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) + throws java.lang.IndexOutOfBoundsException { + this._hiddenColumnsList.add(index, vHiddenColumns); + } + + /** + */ + public void deleteCentreColumnLabels( + ) { + this._has_centreColumnLabels= false; + } + + /** + */ + public void deleteConsThreshold( + ) { + this._has_consThreshold= false; + } + + /** + */ + public void deleteConservationSelected( + ) { + this._has_conservationSelected= false; + } + + /** + */ + public void deleteFollowHighlight( + ) { + this._has_followHighlight= false; + } + + /** + */ + public void deleteFollowSelection( + ) { + this._has_followSelection= false; + } + + /** + */ + public void deleteFontSize( + ) { + this._has_fontSize= false; + } + + /** + */ + public void deleteFontStyle( + ) { + this._has_fontStyle= false; + } + + /** + */ + public void deleteGatheredViews( + ) { + this._has_gatheredViews= false; + } + + /** + */ + public void deleteHeight( + ) { + this._has_height= false; + } + + /** + */ + public void deleteIgnoreGapsinConsensus( + ) { + this._has_ignoreGapsinConsensus= false; + } + + /** + */ + public void deleteNormaliseSequenceLogo( + ) { + this._has_normaliseSequenceLogo= false; + } + + /** + */ + public void deletePidSelected( + ) { + this._has_pidSelected= false; + } + + /** + */ + public void deletePidThreshold( + ) { + this._has_pidThreshold= false; + } + + /** + */ + public void deleteRenderGaps( + ) { + this._has_renderGaps= false; + } + + /** + */ + public void deleteRightAlignIds( + ) { + this._has_rightAlignIds= false; + } + + /** + */ + public void deleteShowAnnotation( + ) { + this._has_showAnnotation= false; + } + + /** + */ + public void deleteShowBoxes( + ) { + this._has_showBoxes= false; + } + + /** + */ + public void deleteShowColourText( + ) { + this._has_showColourText= false; + } + + /** + */ + public void deleteShowConsensusHistogram( + ) { + this._has_showConsensusHistogram= false; + } + + /** + */ + public void deleteShowDbRefTooltip( + ) { + this._has_showDbRefTooltip= false; + } + + /** + */ + public void deleteShowFullId( + ) { + this._has_showFullId= false; + } + + /** + */ + public void deleteShowGroupConsensus( + ) { + this._has_showGroupConsensus= false; + } + + /** + */ + public void deleteShowGroupConservation( + ) { + this._has_showGroupConservation= false; + } + + /** + */ + public void deleteShowNPfeatureTooltip( + ) { + this._has_showNPfeatureTooltip= false; + } + + /** + */ + public void deleteShowSequenceFeatures( + ) { + this._has_showSequenceFeatures= false; + } + + /** + */ + public void deleteShowSequenceLogo( + ) { + this._has_showSequenceLogo= false; + } + + /** + */ + public void deleteShowText( + ) { + this._has_showText= false; + } + + /** + */ + public void deleteShowUnconserved( + ) { + this._has_showUnconserved= false; + } + + /** + */ + public void deleteStartRes( + ) { + this._has_startRes= false; + } + + /** + */ + public void deleteStartSeq( + ) { + this._has_startSeq= false; + } + + /** + */ + public void deleteTextCol1( + ) { + this._has_textCol1= false; + } + + /** + */ + public void deleteTextCol2( + ) { + this._has_textCol2= false; + } + + /** + */ + public void deleteTextColThreshold( + ) { + this._has_textColThreshold= false; + } + + /** + */ + public void deleteWidth( + ) { + this._has_width= false; + } + + /** + */ + public void deleteWrapAlignment( + ) { + this._has_wrapAlignment= false; + } + + /** + */ + public void deleteXpos( + ) { + this._has_xpos= false; + } + + /** + */ + public void deleteYpos( + ) { + this._has_ypos= false; + } + + /** + * Method enumerateCalcIdParam. + * + * @return an Enumeration over all + * jalview.schemabinding.version2.CalcIdParam elements + */ + public java.util.Enumeration enumerateCalcIdParam( + ) { + return this._calcIdParamList.elements(); + } + + /** + * Method enumerateHiddenColumns. + * + * @return an Enumeration over all + * jalview.schemabinding.version2.HiddenColumns elements + */ + public java.util.Enumeration enumerateHiddenColumns( + ) { + return this._hiddenColumnsList.elements(); + } + + /** + * Returns the value of field 'annotationColours'. + * + * @return the value of field 'AnnotationColours'. + */ + public jalview.schemabinding.version2.AnnotationColours getAnnotationColours( + ) { + return this._annotationColours; + } + + /** + * Returns the value of field 'bgColour'. + * + * @return the value of field 'BgColour'. + */ + public java.lang.String getBgColour( + ) { + return this._bgColour; + } + + /** + * Method getCalcIdParam. + * + * @param index + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + * @return the value of the + * jalview.schemabinding.version2.CalcIdParam at the given index + */ + public jalview.schemabinding.version2.CalcIdParam getCalcIdParam( + final int index) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._calcIdParamList.size()) { + throw new IndexOutOfBoundsException("getCalcIdParam: Index value '" + index + "' not in range [0.." + (this._calcIdParamList.size() - 1) + "]"); + } + + return (jalview.schemabinding.version2.CalcIdParam) _calcIdParamList.get(index); + } + + /** + * Method getCalcIdParam.Returns the contents of the collection + * in an Array.

Note: Just in case the collection contents + * are changing in another thread, we pass a 0-length Array of + * the correct type into the API call. This way we know + * that the Array returned is of exactly the correct length. + * + * @return this collection as an Array + */ + public jalview.schemabinding.version2.CalcIdParam[] getCalcIdParam( + ) { + jalview.schemabinding.version2.CalcIdParam[] array = new jalview.schemabinding.version2.CalcIdParam[0]; + return (jalview.schemabinding.version2.CalcIdParam[]) this._calcIdParamList.toArray(array); + } + + /** + * Method getCalcIdParamCount. + * + * @return the size of this collection + */ + public int getCalcIdParamCount( + ) { + return this._calcIdParamList.size(); + } + + /** + * Returns the value of field 'centreColumnLabels'. + * + * @return the value of field 'CentreColumnLabels'. + */ + public boolean getCentreColumnLabels( + ) { + return this._centreColumnLabels; + } + + /** + * Returns the value of field 'complementId'. The field + * 'complementId' has the following description: The viewport + * id of this viewport's (cdna/protein) coding complement, if + * any + * + * + * @return the value of field 'ComplementId'. + */ + public java.lang.String getComplementId( + ) { + return this._complementId; + } + + /** + * Returns the value of field 'consThreshold'. + * + * @return the value of field 'ConsThreshold'. + */ + public int getConsThreshold( + ) { + return this._consThreshold; + } + + /** + * Returns the value of field 'conservationSelected'. + * + * @return the value of field 'ConservationSelected'. + */ + public boolean getConservationSelected( + ) { + return this._conservationSelected; + } + + /** + * Returns the value of field 'followHighlight'. + * + * @return the value of field 'FollowHighlight'. + */ + public boolean getFollowHighlight( + ) { + return this._followHighlight; + } + + /** + * Returns the value of field 'followSelection'. + * + * @return the value of field 'FollowSelection'. + */ + public boolean getFollowSelection( + ) { + return this._followSelection; + } + + /** + * Returns the value of field 'fontName'. + * + * @return the value of field 'FontName'. + */ + public java.lang.String getFontName( + ) { + return this._fontName; + } + + /** + * Returns the value of field 'fontSize'. + * + * @return the value of field 'FontSize'. + */ + public int getFontSize( + ) { + return this._fontSize; + } + + /** + * Returns the value of field 'fontStyle'. + * + * @return the value of field 'FontStyle'. + */ + public int getFontStyle( + ) { + return this._fontStyle; + } + + /** + * Returns the value of field 'gatheredViews'. + * + * @return the value of field 'GatheredViews'. + */ + public boolean getGatheredViews( + ) { + return this._gatheredViews; + } + + /** + * Returns the value of field 'height'. + * + * @return the value of field 'Height'. + */ + public int getHeight( + ) { + return this._height; + } + + /** + * Method getHiddenColumns. + * + * @param index + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + * @return the value of the + * jalview.schemabinding.version2.HiddenColumns at the given + * index + */ + public jalview.schemabinding.version2.HiddenColumns getHiddenColumns( + final int index) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._hiddenColumnsList.size()) { + throw new IndexOutOfBoundsException("getHiddenColumns: Index value '" + index + "' not in range [0.." + (this._hiddenColumnsList.size() - 1) + "]"); + } + + return (jalview.schemabinding.version2.HiddenColumns) _hiddenColumnsList.get(index); + } + + /** + * Method getHiddenColumns.Returns the contents of the + * collection in an Array.

Note: Just in case the + * collection contents are changing in another thread, we pass + * a 0-length Array of the correct type into the API call. + * This way we know that the Array returned is of + * exactly the correct length. + * + * @return this collection as an Array + */ + public jalview.schemabinding.version2.HiddenColumns[] getHiddenColumns( + ) { + jalview.schemabinding.version2.HiddenColumns[] array = new jalview.schemabinding.version2.HiddenColumns[0]; + return (jalview.schemabinding.version2.HiddenColumns[]) this._hiddenColumnsList.toArray(array); + } + + /** + * Method getHiddenColumnsCount. + * + * @return the size of this collection + */ + public int getHiddenColumnsCount( + ) { + return this._hiddenColumnsList.size(); + } + + /** + * Returns the value of field 'id'. The field 'id' has the + * following description: unique id used by jalview to + * synchronize between stored and + * instantiated views + * + * + * @return the value of field 'Id'. + */ + public java.lang.String getId( + ) { + return this._id; + } + + /** + * Returns the value of field 'ignoreGapsinConsensus'. + * + * @return the value of field 'IgnoreGapsinConsensus'. + */ + public boolean getIgnoreGapsinConsensus( + ) { + return this._ignoreGapsinConsensus; + } + + /** + * Returns the value of field 'normaliseSequenceLogo'. + * + * @return the value of field 'NormaliseSequenceLogo'. + */ + public boolean getNormaliseSequenceLogo( + ) { + return this._normaliseSequenceLogo; + } + + /** + * Returns the value of field 'pidSelected'. + * + * @return the value of field 'PidSelected'. + */ + public boolean getPidSelected( + ) { + return this._pidSelected; + } + + /** + * Returns the value of field 'pidThreshold'. + * + * @return the value of field 'PidThreshold'. + */ + public int getPidThreshold( + ) { + return this._pidThreshold; + } + + /** + * Returns the value of field 'renderGaps'. + * + * @return the value of field 'RenderGaps'. + */ + public boolean getRenderGaps( + ) { + return this._renderGaps; + } + + /** + * Returns the value of field 'rightAlignIds'. + * + * @return the value of field 'RightAlignIds'. + */ + public boolean getRightAlignIds( + ) { + return this._rightAlignIds; + } + + /** + * Returns the value of field 'sequenceSetId'. + * + * @return the value of field 'SequenceSetId'. + */ + public java.lang.String getSequenceSetId( + ) { + return this._sequenceSetId; + } + + /** + * Returns the value of field 'showAnnotation'. + * + * @return the value of field 'ShowAnnotation'. + */ + public boolean getShowAnnotation( + ) { + return this._showAnnotation; + } + + /** + * Returns the value of field 'showBoxes'. + * + * @return the value of field 'ShowBoxes'. + */ + public boolean getShowBoxes( + ) { + return this._showBoxes; + } + + /** + * Returns the value of field 'showColourText'. + * + * @return the value of field 'ShowColourText'. + */ + public boolean getShowColourText( + ) { + return this._showColourText; + } + + /** + * Returns the value of field 'showConsensusHistogram'. + * + * @return the value of field 'ShowConsensusHistogram'. + */ + public boolean getShowConsensusHistogram( + ) { + return this._showConsensusHistogram; + } + + /** + * Returns the value of field 'showDbRefTooltip'. + * + * @return the value of field 'ShowDbRefTooltip'. + */ + public boolean getShowDbRefTooltip( + ) { + return this._showDbRefTooltip; + } + + /** + * Returns the value of field 'showFullId'. + * + * @return the value of field 'ShowFullId'. + */ + public boolean getShowFullId( + ) { + return this._showFullId; + } + + /** + * Returns the value of field 'showGroupConsensus'. + * + * @return the value of field 'ShowGroupConsensus'. + */ + public boolean getShowGroupConsensus( + ) { + return this._showGroupConsensus; + } + + /** + * Returns the value of field 'showGroupConservation'. + * + * @return the value of field 'ShowGroupConservation'. + */ + public boolean getShowGroupConservation( + ) { + return this._showGroupConservation; + } + + /** + * Returns the value of field 'showNPfeatureTooltip'. + * + * @return the value of field 'ShowNPfeatureTooltip'. + */ + public boolean getShowNPfeatureTooltip( + ) { + return this._showNPfeatureTooltip; + } + + /** + * Returns the value of field 'showSequenceFeatures'. + * + * @return the value of field 'ShowSequenceFeatures'. + */ + public boolean getShowSequenceFeatures( + ) { + return this._showSequenceFeatures; + } + + /** + * Returns the value of field 'showSequenceLogo'. + * + * @return the value of field 'ShowSequenceLogo'. + */ + public boolean getShowSequenceLogo( + ) { + return this._showSequenceLogo; + } + + /** + * Returns the value of field 'showText'. + * + * @return the value of field 'ShowText'. + */ + public boolean getShowText( + ) { + return this._showText; + } + + /** + * Returns the value of field 'showUnconserved'. + * + * @return the value of field 'ShowUnconserved'. + */ + public boolean getShowUnconserved( + ) { + return this._showUnconserved; + } + + /** + * Returns the value of field 'startRes'. + * + * @return the value of field 'StartRes'. + */ + public int getStartRes( + ) { + return this._startRes; + } + + /** + * Returns the value of field 'startSeq'. + * + * @return the value of field 'StartSeq'. + */ + public int getStartSeq( + ) { + return this._startSeq; + } + + /** + * Returns the value of field 'textCol1'. + * + * @return the value of field 'TextCol1'. + */ + public int getTextCol1( + ) { + return this._textCol1; + } + + /** + * Returns the value of field 'textCol2'. + * + * @return the value of field 'TextCol2'. + */ + public int getTextCol2( + ) { + return this._textCol2; + } + + /** + * Returns the value of field 'textColThreshold'. + * + * @return the value of field 'TextColThreshold'. + */ + public int getTextColThreshold( + ) { + return this._textColThreshold; + } + + /** + * Returns the value of field 'title'. + * + * @return the value of field 'Title'. + */ + public java.lang.String getTitle( + ) { + return this._title; + } + + /** + * Returns the value of field 'viewName'. + * + * @return the value of field 'ViewName'. + */ + public java.lang.String getViewName( + ) { + return this._viewName; + } + + /** + * Returns the value of field 'width'. + * + * @return the value of field 'Width'. + */ + public int getWidth( + ) { + return this._width; + } + + /** + * Returns the value of field 'wrapAlignment'. + * + * @return the value of field 'WrapAlignment'. + */ + public boolean getWrapAlignment( + ) { + return this._wrapAlignment; + } + + /** + * Returns the value of field 'xpos'. + * + * @return the value of field 'Xpos'. + */ + public int getXpos( + ) { + return this._xpos; + } + + /** + * Returns the value of field 'ypos'. + * + * @return the value of field 'Ypos'. + */ + public int getYpos( + ) { + return this._ypos; + } + + /** + * Method hasCentreColumnLabels. + * + * @return true if at least one CentreColumnLabels has been adde + */ + public boolean hasCentreColumnLabels( + ) { + return this._has_centreColumnLabels; + } + + /** + * Method hasConsThreshold. + * + * @return true if at least one ConsThreshold has been added + */ + public boolean hasConsThreshold( + ) { + return this._has_consThreshold; + } + + /** + * Method hasConservationSelected. + * + * @return true if at least one ConservationSelected has been + * added + */ + public boolean hasConservationSelected( + ) { + return this._has_conservationSelected; + } + + /** + * Method hasFollowHighlight. + * + * @return true if at least one FollowHighlight has been added + */ + public boolean hasFollowHighlight( + ) { + return this._has_followHighlight; + } + + /** + * Method hasFollowSelection. + * + * @return true if at least one FollowSelection has been added + */ + public boolean hasFollowSelection( + ) { + return this._has_followSelection; + } + + /** + * Method hasFontSize. + * + * @return true if at least one FontSize has been added + */ + public boolean hasFontSize( + ) { + return this._has_fontSize; + } + + /** + * Method hasFontStyle. + * + * @return true if at least one FontStyle has been added + */ + public boolean hasFontStyle( + ) { + return this._has_fontStyle; + } + + /** + * Method hasGatheredViews. + * + * @return true if at least one GatheredViews has been added + */ + public boolean hasGatheredViews( + ) { + return this._has_gatheredViews; + } + + /** + * Method hasHeight. + * + * @return true if at least one Height has been added + */ + public boolean hasHeight( + ) { + return this._has_height; + } + + /** + * Method hasIgnoreGapsinConsensus. + * + * @return true if at least one IgnoreGapsinConsensus has been + * added + */ + public boolean hasIgnoreGapsinConsensus( + ) { + return this._has_ignoreGapsinConsensus; + } + + /** + * Method hasNormaliseSequenceLogo. + * + * @return true if at least one NormaliseSequenceLogo has been + * added + */ + public boolean hasNormaliseSequenceLogo( + ) { + return this._has_normaliseSequenceLogo; + } + + /** + * Method hasPidSelected. + * + * @return true if at least one PidSelected has been added + */ + public boolean hasPidSelected( + ) { + return this._has_pidSelected; + } + + /** + * Method hasPidThreshold. + * + * @return true if at least one PidThreshold has been added + */ + public boolean hasPidThreshold( + ) { + return this._has_pidThreshold; + } + + /** + * Method hasRenderGaps. + * + * @return true if at least one RenderGaps has been added + */ + public boolean hasRenderGaps( + ) { + return this._has_renderGaps; + } + + /** + * Method hasRightAlignIds. + * + * @return true if at least one RightAlignIds has been added + */ + public boolean hasRightAlignIds( + ) { + return this._has_rightAlignIds; + } + + /** + * Method hasShowAnnotation. + * + * @return true if at least one ShowAnnotation has been added + */ + public boolean hasShowAnnotation( + ) { + return this._has_showAnnotation; + } + + /** + * Method hasShowBoxes. + * + * @return true if at least one ShowBoxes has been added + */ + public boolean hasShowBoxes( + ) { + return this._has_showBoxes; + } + + /** + * Method hasShowColourText. + * + * @return true if at least one ShowColourText has been added + */ + public boolean hasShowColourText( + ) { + return this._has_showColourText; + } + + /** + * Method hasShowConsensusHistogram. + * + * @return true if at least one ShowConsensusHistogram has been + * added + */ + public boolean hasShowConsensusHistogram( + ) { + return this._has_showConsensusHistogram; + } + + /** + * Method hasShowDbRefTooltip. + * + * @return true if at least one ShowDbRefTooltip has been added + */ + public boolean hasShowDbRefTooltip( + ) { + return this._has_showDbRefTooltip; + } + + /** + * Method hasShowFullId. + * + * @return true if at least one ShowFullId has been added + */ + public boolean hasShowFullId( + ) { + return this._has_showFullId; + } + + /** + * Method hasShowGroupConsensus. + * + * @return true if at least one ShowGroupConsensus has been adde + */ + public boolean hasShowGroupConsensus( + ) { + return this._has_showGroupConsensus; + } + + /** + * Method hasShowGroupConservation. + * + * @return true if at least one ShowGroupConservation has been + * added + */ + public boolean hasShowGroupConservation( + ) { + return this._has_showGroupConservation; + } + + /** + * Method hasShowNPfeatureTooltip. + * + * @return true if at least one ShowNPfeatureTooltip has been + * added + */ + public boolean hasShowNPfeatureTooltip( + ) { + return this._has_showNPfeatureTooltip; + } + + /** + * Method hasShowSequenceFeatures. + * + * @return true if at least one ShowSequenceFeatures has been + * added + */ + public boolean hasShowSequenceFeatures( + ) { + return this._has_showSequenceFeatures; + } + + /** + * Method hasShowSequenceLogo. + * + * @return true if at least one ShowSequenceLogo has been added + */ + public boolean hasShowSequenceLogo( + ) { + return this._has_showSequenceLogo; + } + + /** + * Method hasShowText. + * + * @return true if at least one ShowText has been added + */ + public boolean hasShowText( + ) { + return this._has_showText; + } + + /** + * Method hasShowUnconserved. + * + * @return true if at least one ShowUnconserved has been added + */ + public boolean hasShowUnconserved( + ) { + return this._has_showUnconserved; + } + + /** + * Method hasStartRes. + * + * @return true if at least one StartRes has been added + */ + public boolean hasStartRes( + ) { + return this._has_startRes; + } + + /** + * Method hasStartSeq. + * + * @return true if at least one StartSeq has been added + */ + public boolean hasStartSeq( + ) { + return this._has_startSeq; + } + + /** + * Method hasTextCol1. + * + * @return true if at least one TextCol1 has been added + */ + public boolean hasTextCol1( + ) { + return this._has_textCol1; + } + + /** + * Method hasTextCol2. + * + * @return true if at least one TextCol2 has been added + */ + public boolean hasTextCol2( + ) { + return this._has_textCol2; + } + + /** + * Method hasTextColThreshold. + * + * @return true if at least one TextColThreshold has been added + */ + public boolean hasTextColThreshold( + ) { + return this._has_textColThreshold; + } + + /** + * Method hasWidth. + * + * @return true if at least one Width has been added + */ + public boolean hasWidth( + ) { + return this._has_width; + } + + /** + * Method hasWrapAlignment. + * + * @return true if at least one WrapAlignment has been added + */ + public boolean hasWrapAlignment( + ) { + return this._has_wrapAlignment; + } + + /** + * Method hasXpos. + * + * @return true if at least one Xpos has been added + */ + public boolean hasXpos( + ) { + return this._has_xpos; + } + + /** + * Method hasYpos. + * + * @return true if at least one Ypos has been added + */ + public boolean hasYpos( + ) { + return this._has_ypos; + } + + /** + * Returns the value of field 'centreColumnLabels'. + * + * @return the value of field 'CentreColumnLabels'. + */ + public boolean isCentreColumnLabels( + ) { + return this._centreColumnLabels; + } + + /** + * Returns the value of field 'conservationSelected'. + * + * @return the value of field 'ConservationSelected'. + */ + public boolean isConservationSelected( + ) { + return this._conservationSelected; + } + + /** + * Returns the value of field 'followHighlight'. + * + * @return the value of field 'FollowHighlight'. + */ + public boolean isFollowHighlight( + ) { + return this._followHighlight; + } + + /** + * Returns the value of field 'followSelection'. + * + * @return the value of field 'FollowSelection'. + */ + public boolean isFollowSelection( + ) { + return this._followSelection; + } + + /** + * Returns the value of field 'gatheredViews'. + * + * @return the value of field 'GatheredViews'. + */ + public boolean isGatheredViews( + ) { + return this._gatheredViews; + } + + /** + * Returns the value of field 'ignoreGapsinConsensus'. + * + * @return the value of field 'IgnoreGapsinConsensus'. + */ + public boolean isIgnoreGapsinConsensus( + ) { + return this._ignoreGapsinConsensus; + } + + /** + * Returns the value of field 'normaliseSequenceLogo'. + * + * @return the value of field 'NormaliseSequenceLogo'. + */ + public boolean isNormaliseSequenceLogo( + ) { + return this._normaliseSequenceLogo; + } + + /** + * Returns the value of field 'pidSelected'. + * + * @return the value of field 'PidSelected'. + */ + public boolean isPidSelected( + ) { + return this._pidSelected; + } + + /** + * Returns the value of field 'renderGaps'. + * + * @return the value of field 'RenderGaps'. + */ + public boolean isRenderGaps( + ) { + return this._renderGaps; + } + + /** + * Returns the value of field 'rightAlignIds'. + * + * @return the value of field 'RightAlignIds'. + */ + public boolean isRightAlignIds( + ) { + return this._rightAlignIds; + } + + /** + * Returns the value of field 'showAnnotation'. + * + * @return the value of field 'ShowAnnotation'. + */ + public boolean isShowAnnotation( + ) { + return this._showAnnotation; + } + + /** + * Returns the value of field 'showBoxes'. + * + * @return the value of field 'ShowBoxes'. + */ + public boolean isShowBoxes( + ) { + return this._showBoxes; + } + + /** + * Returns the value of field 'showColourText'. + * + * @return the value of field 'ShowColourText'. + */ + public boolean isShowColourText( + ) { + return this._showColourText; + } + + /** + * Returns the value of field 'showConsensusHistogram'. + * + * @return the value of field 'ShowConsensusHistogram'. + */ + public boolean isShowConsensusHistogram( + ) { + return this._showConsensusHistogram; + } + + /** + * Returns the value of field 'showDbRefTooltip'. + * + * @return the value of field 'ShowDbRefTooltip'. + */ + public boolean isShowDbRefTooltip( + ) { + return this._showDbRefTooltip; + } + + /** + * Returns the value of field 'showFullId'. + * + * @return the value of field 'ShowFullId'. + */ + public boolean isShowFullId( + ) { + return this._showFullId; + } + + /** + * Returns the value of field 'showGroupConsensus'. + * + * @return the value of field 'ShowGroupConsensus'. + */ + public boolean isShowGroupConsensus( + ) { + return this._showGroupConsensus; + } + + /** + * Returns the value of field 'showGroupConservation'. + * + * @return the value of field 'ShowGroupConservation'. + */ + public boolean isShowGroupConservation( + ) { + return this._showGroupConservation; + } + + /** + * Returns the value of field 'showNPfeatureTooltip'. + * + * @return the value of field 'ShowNPfeatureTooltip'. + */ + public boolean isShowNPfeatureTooltip( + ) { + return this._showNPfeatureTooltip; + } + + /** + * Returns the value of field 'showSequenceFeatures'. + * + * @return the value of field 'ShowSequenceFeatures'. + */ + public boolean isShowSequenceFeatures( + ) { + return this._showSequenceFeatures; + } + + /** + * Returns the value of field 'showSequenceLogo'. + * + * @return the value of field 'ShowSequenceLogo'. + */ + public boolean isShowSequenceLogo( + ) { + return this._showSequenceLogo; + } + + /** + * Returns the value of field 'showText'. + * + * @return the value of field 'ShowText'. + */ + public boolean isShowText( + ) { + return this._showText; + } + + /** + * Returns the value of field 'showUnconserved'. + * + * @return the value of field 'ShowUnconserved'. + */ + public boolean isShowUnconserved( + ) { + return this._showUnconserved; + } + + /** + * Method isValid. + * + * @return true if this object is valid according to the schema + */ + public boolean isValid( + ) { + try { + validate(); + } catch (org.exolab.castor.xml.ValidationException vex) { + return false; + } + return true; + } + + /** + * Returns the value of field 'wrapAlignment'. + * + * @return the value of field 'WrapAlignment'. + */ + public boolean isWrapAlignment( + ) { + return this._wrapAlignment; + } + + /** + * + * + * @param out + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + */ + public void marshal( + final java.io.Writer out) + throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + Marshaller.marshal(this, out); + } + + /** + * + * + * @param handler + * @throws java.io.IOException if an IOException occurs during + * marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + */ + public void marshal( + final org.xml.sax.ContentHandler handler) + throws java.io.IOException, org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + Marshaller.marshal(this, handler); + } + + /** + */ + public void removeAllCalcIdParam( + ) { + this._calcIdParamList.clear(); + } + + /** + */ + public void removeAllHiddenColumns( + ) { + this._hiddenColumnsList.clear(); + } + + /** + * Method removeCalcIdParam. + * + * @param vCalcIdParam + * @return true if the object was removed from the collection. + */ + public boolean removeCalcIdParam( + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) { + boolean removed = _calcIdParamList.remove(vCalcIdParam); + return removed; + } + + /** + * Method removeCalcIdParamAt. + * + * @param index + * @return the element removed from the collection + */ + public jalview.schemabinding.version2.CalcIdParam removeCalcIdParamAt( + final int index) { + java.lang.Object obj = this._calcIdParamList.remove(index); + return (jalview.schemabinding.version2.CalcIdParam) obj; + } + + /** + * Method removeHiddenColumns. + * + * @param vHiddenColumns + * @return true if the object was removed from the collection. + */ + public boolean removeHiddenColumns( + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) { + boolean removed = _hiddenColumnsList.remove(vHiddenColumns); + return removed; + } + + /** + * Method removeHiddenColumnsAt. + * + * @param index + * @return the element removed from the collection + */ + public jalview.schemabinding.version2.HiddenColumns removeHiddenColumnsAt( + final int index) { + java.lang.Object obj = this._hiddenColumnsList.remove(index); + return (jalview.schemabinding.version2.HiddenColumns) obj; + } + + /** + * Sets the value of field 'annotationColours'. + * + * @param annotationColours the value of field + * 'annotationColours'. + */ + public void setAnnotationColours( + final jalview.schemabinding.version2.AnnotationColours annotationColours) { + this._annotationColours = annotationColours; + } + + /** + * Sets the value of field 'bgColour'. + * + * @param bgColour the value of field 'bgColour'. + */ + public void setBgColour( + final java.lang.String bgColour) { + this._bgColour = bgColour; + } + + /** + * + * + * @param index + * @param vCalcIdParam + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void setCalcIdParam( + final int index, + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._calcIdParamList.size()) { + throw new IndexOutOfBoundsException("setCalcIdParam: Index value '" + index + "' not in range [0.." + (this._calcIdParamList.size() - 1) + "]"); + } + + this._calcIdParamList.set(index, vCalcIdParam); + } + + /** + * + * + * @param vCalcIdParamArray + */ + public void setCalcIdParam( + final jalview.schemabinding.version2.CalcIdParam[] vCalcIdParamArray) { + //-- copy array + _calcIdParamList.clear(); + + for (int i = 0; i < vCalcIdParamArray.length; i++) { + this._calcIdParamList.add(vCalcIdParamArray[i]); + } + } + + /** + * Sets the value of field 'centreColumnLabels'. + * + * @param centreColumnLabels the value of field + * 'centreColumnLabels'. + */ + public void setCentreColumnLabels( + final boolean centreColumnLabels) { + this._centreColumnLabels = centreColumnLabels; + this._has_centreColumnLabels = true; + } + + /** + * Sets the value of field 'complementId'. The field + * 'complementId' has the following description: The viewport + * id of this viewport's (cdna/protein) coding complement, if + * any + * + * + * @param complementId the value of field 'complementId'. + */ + public void setComplementId( + final java.lang.String complementId) { + this._complementId = complementId; + } + + /** + * Sets the value of field 'consThreshold'. + * + * @param consThreshold the value of field 'consThreshold'. + */ + public void setConsThreshold( + final int consThreshold) { + this._consThreshold = consThreshold; + this._has_consThreshold = true; + } + + /** + * Sets the value of field 'conservationSelected'. + * + * @param conservationSelected the value of field + * 'conservationSelected'. + */ + public void setConservationSelected( + final boolean conservationSelected) { + this._conservationSelected = conservationSelected; + this._has_conservationSelected = true; + } + + /** + * Sets the value of field 'followHighlight'. + * + * @param followHighlight the value of field 'followHighlight'. + */ + public void setFollowHighlight( + final boolean followHighlight) { + this._followHighlight = followHighlight; + this._has_followHighlight = true; + } + + /** + * Sets the value of field 'followSelection'. + * + * @param followSelection the value of field 'followSelection'. + */ + public void setFollowSelection( + final boolean followSelection) { + this._followSelection = followSelection; + this._has_followSelection = true; + } + + /** + * Sets the value of field 'fontName'. + * + * @param fontName the value of field 'fontName'. + */ + public void setFontName( + final java.lang.String fontName) { + this._fontName = fontName; + } + + /** + * Sets the value of field 'fontSize'. + * + * @param fontSize the value of field 'fontSize'. + */ + public void setFontSize( + final int fontSize) { + this._fontSize = fontSize; + this._has_fontSize = true; + } + + /** + * Sets the value of field 'fontStyle'. + * + * @param fontStyle the value of field 'fontStyle'. + */ + public void setFontStyle( + final int fontStyle) { + this._fontStyle = fontStyle; + this._has_fontStyle = true; + } + + /** + * Sets the value of field 'gatheredViews'. + * + * @param gatheredViews the value of field 'gatheredViews'. + */ + public void setGatheredViews( + final boolean gatheredViews) { + this._gatheredViews = gatheredViews; + this._has_gatheredViews = true; + } + + /** + * Sets the value of field 'height'. + * + * @param height the value of field 'height'. + */ + public void setHeight( + final int height) { + this._height = height; + this._has_height = true; + } + + /** + * + * + * @param index + * @param vHiddenColumns + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void setHiddenColumns( + final int index, + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._hiddenColumnsList.size()) { + throw new IndexOutOfBoundsException("setHiddenColumns: Index value '" + index + "' not in range [0.." + (this._hiddenColumnsList.size() - 1) + "]"); + } + + this._hiddenColumnsList.set(index, vHiddenColumns); + } + + /** + * + * + * @param vHiddenColumnsArray + */ + public void setHiddenColumns( + final jalview.schemabinding.version2.HiddenColumns[] vHiddenColumnsArray) { + //-- copy array + _hiddenColumnsList.clear(); + + for (int i = 0; i < vHiddenColumnsArray.length; i++) { + this._hiddenColumnsList.add(vHiddenColumnsArray[i]); + } + } + + /** + * Sets the value of field 'id'. The field 'id' has the + * following description: unique id used by jalview to + * synchronize between stored and + * instantiated views + * + * + * @param id the value of field 'id'. + */ + public void setId( + final java.lang.String id) { + this._id = id; + } + + /** + * Sets the value of field 'ignoreGapsinConsensus'. + * + * @param ignoreGapsinConsensus the value of field + * 'ignoreGapsinConsensus'. + */ + public void setIgnoreGapsinConsensus( + final boolean ignoreGapsinConsensus) { + this._ignoreGapsinConsensus = ignoreGapsinConsensus; + this._has_ignoreGapsinConsensus = true; + } + + /** + * Sets the value of field 'normaliseSequenceLogo'. + * + * @param normaliseSequenceLogo the value of field + * 'normaliseSequenceLogo'. + */ + public void setNormaliseSequenceLogo( + final boolean normaliseSequenceLogo) { + this._normaliseSequenceLogo = normaliseSequenceLogo; + this._has_normaliseSequenceLogo = true; + } + + /** + * Sets the value of field 'pidSelected'. + * + * @param pidSelected the value of field 'pidSelected'. + */ + public void setPidSelected( + final boolean pidSelected) { + this._pidSelected = pidSelected; + this._has_pidSelected = true; + } + + /** + * Sets the value of field 'pidThreshold'. + * + * @param pidThreshold the value of field 'pidThreshold'. + */ + public void setPidThreshold( + final int pidThreshold) { + this._pidThreshold = pidThreshold; + this._has_pidThreshold = true; + } + + /** + * Sets the value of field 'renderGaps'. + * + * @param renderGaps the value of field 'renderGaps'. + */ + public void setRenderGaps( + final boolean renderGaps) { + this._renderGaps = renderGaps; + this._has_renderGaps = true; + } + + /** + * Sets the value of field 'rightAlignIds'. + * + * @param rightAlignIds the value of field 'rightAlignIds'. + */ + public void setRightAlignIds( + final boolean rightAlignIds) { + this._rightAlignIds = rightAlignIds; + this._has_rightAlignIds = true; + } + + /** + * Sets the value of field 'sequenceSetId'. + * + * @param sequenceSetId the value of field 'sequenceSetId'. + */ + public void setSequenceSetId( + final java.lang.String sequenceSetId) { + this._sequenceSetId = sequenceSetId; + } + + /** + * Sets the value of field 'showAnnotation'. + * + * @param showAnnotation the value of field 'showAnnotation'. + */ + public void setShowAnnotation( + final boolean showAnnotation) { + this._showAnnotation = showAnnotation; + this._has_showAnnotation = true; + } + + /** + * Sets the value of field 'showBoxes'. + * + * @param showBoxes the value of field 'showBoxes'. + */ + public void setShowBoxes( + final boolean showBoxes) { + this._showBoxes = showBoxes; + this._has_showBoxes = true; + } + + /** + * Sets the value of field 'showColourText'. + * + * @param showColourText the value of field 'showColourText'. + */ + public void setShowColourText( + final boolean showColourText) { + this._showColourText = showColourText; + this._has_showColourText = true; + } + + /** + * Sets the value of field 'showConsensusHistogram'. + * + * @param showConsensusHistogram the value of field + * 'showConsensusHistogram'. + */ + public void setShowConsensusHistogram( + final boolean showConsensusHistogram) { + this._showConsensusHistogram = showConsensusHistogram; + this._has_showConsensusHistogram = true; + } + + /** + * Sets the value of field 'showDbRefTooltip'. + * + * @param showDbRefTooltip the value of field 'showDbRefTooltip' + */ + public void setShowDbRefTooltip( + final boolean showDbRefTooltip) { + this._showDbRefTooltip = showDbRefTooltip; + this._has_showDbRefTooltip = true; + } + + /** + * Sets the value of field 'showFullId'. + * + * @param showFullId the value of field 'showFullId'. + */ + public void setShowFullId( + final boolean showFullId) { + this._showFullId = showFullId; + this._has_showFullId = true; + } + + /** + * Sets the value of field 'showGroupConsensus'. + * + * @param showGroupConsensus the value of field + * 'showGroupConsensus'. + */ + public void setShowGroupConsensus( + final boolean showGroupConsensus) { + this._showGroupConsensus = showGroupConsensus; + this._has_showGroupConsensus = true; + } + + /** + * Sets the value of field 'showGroupConservation'. + * + * @param showGroupConservation the value of field + * 'showGroupConservation'. + */ + public void setShowGroupConservation( + final boolean showGroupConservation) { + this._showGroupConservation = showGroupConservation; + this._has_showGroupConservation = true; + } + + /** + * Sets the value of field 'showNPfeatureTooltip'. + * + * @param showNPfeatureTooltip the value of field + * 'showNPfeatureTooltip'. + */ + public void setShowNPfeatureTooltip( + final boolean showNPfeatureTooltip) { + this._showNPfeatureTooltip = showNPfeatureTooltip; + this._has_showNPfeatureTooltip = true; + } + + /** + * Sets the value of field 'showSequenceFeatures'. + * + * @param showSequenceFeatures the value of field + * 'showSequenceFeatures'. + */ + public void setShowSequenceFeatures( + final boolean showSequenceFeatures) { + this._showSequenceFeatures = showSequenceFeatures; + this._has_showSequenceFeatures = true; + } + + /** + * Sets the value of field 'showSequenceLogo'. + * + * @param showSequenceLogo the value of field 'showSequenceLogo' + */ + public void setShowSequenceLogo( + final boolean showSequenceLogo) { + this._showSequenceLogo = showSequenceLogo; + this._has_showSequenceLogo = true; + } + + /** + * Sets the value of field 'showText'. + * + * @param showText the value of field 'showText'. + */ + public void setShowText( + final boolean showText) { + this._showText = showText; + this._has_showText = true; + } + + /** + * Sets the value of field 'showUnconserved'. + * + * @param showUnconserved the value of field 'showUnconserved'. + */ + public void setShowUnconserved( + final boolean showUnconserved) { + this._showUnconserved = showUnconserved; + this._has_showUnconserved = true; + } + + /** + * Sets the value of field 'startRes'. + * + * @param startRes the value of field 'startRes'. + */ + public void setStartRes( + final int startRes) { + this._startRes = startRes; + this._has_startRes = true; + } + + /** + * Sets the value of field 'startSeq'. + * + * @param startSeq the value of field 'startSeq'. + */ + public void setStartSeq( + final int startSeq) { + this._startSeq = startSeq; + this._has_startSeq = true; + } + + /** + * Sets the value of field 'textCol1'. + * + * @param textCol1 the value of field 'textCol1'. + */ + public void setTextCol1( + final int textCol1) { + this._textCol1 = textCol1; + this._has_textCol1 = true; + } + + /** + * Sets the value of field 'textCol2'. + * + * @param textCol2 the value of field 'textCol2'. + */ + public void setTextCol2( + final int textCol2) { + this._textCol2 = textCol2; + this._has_textCol2 = true; + } + + /** + * Sets the value of field 'textColThreshold'. + * + * @param textColThreshold the value of field 'textColThreshold' + */ + public void setTextColThreshold( + final int textColThreshold) { + this._textColThreshold = textColThreshold; + this._has_textColThreshold = true; + } + + /** + * Sets the value of field 'title'. + * + * @param title the value of field 'title'. + */ + public void setTitle( + final java.lang.String title) { + this._title = title; + } + + /** + * Sets the value of field 'viewName'. + * + * @param viewName the value of field 'viewName'. + */ + public void setViewName( + final java.lang.String viewName) { + this._viewName = viewName; + } + + /** + * Sets the value of field 'width'. + * + * @param width the value of field 'width'. + */ + public void setWidth( + final int width) { + this._width = width; + this._has_width = true; + } + + /** + * Sets the value of field 'wrapAlignment'. + * + * @param wrapAlignment the value of field 'wrapAlignment'. + */ + public void setWrapAlignment( + final boolean wrapAlignment) { + this._wrapAlignment = wrapAlignment; + this._has_wrapAlignment = true; + } + + /** + * Sets the value of field 'xpos'. + * + * @param xpos the value of field 'xpos'. + */ + public void setXpos( + final int xpos) { + this._xpos = xpos; + this._has_xpos = true; + } + + /** + * Sets the value of field 'ypos'. + * + * @param ypos the value of field 'ypos'. + */ + public void setYpos( + final int ypos) { + this._ypos = ypos; + this._has_ypos = true; + } + + /** + * Method unmarshal. + * + * @param reader + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + * @return the unmarshaled + * jalview.schemabinding.version2.Viewport + */ + public static jalview.schemabinding.version2.Viewport unmarshal( + final java.io.Reader reader) + throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + return (jalview.schemabinding.version2.Viewport) Unmarshaller.unmarshal(jalview.schemabinding.version2.Viewport.class, reader); + } + + /** + * + * + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + */ + public void validate( + ) + throws org.exolab.castor.xml.ValidationException { + org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator(); + validator.validate(this); + } } diff --git a/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java b/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java index 3e3ee2d..5af9a23 100644 --- a/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java +++ b/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java @@ -20,8 +20,8 @@ */ package jalview.schemabinding.version2.descriptors; -//---------------------------------/ -//- Imported classes and packages -/ + //---------------------------------/ + //- Imported classes and packages -/ //---------------------------------/ import jalview.schemabinding.version2.Viewport; @@ -31,2600 +31,2061 @@ import jalview.schemabinding.version2.Viewport; * * @version $Revision$ $Date$ */ -public class ViewportDescriptor extends - org.exolab.castor.xml.util.XMLClassDescriptorImpl -{ - - // --------------------------/ - // - Class/Member Variables -/ - // --------------------------/ - - /** - * Field _elementDefinition. - */ - private boolean _elementDefinition; - - /** - * Field _nsPrefix. - */ - private java.lang.String _nsPrefix; - - /** - * Field _nsURI. - */ - private java.lang.String _nsURI; - - /** - * Field _xmlName. - */ - private java.lang.String _xmlName; - - // ----------------/ - // - Constructors -/ - // ----------------/ - - public ViewportDescriptor() - { - super(); - _nsURI = "www.jalview.org"; - _xmlName = "Viewport"; - _elementDefinition = true; - - // -- set grouping compositor - setCompositorAsSequence(); - org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null; - org.exolab.castor.mapping.FieldHandler handler = null; - org.exolab.castor.xml.FieldValidator fieldValidator = null; - // -- initialize attribute descriptors - - // -- _conservationSelected - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_conservationSelected", - "conservationSelected", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasConservationSelected()) - { - return null; - } - return (target.getConservationSelected() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteConservationSelected(); - return; - } - target.setConservationSelected(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _conservationSelected - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); +public class ViewportDescriptor extends org.exolab.castor.xml.util.XMLClassDescriptorImpl { + + + //--------------------------/ + //- Class/Member Variables -/ + //--------------------------/ + + /** + * Field _elementDefinition. + */ + private boolean _elementDefinition; + + /** + * Field _nsPrefix. + */ + private java.lang.String _nsPrefix; + + /** + * Field _nsURI. + */ + private java.lang.String _nsURI; + + /** + * Field _xmlName. + */ + private java.lang.String _xmlName; + + + //----------------/ + //- Constructors -/ + //----------------/ + + public ViewportDescriptor() { + super(); + _nsURI = "www.jalview.org"; + _xmlName = "Viewport"; + _elementDefinition = true; + + //-- set grouping compositor + setCompositorAsSequence(); + org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null; + org.exolab.castor.mapping.FieldHandler handler = null; + org.exolab.castor.xml.FieldValidator fieldValidator = null; + //-- initialize attribute descriptors + + //-- _conservationSelected + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_conservationSelected", "conservationSelected", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasConservationSelected()) { return null; } + return (target.getConservationSelected() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteConservationSelected(); + return; + } + target.setConservationSelected( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _conservationSelected + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _pidSelected + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_pidSelected", "pidSelected", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasPidSelected()) { return null; } + return (target.getPidSelected() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deletePidSelected(); + return; + } + target.setPidSelected( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _pidSelected + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _bgColour + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_bgColour", "bgColour", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getBgColour(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setBgColour( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _bgColour + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _consThreshold + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_consThreshold", "consThreshold", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasConsThreshold()) { return null; } + return new java.lang.Integer(target.getConsThreshold()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteConsThreshold(); + return; + } + target.setConsThreshold( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _consThreshold + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _pidThreshold + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_pidThreshold", "pidThreshold", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasPidThreshold()) { return null; } + return new java.lang.Integer(target.getPidThreshold()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deletePidThreshold(); + return; + } + target.setPidThreshold( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _pidThreshold + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _title + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_title", "title", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getTitle(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setTitle( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _title + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _showFullId + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showFullId", "showFullId", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowFullId()) { return null; } + return (target.getShowFullId() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowFullId(); + return; + } + target.setShowFullId( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showFullId + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _rightAlignIds + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_rightAlignIds", "rightAlignIds", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasRightAlignIds()) { return null; } + return (target.getRightAlignIds() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteRightAlignIds(); + return; + } + target.setRightAlignIds( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _rightAlignIds + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showText + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showText", "showText", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowText()) { return null; } + return (target.getShowText() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowText(); + return; + } + target.setShowText( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showText + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showColourText + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showColourText", "showColourText", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowColourText()) { return null; } + return (target.getShowColourText() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowColourText(); + return; + } + target.setShowColourText( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showColourText + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showUnconserved + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showUnconserved", "showUnconserved", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowUnconserved()) { return null; } + return (target.getShowUnconserved() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowUnconserved(); + return; + } + target.setShowUnconserved( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showUnconserved + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showBoxes + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showBoxes", "showBoxes", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowBoxes()) { return null; } + return (target.getShowBoxes() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowBoxes(); + return; + } + target.setShowBoxes( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showBoxes + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _wrapAlignment + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_wrapAlignment", "wrapAlignment", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasWrapAlignment()) { return null; } + return (target.getWrapAlignment() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteWrapAlignment(); + return; + } + target.setWrapAlignment( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _wrapAlignment + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _renderGaps + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_renderGaps", "renderGaps", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasRenderGaps()) { return null; } + return (target.getRenderGaps() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteRenderGaps(); + return; + } + target.setRenderGaps( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _renderGaps + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showSequenceFeatures + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showSequenceFeatures", "showSequenceFeatures", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowSequenceFeatures()) { return null; } + return (target.getShowSequenceFeatures() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowSequenceFeatures(); + return; + } + target.setShowSequenceFeatures( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showSequenceFeatures + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showNPfeatureTooltip + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showNPfeatureTooltip", "showNPfeatureTooltip", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowNPfeatureTooltip()) { return null; } + return (target.getShowNPfeatureTooltip() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowNPfeatureTooltip(); + return; + } + target.setShowNPfeatureTooltip( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showNPfeatureTooltip + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showDbRefTooltip + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showDbRefTooltip", "showDbRefTooltip", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowDbRefTooltip()) { return null; } + return (target.getShowDbRefTooltip() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowDbRefTooltip(); + return; + } + target.setShowDbRefTooltip( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showDbRefTooltip + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _followHighlight + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_followHighlight", "followHighlight", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFollowHighlight()) { return null; } + return (target.getFollowHighlight() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFollowHighlight(); + return; + } + target.setFollowHighlight( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _followHighlight + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _followSelection + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_followSelection", "followSelection", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFollowSelection()) { return null; } + return (target.getFollowSelection() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFollowSelection(); + return; + } + target.setFollowSelection( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _followSelection + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showAnnotation + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showAnnotation", "showAnnotation", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowAnnotation()) { return null; } + return (target.getShowAnnotation() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowAnnotation(); + return; + } + target.setShowAnnotation( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showAnnotation + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _centreColumnLabels + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_centreColumnLabels", "centreColumnLabels", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasCentreColumnLabels()) { return null; } + return (target.getCentreColumnLabels() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteCentreColumnLabels(); + return; + } + target.setCentreColumnLabels( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _centreColumnLabels + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showGroupConservation + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showGroupConservation", "showGroupConservation", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowGroupConservation()) { return null; } + return (target.getShowGroupConservation() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowGroupConservation(); + return; + } + target.setShowGroupConservation( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showGroupConservation + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showGroupConsensus + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showGroupConsensus", "showGroupConsensus", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowGroupConsensus()) { return null; } + return (target.getShowGroupConsensus() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowGroupConsensus(); + return; + } + target.setShowGroupConsensus( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showGroupConsensus + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showConsensusHistogram + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showConsensusHistogram", "showConsensusHistogram", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowConsensusHistogram()) { return null; } + return (target.getShowConsensusHistogram() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowConsensusHistogram(); + return; + } + target.setShowConsensusHistogram( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showConsensusHistogram + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showSequenceLogo + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showSequenceLogo", "showSequenceLogo", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowSequenceLogo()) { return null; } + return (target.getShowSequenceLogo() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowSequenceLogo(); + return; + } + target.setShowSequenceLogo( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showSequenceLogo + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _normaliseSequenceLogo + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_normaliseSequenceLogo", "normaliseSequenceLogo", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasNormaliseSequenceLogo()) { return null; } + return (target.getNormaliseSequenceLogo() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteNormaliseSequenceLogo(); + return; + } + target.setNormaliseSequenceLogo( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _normaliseSequenceLogo + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _ignoreGapsinConsensus + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_ignoreGapsinConsensus", "ignoreGapsinConsensus", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasIgnoreGapsinConsensus()) { return null; } + return (target.getIgnoreGapsinConsensus() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteIgnoreGapsinConsensus(); + return; + } + target.setIgnoreGapsinConsensus( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _ignoreGapsinConsensus + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _startRes + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_startRes", "startRes", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasStartRes()) { return null; } + return new java.lang.Integer(target.getStartRes()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteStartRes(); + return; + } + target.setStartRes( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _startRes + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _startSeq + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_startSeq", "startSeq", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasStartSeq()) { return null; } + return new java.lang.Integer(target.getStartSeq()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteStartSeq(); + return; + } + target.setStartSeq( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _startSeq + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _fontName + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_fontName", "fontName", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getFontName(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setFontName( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _fontName + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _fontSize + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_fontSize", "fontSize", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFontSize()) { return null; } + return new java.lang.Integer(target.getFontSize()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFontSize(); + return; + } + target.setFontSize( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _fontSize + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _fontStyle + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_fontStyle", "fontStyle", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFontStyle()) { return null; } + return new java.lang.Integer(target.getFontStyle()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFontStyle(); + return; + } + target.setFontStyle( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _fontStyle + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _viewName + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_viewName", "viewName", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getViewName(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setViewName( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _viewName + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _sequenceSetId + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_sequenceSetId", "sequenceSetId", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getSequenceSetId(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setSequenceSetId( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _sequenceSetId + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _gatheredViews + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_gatheredViews", "gatheredViews", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasGatheredViews()) { return null; } + return (target.getGatheredViews() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteGatheredViews(); + return; + } + target.setGatheredViews( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _gatheredViews + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _textCol1 + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_textCol1", "textCol1", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasTextCol1()) { return null; } + return new java.lang.Integer(target.getTextCol1()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteTextCol1(); + return; + } + target.setTextCol1( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _textCol1 + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _textCol2 + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_textCol2", "textCol2", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasTextCol2()) { return null; } + return new java.lang.Integer(target.getTextCol2()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteTextCol2(); + return; + } + target.setTextCol2( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _textCol2 + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _textColThreshold + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_textColThreshold", "textColThreshold", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasTextColThreshold()) { return null; } + return new java.lang.Integer(target.getTextColThreshold()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteTextColThreshold(); + return; + } + target.setTextColThreshold( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _textColThreshold + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _id + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_id", "id", org.exolab.castor.xml.NodeType.Attribute); + super.setIdentity(desc); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getId(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setId( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new java.lang.String(); + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _id + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IdValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IdValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _complementId + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_complementId", "complementId", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getComplementId(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setComplementId( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _complementId + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _width + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_width", "width", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasWidth()) { return null; } + return new java.lang.Integer(target.getWidth()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteWidth(); + return; + } + target.setWidth( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _width + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _height + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_height", "height", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasHeight()) { return null; } + return new java.lang.Integer(target.getHeight()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteHeight(); + return; + } + target.setHeight( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _height + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _xpos + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_xpos", "xpos", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasXpos()) { return null; } + return new java.lang.Integer(target.getXpos()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteXpos(); + return; + } + target.setXpos( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _xpos + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _ypos + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_ypos", "ypos", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasYpos()) { return null; } + return new java.lang.Integer(target.getYpos()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteYpos(); + return; + } + target.setYpos( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _ypos + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- initialize element descriptors + + //-- _annotationColours + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.AnnotationColours.class, "_annotationColours", "AnnotationColours", org.exolab.castor.xml.NodeType.Element); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getAnnotationColours(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setAnnotationColours( (jalview.schemabinding.version2.AnnotationColours) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new jalview.schemabinding.version2.AnnotationColours(); + } + }; + desc.setHandler(handler); + desc.setNameSpaceURI("www.jalview.org"); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _annotationColours + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + } + desc.setValidator(fieldValidator); + //-- _hiddenColumnsList + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.HiddenColumns.class, "_hiddenColumnsList", "hiddenColumns", org.exolab.castor.xml.NodeType.Element); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getHiddenColumns(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.addHiddenColumns( (jalview.schemabinding.version2.HiddenColumns) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public void resetValue(Object object) throws IllegalStateException, IllegalArgumentException { + try { + Viewport target = (Viewport) object; + target.removeAllHiddenColumns(); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new jalview.schemabinding.version2.HiddenColumns(); + } + }; + desc.setHandler(handler); + desc.setNameSpaceURI("www.jalview.org"); + desc.setMultivalued(true); + addFieldDescriptor(desc); + + //-- validation code for: _hiddenColumnsList + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + fieldValidator.setMinOccurs(0); + { //-- local scope + } + desc.setValidator(fieldValidator); + //-- _calcIdParamList + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.CalcIdParam.class, "_calcIdParamList", "calcIdParam", org.exolab.castor.xml.NodeType.Element); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getCalcIdParam(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.addCalcIdParam( (jalview.schemabinding.version2.CalcIdParam) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public void resetValue(Object object) throws IllegalStateException, IllegalArgumentException { + try { + Viewport target = (Viewport) object; + target.removeAllCalcIdParam(); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new jalview.schemabinding.version2.CalcIdParam(); + } + }; + desc.setHandler(handler); + desc.setNameSpaceURI("www.jalview.org"); + desc.setMultivalued(true); + addFieldDescriptor(desc); + + //-- validation code for: _calcIdParamList + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + fieldValidator.setMinOccurs(0); + { //-- local scope + } + desc.setValidator(fieldValidator); } - desc.setValidator(fieldValidator); - // -- _pidSelected - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_pidSelected", "pidSelected", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasPidSelected()) - { - return null; - } - return (target.getPidSelected() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deletePidSelected(); - return; - } - target.setPidSelected(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _pidSelected - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _bgColour - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_bgColour", "bgColour", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getBgColour(); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setBgColour((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } + //-----------/ + //- Methods -/ + //-----------/ - public java.lang.Object newInstance(java.lang.Object parent) - { + /** + * Method getAccessMode. + * + * @return the access mode specified for this class. + */ + public org.exolab.castor.mapping.AccessMode getAccessMode( + ) { return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _bgColour - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); } - desc.setValidator(fieldValidator); - // -- _consThreshold - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_consThreshold", "consThreshold", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasConsThreshold()) - { - return null; - } - return new java.lang.Integer(target.getConsThreshold()); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteConsThreshold(); - return; - } - target.setConsThreshold(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _consThreshold - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); + /** + * Method getIdentity. + * + * @return the identity field, null if this class has no + * identity. + */ + public org.exolab.castor.mapping.FieldDescriptor getIdentity( + ) { + return super.getIdentity(); } - desc.setValidator(fieldValidator); - // -- _pidThreshold - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_pidThreshold", "pidThreshold", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasPidThreshold()) - { - return null; - } - return new java.lang.Integer(target.getPidThreshold()); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deletePidThreshold(); - return; - } - target.setPidThreshold(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _pidThreshold - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); + /** + * Method getJavaClass. + * + * @return the Java class represented by this descriptor. + */ + public java.lang.Class getJavaClass( + ) { + return jalview.schemabinding.version2.Viewport.class; } - desc.setValidator(fieldValidator); - // -- _title - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_title", "title", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getTitle(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setTitle((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _title - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); + /** + * Method getNameSpacePrefix. + * + * @return the namespace prefix to use when marshaling as XML. + */ + public java.lang.String getNameSpacePrefix( + ) { + return _nsPrefix; } - desc.setValidator(fieldValidator); - // -- _showFullId - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showFullId", "showFullId", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowFullId()) - { - return null; - } - return (target.getShowFullId() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowFullId(); - return; - } - target.setShowFullId(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showFullId - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _rightAlignIds - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_rightAlignIds", "rightAlignIds", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasRightAlignIds()) - { - return null; - } - return (target.getRightAlignIds() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteRightAlignIds(); - return; - } - target.setRightAlignIds(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _rightAlignIds - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method getNameSpaceURI. + * + * @return the namespace URI used when marshaling and + * unmarshaling as XML. + */ + public java.lang.String getNameSpaceURI( + ) { + return _nsURI; } - desc.setValidator(fieldValidator); - // -- _showText - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showText", "showText", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowText()) - { - return null; - } - return (target.getShowText() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowText(); - return; - } - target.setShowText(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _showText - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method getValidator. + * + * @return a specific validator for the class described by this + * ClassDescriptor. + */ + public org.exolab.castor.xml.TypeValidator getValidator( + ) { + return this; } - desc.setValidator(fieldValidator); - // -- _showColourText - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showColourText", "showColourText", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowColourText()) - { - return null; - } - return (target.getShowColourText() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowColourText(); - return; - } - target.setShowColourText(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _showColourText - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method getXMLName. + * + * @return the XML Name for the Class being described. + */ + public java.lang.String getXMLName( + ) { + return _xmlName; } - desc.setValidator(fieldValidator); - // -- _showUnconserved - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showUnconserved", "showUnconserved", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowUnconserved()) - { - return null; - } - return (target.getShowUnconserved() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowUnconserved(); - return; - } - target.setShowUnconserved(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showUnconserved - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showBoxes - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showBoxes", "showBoxes", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowBoxes()) - { - return null; - } - return (target.getShowBoxes() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowBoxes(); - return; - } - target.setShowBoxes(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showBoxes - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _wrapAlignment - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_wrapAlignment", "wrapAlignment", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasWrapAlignment()) - { - return null; - } - return (target.getWrapAlignment() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteWrapAlignment(); - return; - } - target.setWrapAlignment(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _wrapAlignment - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method isElementDefinition. + * + * @return true if XML schema definition of this Class is that + * of a global + * element or element with anonymous type definition. + */ + public boolean isElementDefinition( + ) { + return _elementDefinition; } - desc.setValidator(fieldValidator); - // -- _renderGaps - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_renderGaps", "renderGaps", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasRenderGaps()) - { - return null; - } - return (target.getRenderGaps() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteRenderGaps(); - return; - } - target.setRenderGaps(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _renderGaps - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showSequenceFeatures - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showSequenceFeatures", - "showSequenceFeatures", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowSequenceFeatures()) - { - return null; - } - return (target.getShowSequenceFeatures() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowSequenceFeatures(); - return; - } - target.setShowSequenceFeatures(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showSequenceFeatures - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showNPfeatureTooltip - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showNPfeatureTooltip", - "showNPfeatureTooltip", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowNPfeatureTooltip()) - { - return null; - } - return (target.getShowNPfeatureTooltip() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowNPfeatureTooltip(); - return; - } - target.setShowNPfeatureTooltip(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showNPfeatureTooltip - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showDbRefTooltip - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showDbRefTooltip", - "showDbRefTooltip", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowDbRefTooltip()) - { - return null; - } - return (target.getShowDbRefTooltip() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowDbRefTooltip(); - return; - } - target.setShowDbRefTooltip(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showDbRefTooltip - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _followHighlight - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_followHighlight", "followHighlight", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFollowHighlight()) - { - return null; - } - return (target.getFollowHighlight() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFollowHighlight(); - return; - } - target.setFollowHighlight(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _followHighlight - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _followSelection - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_followSelection", "followSelection", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFollowSelection()) - { - return null; - } - return (target.getFollowSelection() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFollowSelection(); - return; - } - target.setFollowSelection(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _followSelection - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showAnnotation - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showAnnotation", "showAnnotation", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowAnnotation()) - { - return null; - } - return (target.getShowAnnotation() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowAnnotation(); - return; - } - target.setShowAnnotation(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showAnnotation - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _centreColumnLabels - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_centreColumnLabels", - "centreColumnLabels", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasCentreColumnLabels()) - { - return null; - } - return (target.getCentreColumnLabels() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteCentreColumnLabels(); - return; - } - target.setCentreColumnLabels(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _centreColumnLabels - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showGroupConservation - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showGroupConservation", - "showGroupConservation", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowGroupConservation()) - { - return null; - } - return (target.getShowGroupConservation() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowGroupConservation(); - return; - } - target.setShowGroupConservation(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showGroupConservation - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showGroupConsensus - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showGroupConsensus", - "showGroupConsensus", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowGroupConsensus()) - { - return null; - } - return (target.getShowGroupConsensus() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowGroupConsensus(); - return; - } - target.setShowGroupConsensus(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showGroupConsensus - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showConsensusHistogram - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showConsensusHistogram", - "showConsensusHistogram", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowConsensusHistogram()) - { - return null; - } - return (target.getShowConsensusHistogram() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowConsensusHistogram(); - return; - } - target.setShowConsensusHistogram(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showConsensusHistogram - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showSequenceLogo - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showSequenceLogo", - "showSequenceLogo", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowSequenceLogo()) - { - return null; - } - return (target.getShowSequenceLogo() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowSequenceLogo(); - return; - } - target.setShowSequenceLogo(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showSequenceLogo - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _normaliseSequenceLogo - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_normaliseSequenceLogo", - "normaliseSequenceLogo", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasNormaliseSequenceLogo()) - { - return null; - } - return (target.getNormaliseSequenceLogo() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteNormaliseSequenceLogo(); - return; - } - target.setNormaliseSequenceLogo(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _normaliseSequenceLogo - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _ignoreGapsinConsensus - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_ignoreGapsinConsensus", - "ignoreGapsinConsensus", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasIgnoreGapsinConsensus()) - { - return null; - } - return (target.getIgnoreGapsinConsensus() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteIgnoreGapsinConsensus(); - return; - } - target.setIgnoreGapsinConsensus(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _ignoreGapsinConsensus - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _startRes - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_startRes", "startRes", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasStartRes()) - { - return null; - } - return new java.lang.Integer(target.getStartRes()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteStartRes(); - return; - } - target.setStartRes(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _startRes - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _startSeq - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_startSeq", "startSeq", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasStartSeq()) - { - return null; - } - return new java.lang.Integer(target.getStartSeq()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteStartSeq(); - return; - } - target.setStartSeq(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _startSeq - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _fontName - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_fontName", "fontName", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getFontName(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setFontName((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _fontName - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); - } - desc.setValidator(fieldValidator); - // -- _fontSize - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_fontSize", "fontSize", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFontSize()) - { - return null; - } - return new java.lang.Integer(target.getFontSize()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFontSize(); - return; - } - target.setFontSize(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _fontSize - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _fontStyle - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_fontStyle", "fontStyle", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFontStyle()) - { - return null; - } - return new java.lang.Integer(target.getFontStyle()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFontStyle(); - return; - } - target.setFontStyle(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _fontStyle - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _viewName - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_viewName", "viewName", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getViewName(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setViewName((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _viewName - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); - } - desc.setValidator(fieldValidator); - // -- _sequenceSetId - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_sequenceSetId", "sequenceSetId", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getSequenceSetId(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setSequenceSetId((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _sequenceSetId - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); - } - desc.setValidator(fieldValidator); - // -- _gatheredViews - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_gatheredViews", "gatheredViews", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasGatheredViews()) - { - return null; - } - return (target.getGatheredViews() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteGatheredViews(); - return; - } - target.setGatheredViews(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _gatheredViews - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _textCol1 - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_textCol1", "textCol1", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasTextCol1()) - { - return null; - } - return new java.lang.Integer(target.getTextCol1()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteTextCol1(); - return; - } - target.setTextCol1(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _textCol1 - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _textCol2 - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_textCol2", "textCol2", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasTextCol2()) - { - return null; - } - return new java.lang.Integer(target.getTextCol2()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteTextCol2(); - return; - } - target.setTextCol2(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _textCol2 - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _textColThreshold - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_textColThreshold", - "textColThreshold", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasTextColThreshold()) - { - return null; - } - return new java.lang.Integer(target.getTextColThreshold()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteTextColThreshold(); - return; - } - target.setTextColThreshold(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _textColThreshold - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _id - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_id", "id", - org.exolab.castor.xml.NodeType.Attribute); - super.setIdentity(desc); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getId(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setId((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new java.lang.String(); - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _id - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IdValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IdValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _width - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_width", "width", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasWidth()) - { - return null; - } - return new java.lang.Integer(target.getWidth()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteWidth(); - return; - } - target.setWidth(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _width - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _height - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_height", "height", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasHeight()) - { - return null; - } - return new java.lang.Integer(target.getHeight()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteHeight(); - return; - } - target.setHeight(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _height - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _xpos - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_xpos", "xpos", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasXpos()) - { - return null; - } - return new java.lang.Integer(target.getXpos()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteXpos(); - return; - } - target.setXpos(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _xpos - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _ypos - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_ypos", "ypos", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasYpos()) - { - return null; - } - return new java.lang.Integer(target.getYpos()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteYpos(); - return; - } - target.setYpos(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _ypos - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- initialize element descriptors - - // -- _annotationColours - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - jalview.schemabinding.version2.AnnotationColours.class, - "_annotationColours", "AnnotationColours", - org.exolab.castor.xml.NodeType.Element); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getAnnotationColours(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setAnnotationColours((jalview.schemabinding.version2.AnnotationColours) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new jalview.schemabinding.version2.AnnotationColours(); - } - }; - desc.setHandler(handler); - desc.setNameSpaceURI("www.jalview.org"); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _annotationColours - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - } - desc.setValidator(fieldValidator); - // -- _hiddenColumnsList - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - jalview.schemabinding.version2.HiddenColumns.class, - "_hiddenColumnsList", "hiddenColumns", - org.exolab.castor.xml.NodeType.Element); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getHiddenColumns(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.addHiddenColumns((jalview.schemabinding.version2.HiddenColumns) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public void resetValue(Object object) throws IllegalStateException, - IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.removeAllHiddenColumns(); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new jalview.schemabinding.version2.HiddenColumns(); - } - }; - desc.setHandler(handler); - desc.setNameSpaceURI("www.jalview.org"); - desc.setMultivalued(true); - addFieldDescriptor(desc); - - // -- validation code for: _hiddenColumnsList - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - fieldValidator.setMinOccurs(0); - { // -- local scope - } - desc.setValidator(fieldValidator); - // -- _calcIdParamList - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - jalview.schemabinding.version2.CalcIdParam.class, - "_calcIdParamList", "calcIdParam", - org.exolab.castor.xml.NodeType.Element); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getCalcIdParam(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.addCalcIdParam((jalview.schemabinding.version2.CalcIdParam) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public void resetValue(Object object) throws IllegalStateException, - IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.removeAllCalcIdParam(); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new jalview.schemabinding.version2.CalcIdParam(); - } - }; - desc.setHandler(handler); - desc.setNameSpaceURI("www.jalview.org"); - desc.setMultivalued(true); - addFieldDescriptor(desc); - - // -- validation code for: _calcIdParamList - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - fieldValidator.setMinOccurs(0); - { // -- local scope - } - desc.setValidator(fieldValidator); - } - - // -----------/ - // - Methods -/ - // -----------/ - - /** - * Method getAccessMode. - * - * @return the access mode specified for this class. - */ - public org.exolab.castor.mapping.AccessMode getAccessMode() - { - return null; - } - - /** - * Method getIdentity. - * - * @return the identity field, null if this class has no identity. - */ - public org.exolab.castor.mapping.FieldDescriptor getIdentity() - { - return super.getIdentity(); - } - - /** - * Method getJavaClass. - * - * @return the Java class represented by this descriptor. - */ - public java.lang.Class getJavaClass() - { - return jalview.schemabinding.version2.Viewport.class; - } - - /** - * Method getNameSpacePrefix. - * - * @return the namespace prefix to use when marshaling as XML. - */ - public java.lang.String getNameSpacePrefix() - { - return _nsPrefix; - } - - /** - * Method getNameSpaceURI. - * - * @return the namespace URI used when marshaling and unmarshaling as XML. - */ - public java.lang.String getNameSpaceURI() - { - return _nsURI; - } - - /** - * Method getValidator. - * - * @return a specific validator for the class described by this - * ClassDescriptor. - */ - public org.exolab.castor.xml.TypeValidator getValidator() - { - return this; - } - - /** - * Method getXMLName. - * - * @return the XML Name for the Class being described. - */ - public java.lang.String getXMLName() - { - return _xmlName; - } - - /** - * Method isElementDefinition. - * - * @return true if XML schema definition of this Class is that of a global - * element or element with anonymous type definition. - */ - public boolean isElementDefinition() - { - return _elementDefinition; - } } diff --git a/src/jalview/schemes/ClustalxColourScheme.java b/src/jalview/schemes/ClustalxColourScheme.java index 92d2dd7..6bc5cb8 100755 --- a/src/jalview/schemes/ClustalxColourScheme.java +++ b/src/jalview/schemes/ClustalxColourScheme.java @@ -25,41 +25,47 @@ import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; import java.awt.Color; -import java.util.Hashtable; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Vector; -public class ClustalxColourScheme extends ResidueColourScheme // implements -// IParameterizable +public class ClustalxColourScheme extends ResidueColourScheme { - public static Hashtable colhash = new Hashtable(); + private static final int EIGHTY_FIVE = 85; - Hashtable[] cons; + private static final int FIFTY = 50; - int[][] cons2; + private static final int EIGHTY = 80; - ConsensusColour[] colours; + private static final int SIXTY = 60; - ConsensusColour[] ResidueColour; + /* + * Map from conventional colour names to Clustal version of the same + */ + private static Map colhash = new HashMap(); + + private int[][] cons2; + + private ConsensusColour[] colours; - int size; + private ConsensusColour[] residueColour; - Consensus[] conses = new Consensus[32]; + private int size; - Vector colourTable = new Vector(); + private Consensus[] conses = new Consensus[32]; private boolean includeGaps = true; + static { - colhash.put("RED", new Color((float) 0.9, (float) 0.2, (float) 0.1)); - colhash.put("BLUE", new Color((float) 0.5, (float) 0.7, (float) 0.9)); - colhash.put("GREEN", new Color((float) 0.1, (float) 0.8, (float) 0.1)); - colhash.put("ORANGE", new Color((float) 0.9, (float) 0.6, (float) 0.3)); - colhash.put("CYAN", new Color((float) 0.1, (float) 0.7, (float) 0.7)); - colhash.put("PINK", new Color((float) 0.9, (float) 0.5, (float) 0.5)); - colhash.put("MAGENTA", new Color((float) 0.8, (float) 0.3, (float) 0.8)); - colhash.put("YELLOW", new Color((float) 0.8, (float) 0.8, (float) 0.0)); + colhash.put(Color.RED, new Color(0.9f, 0.2f, 0.1f)); + colhash.put(Color.BLUE, new Color(0.5f, 0.7f, 0.9f)); + colhash.put(Color.GREEN, new Color(0.1f, 0.8f, 0.1f)); + colhash.put(Color.ORANGE, new Color(0.9f, 0.6f, 0.3f)); + colhash.put(Color.CYAN, new Color(0.1f, 0.7f, 0.7f)); + colhash.put(Color.PINK, new Color(0.9f, 0.5f, 0.5f)); + colhash.put(Color.MAGENTA, new Color(0.8f, 0.3f, 0.8f)); + colhash.put(Color.YELLOW, new Color(0.8f, 0.8f, 0.0f)); } public ClustalxColourScheme(AnnotatedCollectionI alignment, @@ -122,36 +128,36 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements public void makeColours() { - conses[0] = new Consensus("WLVIMAFCYHP", 60); - conses[1] = new Consensus("WLVIMAFCYHP", 80); - conses[2] = new Consensus("ED", 50); - conses[3] = new Consensus("KR", 60); - conses[4] = new Consensus("G", 50); - conses[5] = new Consensus("N", 50); - conses[6] = new Consensus("QE", 50); - conses[7] = new Consensus("P", 50); - conses[8] = new Consensus("TS", 50); - - conses[26] = new Consensus("A", 85); - conses[27] = new Consensus("C", 85); - conses[10] = new Consensus("E", 85); - conses[11] = new Consensus("F", 85); - conses[12] = new Consensus("G", 85); - conses[13] = new Consensus("H", 85); - conses[14] = new Consensus("I", 85); - conses[15] = new Consensus("L", 85); - conses[16] = new Consensus("M", 85); - conses[17] = new Consensus("N", 85); - conses[18] = new Consensus("P", 85); - conses[19] = new Consensus("Q", 85); - conses[20] = new Consensus("R", 85); - conses[21] = new Consensus("S", 85); - conses[22] = new Consensus("T", 85); - conses[23] = new Consensus("V", 85); - conses[24] = new Consensus("W", 85); - conses[25] = new Consensus("Y", 85); - conses[28] = new Consensus("K", 85); - conses[29] = new Consensus("D", 85); + conses[0] = new Consensus("WLVIMAFCYHP", SIXTY); + conses[1] = new Consensus("WLVIMAFCYHP", EIGHTY); + conses[2] = new Consensus("ED", FIFTY); + conses[3] = new Consensus("KR", SIXTY); + conses[4] = new Consensus("G", FIFTY); + conses[5] = new Consensus("N", FIFTY); + conses[6] = new Consensus("QE", FIFTY); + conses[7] = new Consensus("P", FIFTY); + conses[8] = new Consensus("TS", FIFTY); + + conses[26] = new Consensus("A", EIGHTY_FIVE); + conses[27] = new Consensus("C", EIGHTY_FIVE); + conses[10] = new Consensus("E", EIGHTY_FIVE); + conses[11] = new Consensus("F", EIGHTY_FIVE); + conses[12] = new Consensus("G", EIGHTY_FIVE); + conses[13] = new Consensus("H", EIGHTY_FIVE); + conses[14] = new Consensus("I", EIGHTY_FIVE); + conses[15] = new Consensus("L", EIGHTY_FIVE); + conses[16] = new Consensus("M", EIGHTY_FIVE); + conses[17] = new Consensus("N", EIGHTY_FIVE); + conses[18] = new Consensus("P", EIGHTY_FIVE); + conses[19] = new Consensus("Q", EIGHTY_FIVE); + conses[20] = new Consensus("R", EIGHTY_FIVE); + conses[21] = new Consensus("S", EIGHTY_FIVE); + conses[22] = new Consensus("T", EIGHTY_FIVE); + conses[23] = new Consensus("V", EIGHTY_FIVE); + conses[24] = new Consensus("W", EIGHTY_FIVE); + conses[25] = new Consensus("Y", EIGHTY_FIVE); + conses[28] = new Consensus("K", EIGHTY_FIVE); + conses[29] = new Consensus("D", EIGHTY_FIVE); conses[30] = new Consensus("G", 0); conses[31] = new Consensus("P", 0); @@ -161,15 +167,15 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements Consensus[] tmp8 = new Consensus[1]; tmp8[0] = conses[30]; // G - colours[7] = new ConsensusColour((Color) colhash.get("ORANGE"), tmp8); + colours[7] = new ConsensusColour(colhash.get(Color.ORANGE), tmp8); Consensus[] tmp9 = new Consensus[1]; tmp9[0] = conses[31]; // P - colours[8] = new ConsensusColour((Color) colhash.get("YELLOW"), tmp9); + colours[8] = new ConsensusColour(colhash.get(Color.YELLOW), tmp9); Consensus[] tmp10 = new Consensus[1]; tmp10[0] = conses[27]; // C - colours[9] = new ConsensusColour((Color) colhash.get("PINK"), tmp8); + colours[9] = new ConsensusColour(colhash.get(Color.PINK), tmp8); Consensus[] tmp1 = new Consensus[14]; tmp1[0] = conses[0]; // % @@ -186,9 +192,9 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp1[11] = conses[25]; // Y tmp1[12] = conses[18]; // P tmp1[13] = conses[19]; // p - colours[0] = new ConsensusColour((Color) colhash.get("BLUE"), tmp1); + colours[0] = new ConsensusColour(colhash.get(Color.BLUE), tmp1); - colours[10] = new ConsensusColour((Color) colhash.get("CYAN"), tmp1); + colours[10] = new ConsensusColour(colhash.get(Color.CYAN), tmp1); Consensus[] tmp2 = new Consensus[5]; tmp2[0] = conses[8]; // t @@ -196,14 +202,14 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp2[2] = conses[22]; // T tmp2[3] = conses[0]; // % tmp2[4] = conses[1]; // # - colours[1] = new ConsensusColour((Color) colhash.get("GREEN"), tmp2); + colours[1] = new ConsensusColour(colhash.get(Color.GREEN), tmp2); Consensus[] tmp3 = new Consensus[3]; tmp3[0] = conses[17]; // N tmp3[1] = conses[29]; // D tmp3[2] = conses[5]; // n - colours[2] = new ConsensusColour((Color) colhash.get("GREEN"), tmp3); + colours[2] = new ConsensusColour(colhash.get(Color.GREEN), tmp3); Consensus[] tmp4 = new Consensus[6]; tmp4[0] = conses[6]; // q = QE @@ -212,14 +218,14 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp4[3] = conses[3]; // + tmp4[4] = conses[28]; // K tmp4[5] = conses[20]; // R - colours[3] = new ConsensusColour((Color) colhash.get("GREEN"), tmp4); + colours[3] = new ConsensusColour(colhash.get(Color.GREEN), tmp4); Consensus[] tmp5 = new Consensus[4]; tmp5[0] = conses[3]; // + tmp5[1] = conses[28]; // K tmp5[2] = conses[20]; // R tmp5[3] = conses[19]; // Q - colours[4] = new ConsensusColour((Color) colhash.get("RED"), tmp5); + colours[4] = new ConsensusColour(colhash.get(Color.RED), tmp5); Consensus[] tmp6 = new Consensus[6]; tmp6[0] = conses[3]; // - @@ -228,7 +234,7 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp6[3] = conses[6]; // QE tmp6[4] = conses[19]; // Q tmp6[5] = conses[2]; // DE - colours[5] = new ConsensusColour((Color) colhash.get("MAGENTA"), tmp6); + colours[5] = new ConsensusColour(colhash.get(Color.MAGENTA), tmp6); Consensus[] tmp7 = new Consensus[5]; tmp7[0] = conses[3]; // - @@ -236,30 +242,30 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp7[2] = conses[10]; // E tmp7[3] = conses[17]; // N tmp7[4] = conses[2]; // DE - colours[6] = new ConsensusColour((Color) colhash.get("MAGENTA"), tmp7); + colours[6] = new ConsensusColour(colhash.get(Color.MAGENTA), tmp7); // Now attach the ConsensusColours to the residue letters - ResidueColour = new ConsensusColour[20]; - ResidueColour[0] = colours[0]; // A - ResidueColour[1] = colours[4]; // R - ResidueColour[2] = colours[2]; // N - ResidueColour[3] = colours[6]; // D - ResidueColour[4] = colours[0]; // C - ResidueColour[5] = colours[3]; // Q - ResidueColour[6] = colours[5]; // E - ResidueColour[7] = colours[7]; // G - ResidueColour[8] = colours[10]; // H - ResidueColour[9] = colours[0]; // I - ResidueColour[10] = colours[0]; // L - ResidueColour[11] = colours[4]; // K - ResidueColour[12] = colours[0]; // M - ResidueColour[13] = colours[0]; // F - ResidueColour[14] = colours[8]; // P - ResidueColour[15] = colours[1]; // S - ResidueColour[16] = colours[1]; // T - ResidueColour[17] = colours[0]; // W - ResidueColour[18] = colours[10]; // Y - ResidueColour[19] = colours[0]; // V + residueColour = new ConsensusColour[20]; + residueColour[0] = colours[0]; // A + residueColour[1] = colours[4]; // R + residueColour[2] = colours[2]; // N + residueColour[3] = colours[6]; // D + residueColour[4] = colours[0]; // C + residueColour[5] = colours[3]; // Q + residueColour[6] = colours[5]; // E + residueColour[7] = colours[7]; // G + residueColour[8] = colours[10]; // H + residueColour[9] = colours[0]; // I + residueColour[10] = colours[0]; // L + residueColour[11] = colours[4]; // K + residueColour[12] = colours[0]; // M + residueColour[13] = colours[0]; // F + residueColour[14] = colours[8]; // P + residueColour[15] = colours[1]; // S + residueColour[16] = colours[1]; // T + residueColour[17] = colours[0]; // W + residueColour[18] = colours[10]; // Y + residueColour[19] = colours[0]; // V } @Override @@ -288,12 +294,12 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements return currentColour; } - for (int k = 0; k < ResidueColour[i].conses.length; k++) + for (int k = 0; k < residueColour[i].conses.length; k++) { - if (ResidueColour[i].conses[k].isConserved(cons2, j, size, + if (residueColour[i].conses[k].isConserved(cons2, j, size, includeGaps)) { - currentColour = ResidueColour[i].c; + currentColour = residueColour[i].c; } } @@ -301,7 +307,7 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements { if (conses[27].isConserved(cons2, j, size, includeGaps)) { - currentColour = (Color) colhash.get("PINK"); + currentColour = colhash.get(Color.PINK); } } diff --git a/src/jalview/schemes/ResidueProperties.java b/src/jalview/schemes/ResidueProperties.java index d13f0a9..4bb246a 100755 --- a/src/jalview/schemes/ResidueProperties.java +++ b/src/jalview/schemes/ResidueProperties.java @@ -27,6 +27,7 @@ import jalview.api.analysis.ScoreModelI; import java.awt.Color; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -43,11 +44,11 @@ public class ResidueProperties public static final int[] purinepyrimidineIndex; - public static final Hashtable aa3Hash = new Hashtable(); + public static final Map aa3Hash = new HashMap(); - public static final Hashtable aa2Triplet = new Hashtable(); + public static final Map aa2Triplet = new HashMap(); - public static final Hashtable nucleotideName = new Hashtable(); + public static final Map nucleotideName = new HashMap(); static { @@ -676,6 +677,8 @@ public class ResidueProperties public static Vector STOP = new Vector(); + public static String START = "ATG"; + static { codonHash.put("K", Lys); @@ -1521,7 +1524,7 @@ public class ResidueProperties return hyd; } - public static Hashtable getAA3Hash() + public static Map getAA3Hash() { return aa3Hash; } diff --git a/src/jalview/structure/AtomSpec.java b/src/jalview/structure/AtomSpec.java new file mode 100644 index 0000000..d3e8d42 --- /dev/null +++ b/src/jalview/structure/AtomSpec.java @@ -0,0 +1,64 @@ +package jalview.structure; + +/** + * Java bean representing an atom in a PDB (or similar) structure model. + * + * @author gmcarstairs + * + */ +public class AtomSpec +{ + // TODO clarify do we want pdbFile here, or pdbId? + // compare highlightAtom in 2.8.2 for JalviewJmolBinding and + // javascript.MouseOverStructureListener + private String pdbFile; + + private String chain; + + private int pdbResNum; + + private int atomIndex; + + /** + * Constructor + * + * @param pdbFile + * @param chain + * @param resNo + * @param atomNo + */ + public AtomSpec(String pdbFile, String chain, int resNo, int atomNo) + { + this.pdbFile = pdbFile; + this.chain = chain; + this.pdbResNum = resNo; + this.atomIndex = atomNo; + } + + public String getPdbFile() + { + return pdbFile; + } + + public String getChain() + { + return chain; + } + + public int getPdbResNum() + { + return pdbResNum; + } + + public int getAtomIndex() + { + return atomIndex; + } + + @Override + public String toString() + { + return "pdbFile: " + pdbFile + ", chain: " + chain + ", res: " + + pdbResNum + ", atom: " + atomIndex; + } +} diff --git a/src/jalview/structure/CommandListener.java b/src/jalview/structure/CommandListener.java new file mode 100644 index 0000000..e5f3e36 --- /dev/null +++ b/src/jalview/structure/CommandListener.java @@ -0,0 +1,35 @@ +package jalview.structure; + +import jalview.commands.CommandI; + +/** + * Defines a listener for commands performed on another alignment. This is to + * support linked editing of two alternative representations of an alignment (in + * particular, cDNA and protein). + * + * @author gmcarstairs + * + */ +public interface CommandListener +{ + /** + * The listener may attempt to perform the specified command; the region acted + * on is determined by a callback to the StructureSelectionManager (which + * holds mappings between alignments). + * + * @param command + * @param undo + * @param ssm + * @param source + * the originator of the command + */ + public void mirrorCommand(CommandI command, boolean undo, + StructureSelectionManager ssm, VamsasSource source); + + /** + * Temporary workaround to make check for source == listener work. + * + * @return + */ + public VamsasSource getVamsasSource(); +} diff --git a/src/jalview/structure/SequenceListener.java b/src/jalview/structure/SequenceListener.java index 83a9fd0..1306f9f 100644 --- a/src/jalview/structure/SequenceListener.java +++ b/src/jalview/structure/SequenceListener.java @@ -20,13 +20,19 @@ */ package jalview.structure; -import jalview.datamodel.*; +import jalview.datamodel.SequenceI; + public interface SequenceListener { + // TODO remove this? never called on SequenceListener type public void mouseOverSequence(SequenceI sequence, int index, int pos); public void highlightSequence(jalview.datamodel.SearchResults results); + // TODO remove this? never called public void updateColours(SequenceI sequence, int index); + + public VamsasSource getVamsasSource(); + } diff --git a/src/jalview/structure/StructureListener.java b/src/jalview/structure/StructureListener.java index 8ac002b..032c40b 100644 --- a/src/jalview/structure/StructureListener.java +++ b/src/jalview/structure/StructureListener.java @@ -20,40 +20,27 @@ */ package jalview.structure; +import java.util.List; + public interface StructureListener { /** - * - * @return list of structure files (unique IDs/filenames) that this listener - * handles messages for, or null if generic listener (only used by - * removeListener method) + * Returns a list of structure files (unique IDs/filenames) that this listener + * handles messages for, or null if generic listener (only used by + * removeListener method) */ public String[] getPdbFile(); /** - * NOT A LISTENER METHOD! called by structure viewer when the given - * atom/structure has been moused over. Typically, implementors call - * StructureSelectionManager.mouseOverStructure - * - * @param atomIndex - * @param strInfo - */ - public void mouseOverStructure(int atomIndex, String strInfo); - - /** - * called by StructureSelectionManager to inform viewer to highlight given - * atomspec + * Called by StructureSelectionManager to inform viewer to highlight given + * atom positions * - * @param atomIndex - * @param pdbResNum - * @param chain - * @param pdbId + * @param atoms */ - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbId); + public void highlightAtoms(List atoms); /** - * called by StructureSelectionManager when the colours of a sequence + * Called by StructureSelectionManager when the colours of a sequence * associated with a structure have changed. * * @param source @@ -62,19 +49,7 @@ public interface StructureListener public void updateColours(Object source); /** - * called by Jalview to get the colour for the given atomspec - * - * @param atomIndex - * @param pdbResNum - * @param chain - * @param pdbId - * @return - */ - public java.awt.Color getColour(int atomIndex, int pdbResNum, - String chain, String pdbId); - - /** - * called by structureSelectionManager to instruct implementor to release any + * Called by structureSelectionManager to instruct implementor to release any * direct references it may hold to the given object (typically, these are * Jalview alignment panels). * diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index af00798..f564f63 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -22,19 +22,29 @@ package jalview.structure; import jalview.analysis.AlignSeq; import jalview.api.StructureSelectionManagerProvider; +import jalview.commands.CommandI; +import jalview.commands.EditCommand; +import jalview.commands.OrderCommand; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.PDBEntry; import jalview.datamodel.SearchResults; import jalview.datamodel.SequenceI; import jalview.io.AppletFormatAdapter; +import jalview.util.MappingUtils; import jalview.util.MessageManager; import java.io.PrintStream; +import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.IdentityHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.Vector; import MCview.Atom; @@ -44,10 +54,28 @@ public class StructureSelectionManager { static IdentityHashMap instances; - StructureMapping[] mappings; + private List mappings = new ArrayList(); - private boolean processSecondaryStructure = false, - secStructServices = false, addTempFacAnnot = false; + private boolean processSecondaryStructure = false; + + private boolean secStructServices = false; + + private boolean addTempFacAnnot = false; + + /* + * Set of any registered mappings between (dataset) sequences. + */ + Set seqmappings = new LinkedHashSet(); + + /* + * Reference counters for the above mappings. Remove mappings when ref count + * goes to zero. + */ + Map seqMappingRefCounts = new HashMap(); + + private List commandListeners = new ArrayList(); + + private List sel_listeners = new ArrayList(); /** * @return true if will try to use external services for processing secondary @@ -115,17 +143,18 @@ public class StructureSelectionManager */ public void reportMapping() { - if (mappings == null) + if (mappings.isEmpty()) { System.err.println("reportMapping: No PDB/Sequence mappings."); } else { - System.err.println("reportMapping: There are " + mappings.length + System.err.println("reportMapping: There are " + mappings.size() + " mappings."); - for (int m = 0; m < mappings.length; m++) + int i = 0; + for (StructureMapping sm : mappings) { - System.err.println("mapping " + m + " : " + mappings[m].pdbfile); + System.err.println("mapping " + i++ + " : " + sm.pdbfile); } } } @@ -246,16 +275,19 @@ public class StructureSelectionManager } } + /** + * Returns the file name for a mapped PDB id (or null if not mapped). + * + * @param pdbid + * @return + */ public String alreadyMappedToFile(String pdbid) { - if (mappings != null) + for (StructureMapping sm : mappings) { - for (int i = 0; i < mappings.length; i++) + if (sm.getPdbId().equals(pdbid)) { - if (mappings[i].getPdbId().equals(pdbid)) - { - return mappings[i].pdbfile; - } + return sm.pdbfile; } } return null; @@ -482,19 +514,7 @@ public class StructureSelectionManager mappingDetails.toString()); if (forStructureView) { - - if (mappings == null) - { - mappings = new StructureMapping[1]; - } - else - { - StructureMapping[] tmp = new StructureMapping[mappings.length + 1]; - System.arraycopy(mappings, 0, tmp, 0, mappings.length); - mappings = tmp; - } - - mappings[mappings.length - 1] = newMapping; + mappings.add(newMapping); } maxChain.transferResidueAnnotation(newMapping, sqmpping); } @@ -546,19 +566,18 @@ public class StructureSelectionManager } } - if (pdbs.size() > 0 && mappings != null) + if (pdbs.size() > 0) { - Vector tmp = new Vector(); - for (int i = 0; i < mappings.length; i++) + List tmp = new ArrayList(); + for (StructureMapping sm : mappings) { - if (!pdbs.contains(mappings[i].pdbfile)) + if (!pdbs.contains(sm.pdbfile)) { - tmp.addElement(mappings[i]); + tmp.add(sm); } } - mappings = new StructureMapping[tmp.size()]; - tmp.copyInto(mappings); + mappings = tmp; } } @@ -569,7 +588,6 @@ public class StructureSelectionManager // old or prematurely sent event return; } - boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null; SearchResults results = null; SequenceI lastseq = null; int lastipos = -1, indexpos; @@ -581,33 +599,21 @@ public class StructureSelectionManager { results = new SearchResults(); } - if (mappings != null) + for (StructureMapping sm : mappings) { - for (int j = 0; j < mappings.length; j++) + if (sm.pdbfile.equals(pdbfile) && sm.pdbchain.equals(chain)) { - if (mappings[j].pdbfile.equals(pdbfile) - && mappings[j].pdbchain.equals(chain)) + indexpos = sm.getSeqPos(pdbResNum); + if (lastipos != indexpos && lastseq != sm.sequence) { - indexpos = mappings[j].getSeqPos(pdbResNum); - if (lastipos != indexpos && lastseq != mappings[j].sequence) + results.addResult(sm.sequence, indexpos, indexpos); + lastipos = indexpos; + lastseq = sm.sequence; + // construct highlighted sequence list + for (AlignedCodonFrame acf : seqmappings) { - results.addResult(mappings[j].sequence, indexpos, indexpos); - lastipos = indexpos; - lastseq = mappings[j].sequence; - // construct highlighted sequence list - if (seqmappings != null) - { - - Enumeration e = seqmappings.elements(); - while (e.hasMoreElements()) - - { - ((AlignedCodonFrame) e.nextElement()).markMappedRegion( - mappings[j].sequence, indexpos, results); - } - } + acf.markMappedRegion(sm.sequence, indexpos, results); } - } } } @@ -626,13 +632,11 @@ public class StructureSelectionManager } } - Vector seqmappings = null; // should be a simpler list of mapped seuqence - /** * highlight regions associated with a position (indexpos) in seq * * @param seq - * the sequeence that the mouse over occured on + * the sequence that the mouse over occurred on * @param indexpos * the absolute position being mouseovered in seq (0 to seq.length()) * @param index @@ -642,93 +646,54 @@ public class StructureSelectionManager public void mouseOverSequence(SequenceI seq, int indexpos, int index, VamsasSource source) { - boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null; + boolean hasSequenceListeners = handlingVamsasMo + || !seqmappings.isEmpty(); SearchResults results = null; if (index == -1) { index = seq.findPosition(indexpos); } - StructureListener sl; - int atomNo = 0; for (int i = 0; i < listeners.size(); i++) { Object listener = listeners.elementAt(i); if (listener == source) { + // TODO listener (e.g. SeqPanel) is never == source (AlignViewport) + // Temporary fudge with SequenceListener.getVamsasSource() continue; } if (listener instanceof StructureListener) { - sl = (StructureListener) listener; - if (mappings == null) - { - continue; - } - for (int j = 0; j < mappings.length; j++) - { - if (mappings[j].sequence == seq - || mappings[j].sequence == seq.getDatasetSequence()) - { - atomNo = mappings[j].getAtomNum(index); - - if (atomNo > 0) - { - sl.highlightAtom(atomNo, mappings[j].getPDBResNum(index), - mappings[j].pdbchain, mappings[j].pdbfile); - } - } - } + highlightStructure((StructureListener) listener, seq, index); } else { - if (relaySeqMappings && hasSequenceListeners - && listener instanceof SequenceListener) + if (listener instanceof SequenceListener) { - // DEBUG - // System.err.println("relay Seq " + seq.getDisplayId(false) + " " + - // index); - - if (results == null) + final SequenceListener seqListener = (SequenceListener) listener; + if (hasSequenceListeners + && seqListener.getVamsasSource() != source) { - results = new SearchResults(); - if (index >= seq.getStart() && index <= seq.getEnd()) + if (relaySeqMappings) { - // construct highlighted sequence list - - if (seqmappings != null) + if (results == null) { - Enumeration e = seqmappings.elements(); - while (e.hasMoreElements()) - - { - ((AlignedCodonFrame) e.nextElement()).markMappedRegion( - seq, index, results); - } + results = MappingUtils.buildSearchResults(seq, index, + seqmappings); } - // hasSequenceListeners = results.getSize() > 0; if (handlingVamsasMo) { - // maybe have to resolve seq to a dataset seqeunce... - // add in additional direct sequence and/or dataset sequence - // highlighting results.addResult(seq, index, index); + } + seqListener.highlightSequence(results); } } - if (hasSequenceListeners) - { - ((SequenceListener) listener).highlightSequence(results); - } } else if (listener instanceof VamsasListener && !handlingVamsasMo) { - // DEBUG - // System.err.println("Vamsas from Seq " + seq.getDisplayId(false) + " - // " + - // index); - // pass the mouse over and absolute position onto the - // VamsasListener(s) - ((VamsasListener) listener).mouseOver(seq, indexpos, source); + ((VamsasListener) listener).mouseOverSequence(seq, indexpos, + source); } else if (listener instanceof SecondaryStructureListener) { @@ -740,6 +705,35 @@ public class StructureSelectionManager } /** + * Send suitable messages to a StructureListener to highlight atoms + * corresponding to the given sequence position. + * + * @param sl + * @param seq + * @param index + */ + protected void highlightStructure(StructureListener sl, SequenceI seq, + int index) + { + int atomNo; + List atoms = new ArrayList(); + for (StructureMapping sm : mappings) + { + if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence()) + { + atomNo = sm.getAtomNum(index); + + if (atomNo > 0) + { + atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm + .getPDBResNum(index), atomNo)); + } + } + } + sl.highlightAtoms(atoms); + } + + /** * true if a mouse over event from an external (ie Vamsas) source is being * handled */ @@ -825,119 +819,114 @@ public class StructureSelectionManager public StructureMapping[] getMapping(String pdbfile) { - Vector tmp = new Vector(); - if (mappings != null) - { - for (int i = 0; i < mappings.length; i++) + List tmp = new ArrayList(); + for (StructureMapping sm : mappings) { - if (mappings[i].pdbfile.equals(pdbfile)) + if (sm.pdbfile.equals(pdbfile)) { - tmp.addElement(mappings[i]); + tmp.add(sm); } - } } - StructureMapping[] ret = new StructureMapping[tmp.size()]; - for (int i = 0; i < tmp.size(); i++) - { - ret[i] = (StructureMapping) tmp.elementAt(i); - } - - return ret; + return tmp.toArray(new StructureMapping[tmp.size()]); } public String printMapping(String pdbfile) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < mappings.length; i++) + StringBuilder sb = new StringBuilder(64); + for (StructureMapping sm : mappings) { - if (mappings[i].pdbfile.equals(pdbfile)) + if (sm.pdbfile.equals(pdbfile)) { - sb.append(mappings[i].mappingDetails); + sb.append(sm.mappingDetails); } } return sb.toString(); } - private int[] seqmappingrefs = null; // refcount for seqmappings elements - - private synchronized void modifySeqMappingList(boolean add, - AlignedCodonFrame[] codonFrames) + /** + * Decrement the reference counter for each of the given mappings, and remove + * it entirely if its reference counter reduces to zero. + * + * @param set + */ + public void removeMappings(Set set) { - if (!add && (seqmappings == null || seqmappings.size() == 0)) - { - return; - } - if (seqmappings == null) + if (set != null) { - seqmappings = new Vector(); + for (AlignedCodonFrame acf : set) + { + removeMapping(acf); + } } - if (codonFrames != null && codonFrames.length > 0) + } + + /** + * Decrement the reference counter for the given mapping, and remove it + * entirely if its reference counter reduces to zero. + * + * @param acf + */ + public void removeMapping(AlignedCodonFrame acf) + { + if (acf != null && seqmappings.contains(acf)) { - for (int cf = 0; cf < codonFrames.length; cf++) + int count = seqMappingRefCounts.get(acf); + count--; + if (count > 0) { - if (seqmappings.contains(codonFrames[cf])) - { - if (add) - { - seqmappingrefs[seqmappings.indexOf(codonFrames[cf])]++; - } - else - { - if (--seqmappingrefs[seqmappings.indexOf(codonFrames[cf])] <= 0) - { - int pos = seqmappings.indexOf(codonFrames[cf]); - int[] nr = new int[seqmappingrefs.length - 1]; - if (pos > 0) - { - System.arraycopy(seqmappingrefs, 0, nr, 0, pos); - } - if (pos < seqmappingrefs.length - 1) - { - System.arraycopy(seqmappingrefs, pos + 1, nr, 0, - seqmappingrefs.length - pos - 2); - } - } - } - } - else - { - if (add) - { - seqmappings.addElement(codonFrames[cf]); - - int[] nsr = new int[(seqmappingrefs == null) ? 1 - : seqmappingrefs.length + 1]; - if (seqmappingrefs != null && seqmappingrefs.length > 0) - { - System.arraycopy(seqmappingrefs, 0, nsr, 0, - seqmappingrefs.length); - } - nsr[(seqmappingrefs == null) ? 0 : seqmappingrefs.length] = 1; - seqmappingrefs = nsr; - } - } + seqMappingRefCounts.put(acf, count); + } + else + { + seqmappings.remove(acf); + seqMappingRefCounts.remove(acf); } } } - public void removeMappings(AlignedCodonFrame[] codonFrames) + /** + * Add each of the given codonFrames to the stored set. If not aready present, + * increments its reference count instead. + * + * @param set + */ + public void addMappings(Set set) { - modifySeqMappingList(false, codonFrames); + if (set != null) + { + for (AlignedCodonFrame acf : set) + { + addMapping(acf); + } + } } - public void addMappings(AlignedCodonFrame[] codonFrames) + /** + * Add the given mapping to the stored set, or if already stored, increment + * its reference counter. + */ + public void addMapping(AlignedCodonFrame acf) { - modifySeqMappingList(true, codonFrames); + if (acf != null) + { + if (seqmappings.contains(acf)) + { + seqMappingRefCounts.put(acf, seqMappingRefCounts.get(acf) + 1); + } + else + { + seqmappings.add(acf); + seqMappingRefCounts.put(acf, 1); + } + } } - Vector sel_listeners = new Vector(); - public void addSelectionListener(SelectionListener selecter) { if (!sel_listeners.contains(selecter)) { - sel_listeners.addElement(selecter); + sel_listeners.add(selecter); } } @@ -945,7 +934,7 @@ public class StructureSelectionManager { if (sel_listeners.contains(toremove)) { - sel_listeners.removeElement(toremove); + sel_listeners.remove(toremove); } } @@ -953,18 +942,11 @@ public class StructureSelectionManager jalview.datamodel.SequenceGroup selection, jalview.datamodel.ColumnSelection colsel, SelectionSource source) { - if (sel_listeners != null && sel_listeners.size() > 0) + for (SelectionListener slis : sel_listeners) { - Enumeration listeners = sel_listeners.elements(); - while (listeners.hasMoreElements()) + if (slis != source) { - SelectionListener slis = ((SelectionListener) listeners - .nextElement()); - if (slis != source) - { - slis.selection(selection, colsel, source); - } - ; + slis.selection(selection, colsel, source); } } } @@ -992,32 +974,6 @@ public class StructureSelectionManager } } - public void finalize() throws Throwable - { - if (listeners != null) - { - listeners.clear(); - listeners = null; - } - if (pdbIdFileName != null) - { - pdbIdFileName.clear(); - pdbIdFileName = null; - } - if (sel_listeners != null) - { - sel_listeners.clear(); - sel_listeners = null; - } - if (view_listeners != null) - { - view_listeners.clear(); - view_listeners = null; - } - mappings = null; - seqmappingrefs = null; - } - /** * release all references associated with this manager provider * @@ -1041,7 +997,6 @@ public class StructureSelectionManager } catch (Throwable x) { } - ; } } } @@ -1055,4 +1010,67 @@ public class StructureSelectionManager } } + public void addCommandListener(CommandListener cl) + { + if (!commandListeners.contains(cl)) + { + commandListeners.add(cl); + } + } + + public boolean hasCommandListener(CommandListener cl) + { + return this.commandListeners.contains(cl); + } + + public boolean removeCommandListener(CommandListener l) + { + return commandListeners.remove(l); + } + + /** + * Forward a command to any command listeners (except for the command's + * source). + * + * @param command + * the command to be broadcast (in its form after being performed) + * @param undo + * if true, the command was being 'undone' + * @param source + */ + public void commandPerformed(CommandI command, boolean undo, + VamsasSource source) + { + for (CommandListener listener : commandListeners) + { + listener.mirrorCommand(command, undo, this, source); + } + } + + /** + * Returns a new CommandI representing the given command as mapped to the + * given sequences. If no mapping could be made, or the command is not of a + * mappable kind, returns null. + * + * @param command + * @param undo + * @param mapTo + * @param gapChar + * @return + */ + public CommandI mapCommand(CommandI command, boolean undo, + final AlignmentI mapTo, char gapChar) + { + if (command instanceof EditCommand) + { + return MappingUtils.mapEditCommand((EditCommand) command, undo, + mapTo, gapChar, seqmappings); + } + else if (command instanceof OrderCommand) + { + return MappingUtils.mapOrderCommand((OrderCommand) command, undo, + mapTo, seqmappings); + } + return null; + } } diff --git a/src/jalview/structure/VamsasListener.java b/src/jalview/structure/VamsasListener.java index 26ebdc1..1c49252 100644 --- a/src/jalview/structure/VamsasListener.java +++ b/src/jalview/structure/VamsasListener.java @@ -36,5 +36,6 @@ import jalview.datamodel.SequenceI; */ public interface VamsasListener { - public void mouseOver(SequenceI seq, int index, VamsasSource source); + public void mouseOverSequence(SequenceI seq, int index, + VamsasSource source); } diff --git a/src/jalview/structures/models/AAStructureBindingModel.java b/src/jalview/structures/models/AAStructureBindingModel.java index 664c903..653ec2d 100644 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@ -3,15 +3,16 @@ package jalview.structures.models; import jalview.api.StructureSelectionManagerProvider; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; +import jalview.structure.AtomSpec; import jalview.structure.StructureListener; import jalview.structure.StructureSelectionManager; import jalview.util.MessageManager; -import java.awt.event.ComponentEvent; import java.util.ArrayList; import java.util.List; /** + * * A base class to hold common function for protein structure model binding. * Initial version created by refactoring JMol and Chimera binding models, but * other structure viewers could in principle be accommodated in future. @@ -361,4 +362,21 @@ public abstract class AAStructureBindingModel extends } } + @Override + public void highlightAtoms(List atoms) + { + if (atoms != null) + { + for (AtomSpec atom : atoms) + { + highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(), + atom.getChain(), atom.getPdbFile()); + } + } + } + + // TODO Jmol and Chimera seem to expect pdbFile, javascript listener pdbId + protected abstract void highlightAtom(int atomIndex, int pdbResNum, + String chain, String pdbFile); + } \ No newline at end of file diff --git a/src/jalview/util/Comparison.java b/src/jalview/util/Comparison.java index 8931b23..b9a95be 100644 --- a/src/jalview/util/Comparison.java +++ b/src/jalview/util/Comparison.java @@ -20,18 +20,25 @@ */ package jalview.util; -import jalview.datamodel.*; +import jalview.datamodel.SequenceI; /** - * DOCUMENT ME! - * - * @author $author$ - * @version $Revision$ + * Assorted methods for analysing or comparing sequences. */ public class Comparison { - /** DOCUMENT ME!! */ - public static final String GapChars = " .-"; + private static final int EIGHTY_FIVE = 85; + + private static final int TO_UPPER_CASE = 'a' - 'A'; + + private static final char GAP_SPACE = ' '; + + private static final char GAP_DOT = '.'; + + private static final char GAP_DASH = '-'; + + public static final String GapChars = new String(new char[] + { GAP_SPACE, GAP_DOT, GAP_DASH }); /** * DOCUMENT ME! @@ -69,12 +76,12 @@ public class Comparison int ilen = si.length() - 1; int jlen = sj.length() - 1; - while (jalview.util.Comparison.isGap(si.charAt(start + ilen))) + while (Comparison.isGap(si.charAt(start + ilen))) { ilen--; } - while (jalview.util.Comparison.isGap(sj.charAt(start + jlen))) + while (Comparison.isGap(sj.charAt(start + jlen))) { jlen--; } @@ -225,47 +232,60 @@ public class Comparison } /** - * DOCUMENT ME! + * Answers true if the supplied character is a recognised gap character, else + * false. Currently hard-coded to recognise '-', '-' or ' ' (hyphen / dot / + * space). * * @param c - * DOCUMENT ME! * - * @return DOCUMENT ME! + * @return */ public static final boolean isGap(char c) { - return (c == '-' || c == '.' || c == ' ') ? true : false; + return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false; } + /** + * Answers true if more than 85% of the sequence residues (ignoring gaps) are + * A, G, C, T or U, else false. This is just a heuristic guess and may give a + * wrong answer (as AGCT are also animo acid codes). + * + * @param seqs + * @return + */ public static final boolean isNucleotide(SequenceI[] seqs) { - int i = 0, iSize = seqs.length, j, jSize; - float nt = 0, aa = 0; - char c; - while (i < iSize) + if (seqs == null) + { + return false; + } + int ntCount = 0; + int aaCount = 0; + for (SequenceI seq : seqs) { - jSize = seqs[i].getLength(); - for (j = 0; j < jSize; j++) + for (char c : seq.getSequence()) { - c = seqs[i].getCharAt(j); if ('a' <= c && c <= 'z') { - c -= ('a' - 'A'); + c -= TO_UPPER_CASE; } if (c == 'A' || c == 'G' || c == 'C' || c == 'T' || c == 'U') { - nt++; + ntCount++; } - else if (!jalview.util.Comparison.isGap(seqs[i].getCharAt(j))) + else if (!Comparison.isGap(c)) { - aa++; + aaCount++; } } - i++; } - if ((nt / (nt + aa)) > 0.85f) + /* + * Check for nucleotide count > 85% of total count (in a form that evades + * int / float conversion or divide by zero). + */ + if (ntCount * 100 > EIGHTY_FIVE * (ntCount + aaCount)) { return true; } diff --git a/src/jalview/util/MapList.java b/src/jalview/util/MapList.java index eb414b9..48aebbf 100644 --- a/src/jalview/util/MapList.java +++ b/src/jalview/util/MapList.java @@ -20,86 +20,119 @@ */ package jalview.util; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** - * MapList Simple way of bijectively mapping a non-contiguous linear range to - * another non-contiguous linear range Use at your own risk! TODO: efficient - * implementation of private posMap method TODO: test/ensure that sense of from - * and to ratio start position is conserved (codon start position recovery) - * TODO: optimize to use int[][] arrays rather than vectors. + * A simple way of bijectively mapping a non-contiguous linear range to another + * non-contiguous linear range. + * + * Use at your own risk! + * + * TODO: efficient implementation of private posMap method + * + * TODO: test/ensure that sense of from and to ratio start position is conserved + * (codon start position recovery) */ public class MapList { + /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) + * Subregions (base 1) described as { [start1, end1], [start2, end2], ...} + */ + private List fromShifts = new ArrayList(); + + /* + * Same format as fromShifts, for the 'mapped to' sequence + */ + private List toShifts = new ArrayList(); + + /* + * number of steps in fromShifts to one toRatio unit + */ + private int fromRatio; + + /* + * number of steps in toShifts to one fromRatio + */ + private int toRatio; + + /* + * lowest and highest value in the from Map + */ + private int fromLowest; + + private int fromHighest; + + /* + * lowest and highest value in the to Map + */ + private int toLowest; + + private int toHighest; + + /** + * Two MapList objects are equal if they are the same object, or they both + * have populated shift ranges and all values are the same. */ - public boolean equals(MapList obj) + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof MapList)) + { + return false; + } + + MapList obj = (MapList) o; if (obj == this) - return true; - if (obj != null && obj.fromRatio == fromRatio && obj.toRatio == toRatio - && obj.fromShifts != null && obj.toShifts != null) { - int i, iSize = fromShifts.size(), j, jSize = obj.fromShifts.size(); - if (iSize != jSize) - return false; - for (i = 0, iSize = fromShifts.size(), j = 0, jSize = obj.fromShifts - .size(); i < iSize;) - { - int[] mi = (int[]) fromShifts.elementAt(i++); - int[] mj = (int[]) obj.fromShifts.elementAt(j++); - if (mi[0] != mj[0] || mi[1] != mj[1]) - return false; - } - iSize = toShifts.size(); - jSize = obj.toShifts.size(); - if (iSize != jSize) - return false; - for (i = 0, j = 0; i < iSize;) - { - int[] mi = (int[]) toShifts.elementAt(i++); - int[] mj = (int[]) obj.toShifts.elementAt(j++); - if (mi[0] != mj[0] || mi[1] != mj[1]) - return false; - } return true; } - return false; + if (obj.fromRatio != fromRatio || obj.toRatio != toRatio + || obj.fromShifts == null || obj.toShifts == null) + { + return false; + } + return Arrays + .deepEquals(fromShifts.toArray(), obj.fromShifts.toArray()) + && Arrays + .deepEquals(toShifts.toArray(), obj.toShifts.toArray()); } - public Vector fromShifts; - - public Vector toShifts; - - int fromRatio; // number of steps in fromShifts to one toRatio unit - - int toRatio; // number of steps in toShifts to one fromRatio - /** + * Returns the 'from' ranges as {[start1, end1], [start2, end2], ...} * - * @return series of intervals mapped in from + * @return */ - public int[] getFromRanges() + public List getFromRanges() { - return getRanges(fromShifts); + return fromShifts; } - public int[] getToRanges() + /** + * Returns the 'to' ranges as {[start1, end1], [start2, end2], ...} + * + * @return + */ + public List getToRanges() { - return getRanges(toShifts); + return toShifts; } - private int[] getRanges(Vector shifts) + /** + * Flattens a list of [start, end] into a single [start1, end1, start2, + * end2,...] array. + * + * @param shifts + * @return + */ + protected static int[] getRanges(List shifts) { int[] rnges = new int[2 * shifts.size()]; - Enumeration e = shifts.elements(); int i = 0; - while (e.hasMoreElements()) + for (int[] r : shifts) { - int r[] = (int[]) e.nextElement(); rnges[i++] = r[0]; rnges[i++] = r[1]; } @@ -107,16 +140,6 @@ public class MapList } /** - * lowest and highest value in the from Map - */ - int[] fromRange = null; - - /** - * lowest and highest value in the to Map - */ - int[] toRange = null; - - /** * * @return length of mapped phrase in from */ @@ -136,100 +159,136 @@ public class MapList public int getFromLowest() { - return fromRange[0]; + return fromLowest; } public int getFromHighest() { - return fromRange[1]; + return fromHighest; } public int getToLowest() { - return toRange[0]; + return toLowest; } public int getToHighest() { - return toRange[1]; - } - - private void ensureRange(int[] limits, int pos) - { - if (limits[0] > pos) - limits[0] = pos; - if (limits[1] < pos) - limits[1] = pos; + return toHighest; } + /** + * Constructor. + * + * @param from + * contiguous regions as [start1, end1, start2, end2, ...] + * @param to + * same format as 'from' + * @param fromRatio + * phrase length in 'from' (e.g. 3 for dna) + * @param toRatio + * phrase length in 'to' (e.g. 1 for protein) + */ public MapList(int from[], int to[], int fromRatio, int toRatio) { - fromRange = new int[] - { from[0], from[1] }; - toRange = new int[] - { to[0], to[1] }; - - fromShifts = new Vector(); + this.fromRatio = fromRatio; + this.toRatio = toRatio; + fromLowest = from[0]; + fromHighest = from[1]; for (int i = 0; i < from.length; i += 2) { - ensureRange(fromRange, from[i]); - ensureRange(fromRange, from[i + 1]); + fromLowest = Math.min(fromLowest, from[i]); + fromHighest = Math.max(fromHighest, from[i + 1]); - fromShifts.addElement(new int[] + fromShifts.add(new int[] { from[i], from[i + 1] }); } - toShifts = new Vector(); + + toLowest = to[0]; + toHighest = to[1]; for (int i = 0; i < to.length; i += 2) { - ensureRange(toRange, to[i]); - ensureRange(toRange, to[i + 1]); - toShifts.addElement(new int[] + toLowest = Math.min(toLowest, to[i]); + toHighest = Math.max(toHighest, to[i + 1]); + toShifts.add(new int[] { to[i], to[i + 1] }); } - this.fromRatio = fromRatio; - this.toRatio = toRatio; } + /** + * Copy constructor. Creates an identical mapping. + * + * @param map + */ public MapList(MapList map) { - this.fromRange = new int[] - { map.fromRange[0], map.fromRange[1] }; - this.toRange = new int[] - { map.toRange[0], map.toRange[1] }; + // TODO not used - remove? + this.fromLowest = map.fromLowest; + this.fromHighest = map.fromHighest; + this.toLowest = map.toLowest; + this.toHighest = map.toHighest; + this.fromRatio = map.fromRatio; this.toRatio = map.toRatio; if (map.fromShifts != null) { - this.fromShifts = new Vector(); - Enumeration e = map.fromShifts.elements(); - while (e.hasMoreElements()) + for (int[] r : map.fromShifts) { - int[] el = (int[]) e.nextElement(); - fromShifts.addElement(new int[] - { el[0], el[1] }); + fromShifts.add(new int[] + { r[0], r[1] }); } } if (map.toShifts != null) { - this.toShifts = new Vector(); - Enumeration e = map.toShifts.elements(); - while (e.hasMoreElements()) + for (int[] r : map.toShifts) { - int[] el = (int[]) e.nextElement(); - toShifts.addElement(new int[] - { el[0], el[1] }); + toShifts.add(new int[] + { r[0], r[1] }); } } } /** + * Constructor given ranges as lists of [start, end] positions + * + * @param fromRange + * @param toRange + * @param fromRatio + * @param toRatio + */ + public MapList(List fromRange, List toRange, + int fromRatio, int toRatio) + { + this.fromShifts = fromRange; + this.toShifts = toRange; + this.fromRatio = fromRatio; + this.toRatio = toRatio; + + fromLowest = Integer.MAX_VALUE; + fromHighest = 0; + for (int[] range : fromRange) { + fromLowest = Math.min(fromLowest, range[0]); + fromHighest = Math.max(fromHighest, range[1]); + } + + toLowest = Integer.MAX_VALUE; + toHighest = 0; + for (int[] range : toRange) + { + toLowest = Math.min(toLowest, range[0]); + toHighest = Math.max(toHighest, range[1]); + } + } + + /** * get all mapped positions from 'from' to 'to' * * @return int[][] { int[] { fromStart, fromFinish, toStart, toFinish }, int * [fromFinish-fromStart+2] { toStart..toFinish mappings}} */ - public int[][] makeFromMap() + protected int[][] makeFromMap() { + // TODO not used - remove?? return posMap(fromShifts, fromRatio, toShifts, toRatio); } @@ -238,27 +297,30 @@ public class MapList * * @return int[to position]=position mapped in from */ - public int[][] makeToMap() + protected int[][] makeToMap() { + // TODO not used - remove?? return posMap(toShifts, toRatio, fromShifts, fromRatio); } /** * construct an int map for intervals in intVals * - * @param intVals + * @param shiftTo * @return int[] { from, to pos in range }, int[range.to-range.from+1] * returning mapped position */ - private int[][] posMap(Vector intVals, int ratio, Vector toIntVals, + private int[][] posMap(List shiftTo, int ratio, + List shiftFrom, int toRatio) { - int iv = 0, ivSize = intVals.size(); + // TODO not used - remove?? + int iv = 0, ivSize = shiftTo.size(); if (iv >= ivSize) { return null; } - int[] intv = (int[]) intVals.elementAt(iv++); + int[] intv = shiftTo.get(iv++); int from = intv[0], to = intv[1]; if (from > to) { @@ -267,7 +329,7 @@ public class MapList } while (iv < ivSize) { - intv = (int[]) intVals.elementAt(iv++); + intv = shiftTo.get(iv++); if (intv[0] < from) { from = intv[0]; @@ -289,7 +351,7 @@ public class MapList int mp[][] = new int[to - from + 2][]; for (int i = 0; i < mp.length; i++) { - int[] m = shift(i + from, intVals, ratio, toIntVals, toRatio); + int[] m = shift(i + from, shiftTo, ratio, shiftFrom, toRatio); if (m != null) { if (i == 0) @@ -345,6 +407,7 @@ public class MapList * shifts.insertElementAt(new int[] { pos, shift}, sidx); else * rshift[1]+=shift; } */ + /** * shift from pos to To(pos) * @@ -373,23 +436,24 @@ public class MapList /** * - * @param fromShifts + * @param shiftTo * @param fromRatio - * @param toShifts + * @param shiftFrom * @param toRatio * @return */ - private int[] shift(int pos, Vector fromShifts, int fromRatio, - Vector toShifts, int toRatio) + protected static int[] shift(int pos, List shiftTo, int fromRatio, + List shiftFrom, int toRatio) { - int[] fromCount = countPos(fromShifts, pos); + // TODO: javadoc; tests + int[] fromCount = countPos(shiftTo, pos); if (fromCount == null) { return null; } int fromRemainder = (fromCount[0] - 1) % fromRatio; int toCount = 1 + (((fromCount[0] - 1) / fromRatio) * toRatio); - int[] toPos = countToPos(toShifts, toCount); + int[] toPos = countToPos(shiftFrom, toCount); if (toPos == null) { return null; // throw new Error("Bad Mapping!"); @@ -402,16 +466,16 @@ public class MapList /** * count how many positions pos is along the series of intervals. * - * @param intVals + * @param shiftTo * @param pos * @return number of positions or null if pos is not within intervals */ - private int[] countPos(Vector intVals, int pos) + protected static int[] countPos(List shiftTo, int pos) { - int count = 0, intv[], iv = 0, ivSize = intVals.size(); + int count = 0, intv[], iv = 0, ivSize = shiftTo.size(); while (iv < ivSize) { - intv = (int[]) intVals.elementAt(iv++); + intv = shiftTo.get(iv++); if (intv[0] <= intv[1]) { if (pos >= intv[0] && pos <= intv[1]) @@ -443,17 +507,18 @@ public class MapList /** * count out pos positions into a series of intervals and return the position * - * @param intVals + * @param shiftFrom * @param pos * @return position pos in interval set */ - private int[] countToPos(Vector intVals, int pos) + protected static int[] countToPos(List shiftFrom, int pos) { - int count = 0, diff = 0, iv = 0, ivSize = intVals.size(), intv[] = + int count = 0, diff = 0, iv = 0, ivSize = shiftFrom.size(); + int[] intv = { 0, 0 }; while (iv < ivSize) { - intv = (int[]) intVals.elementAt(iv++); + intv = shiftFrom.get(iv++); diff = intv[1] - intv[0]; if (diff >= 0) { @@ -487,69 +552,68 @@ public class MapList * find series of intervals mapping from start-end in the From map. * * @param start - * position in to map + * position mapped 'to' * @param end - * position in to map - * @return series of ranges in from map + * position mapped 'to' + * @return series of [start, end] ranges in sequence mapped 'from' */ public int[] locateInFrom(int start, int end) { // inefficient implementation int fromStart[] = shiftTo(start); - int fromEnd[] = shiftTo(end); // needs to be inclusive of end of symbol - // position - if (fromStart == null || fromEnd == null) - return null; - int iv[] = getIntervals(fromShifts, fromStart, fromEnd, fromRatio); - return iv; + // needs to be inclusive of end of symbol position + int fromEnd[] = shiftTo(end); + + return getIntervals(fromShifts, fromStart, fromEnd, fromRatio); } /** * find series of intervals mapping from start-end in the to map. * * @param start - * position in from map + * position mapped 'from' * @param end - * position in from map - * @return series of ranges in to map + * position mapped 'from' + * @return series of [start, end] ranges in sequence mapped 'to' */ public int[] locateInTo(int start, int end) { - // inefficient implementation int toStart[] = shiftFrom(start); int toEnd[] = shiftFrom(end); - if (toStart == null || toEnd == null) - return null; - int iv[] = getIntervals(toShifts, toStart, toEnd, toRatio); - return iv; + return getIntervals(toShifts, toStart, toEnd, toRatio); } /** * like shift - except returns the intervals in the given vector of shifts * which were spanned in traversing fromStart to fromEnd * - * @param fromShifts2 + * @param shiftFrom * @param fromStart * @param fromEnd * @param fromRatio2 * @return series of from,to intervals from from first position of starting * region to final position of ending region inclusive */ - private int[] getIntervals(Vector fromShifts2, int[] fromStart, + protected static int[] getIntervals(List shiftFrom, + int[] fromStart, int[] fromEnd, int fromRatio2) { + if (fromStart == null || fromEnd == null) + { + return null; + } int startpos, endpos; startpos = fromStart[0]; // first position in fromStart endpos = fromEnd[0]; // last position in fromEnd int endindx = (fromRatio2 - 1); // additional positions to get to last // position from endpos - int intv = 0, intvSize = fromShifts2.size(); + int intv = 0, intvSize = shiftFrom.size(); int iv[], i = 0, fs = -1, fe_s = -1, fe = -1; // containing intervals // search intervals to locate ones containing startpos and count endindx // positions on from endpos while (intv < intvSize && (fs == -1 || fe == -1)) { - iv = (int[]) fromShifts2.elementAt(intv++); + iv = shiftFrom.get(intv++); if (fe_s > -1) { endpos = iv[0]; // start counting from beginning of interval @@ -612,39 +676,45 @@ public class MapList i++; } if (fs == fe && fe == -1) + { return null; - Vector ranges = new Vector(); + } + List ranges = new ArrayList(); if (fs <= fe) { intv = fs; i = fs; // truncate initial interval - iv = (int[]) fromShifts2.elementAt(intv++); + iv = shiftFrom.get(intv++); iv = new int[] { iv[0], iv[1] };// clone if (i == fs) + { iv[0] = startpos; + } while (i != fe) { - ranges.addElement(iv); // add initial range - iv = (int[]) fromShifts2.elementAt(intv++); // get next interval + ranges.add(iv); // add initial range + iv = shiftFrom.get(intv++); // get next interval iv = new int[] { iv[0], iv[1] };// clone i++; } if (i == fe) + { iv[1] = endpos; - ranges.addElement(iv); // add only - or final range + } + ranges.add(iv); // add only - or final range } else { // walk from end of interval. - i = fromShifts2.size() - 1; + i = shiftFrom.size() - 1; while (i > fs) { i--; } - iv = (int[]) fromShifts2.elementAt(i); + iv = shiftFrom.get(i); iv = new int[] { iv[1], iv[0] };// reverse and clone // truncate initial interval @@ -654,8 +724,8 @@ public class MapList } while (--i != fe) { // fix apparent logic bug when fe==-1 - ranges.addElement(iv); // add (truncated) reversed interval - iv = (int[]) fromShifts2.elementAt(i); + ranges.add(iv); // add (truncated) reversed interval + iv = shiftFrom.get(i); iv = new int[] { iv[1], iv[0] }; // reverse and clone } @@ -664,7 +734,7 @@ public class MapList // interval is already reversed iv[1] = endpos; } - ranges.addElement(iv); // add only - or final range + ranges.add(iv); // add only - or final range } // create array of start end intervals. int[] range = null; @@ -676,10 +746,10 @@ public class MapList i = 0; while (intv < intvSize) { - iv = (int[]) ranges.elementAt(intv); + iv = ranges.get(intv); range[i++] = iv[0]; range[i++] = iv[1]; - ranges.setElementAt(null, intv++); // remove + ranges.set(intv++, null); // remove } } return range; @@ -694,6 +764,7 @@ public class MapList */ public int getToPosition(int mpos) { + // TODO not used - remove?? int[] mp = shiftTo(mpos); if (mp != null) { @@ -730,6 +801,7 @@ public class MapList */ public int getMappedPosition(int pos) { + // TODO not used - remove?? int[] mp = shiftFrom(pos); if (mp != null) { @@ -740,6 +812,7 @@ public class MapList public int[] getMappedWord(int pos) { + // TODO not used - remove?? int[] mp = shiftFrom(pos); if (mp != null) { @@ -750,223 +823,6 @@ public class MapList } /** - * test routine. not incremental. - * - * @param ml - * @param fromS - * @param fromE - */ - public static void testMap(MapList ml, int fromS, int fromE) - { - for (int from = 1; from <= 25; from++) - { - int[] too = ml.shiftFrom(from); - System.out.print("ShiftFrom(" + from + ")=="); - if (too == null) - { - System.out.print("NaN\n"); - } - else - { - System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")"); - System.out.print("\t+--+\t"); - int[] toofrom = ml.shiftTo(too[0]); - if (toofrom != null) - { - if (toofrom[0] != from) - { - System.err.println("Mapping not reflexive:" + from + " " - + too[0] + "->" + toofrom[0]); - } - System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] - + " % " + toofrom[1] + " (" + toofrom[2] + ")"); - } - else - { - System.out.println("ShiftTo(" + too[0] + ")==" - + "NaN! - not Bijective Mapping!"); - } - } - } - int mmap[][] = ml.makeFromMap(); - System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " - + mmap[0][2] + " " + mmap[0][3] + " "); - for (int i = 1; i <= mmap[1].length; i++) - { - if (mmap[1][i - 1] == -1) - { - System.out.print(i + "=XXX"); - - } - else - { - System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); - } - if (i % 20 == 0) - { - System.out.print("\n"); - } - else - { - System.out.print(","); - } - } - // test range function - System.out.print("\nTest locateInFrom\n"); - { - int f = mmap[0][2], t = mmap[0][3]; - while (f <= t) - { - System.out.println("Range " + f + " to " + t); - int rng[] = ml.locateInFrom(f, t); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - System.out.print("\nReversed\n"); - rng = ml.locateInFrom(t, f); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - System.out.print("\n"); - f++; - t--; - } - } - System.out.print("\n"); - mmap = ml.makeToMap(); - System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " - + mmap[0][2] + " " + mmap[0][3] + " "); - for (int i = 1; i <= mmap[1].length; i++) - { - if (mmap[1][i - 1] == -1) - { - System.out.print(i + "=XXX"); - - } - else - { - System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); - } - if (i % 20 == 0) - { - System.out.print("\n"); - } - else - { - System.out.print(","); - } - } - System.out.print("\n"); - // test range function - System.out.print("\nTest locateInTo\n"); - { - int f = mmap[0][2], t = mmap[0][3]; - while (f <= t) - { - System.out.println("Range " + f + " to " + t); - int rng[] = ml.locateInTo(f, t); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - System.out.print("\nReversed\n"); - rng = ml.locateInTo(t, f); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - f++; - t--; - System.out.print("\n"); - } - } - - } - - public static void main(String argv[]) - { - MapList ml = new MapList(new int[] - { 1, 5, 10, 15, 25, 20 }, new int[] - { 51, 1 }, 1, 3); - MapList ml1 = new MapList(new int[] - { 1, 3, 17, 4 }, new int[] - { 51, 1 }, 1, 3); - MapList ml2 = new MapList(new int[] - { 1, 60 }, new int[] - { 1, 20 }, 3, 1); - // test internal consistency - int to[] = new int[51]; - MapList.testMap(ml, 1, 60); - MapList mldna = new MapList(new int[] - { 2, 2, 6, 8, 12, 16 }, new int[] - { 1, 3 }, 3, 1); - int[] frm = mldna.locateInFrom(1, 1); - testLocateFrom(mldna, 1, 1, new int[] - { 2, 2, 6, 7 }); - MapList.testMap(mldna, 1, 3); - /* - * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[] - * toofrom=ml.shiftFrom(too[0]); - * System.out.println("ShiftFrom("+from+")=="+too[0]+" % - * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); } - */ - System.out.print("Success?\n"); // if we get here - something must be - // working! - } - - private static void testLocateFrom(MapList mldna, int i, int j, int[] ks) - { - int[] frm = mldna.locateInFrom(i, j); - if (frm == ks || java.util.Arrays.equals(frm, ks)) - { - System.out.println("Success test locate from " + i + " to " + j); - } - else - { - System.err.println("Failed test locate from " + i + " to " + j); - for (int c = 0; c < frm.length; c++) - { - System.err.print(frm[c] + ((c % 2 == 0) ? "," : ";")); - } - System.err.println("Expected"); - for (int c = 0; c < ks.length; c++) - { - System.err.print(ks[c] + ((c % 2 == 0) ? "," : ";")); - } - } - } - - /** * * @return a MapList whose From range is this maplist's To Range, and vice * versa @@ -987,6 +843,7 @@ public class MapList */ public boolean containsEither(boolean local, MapList map) { + // TODO not used - remove? if (local) { return ((getFromLowest() >= map.getFromLowest() && getFromHighest() <= map diff --git a/src/jalview/util/MappingUtils.java b/src/jalview/util/MappingUtils.java new file mode 100644 index 0000000..eebc539 --- /dev/null +++ b/src/jalview/util/MappingUtils.java @@ -0,0 +1,489 @@ +package jalview.util; + +import jalview.analysis.AlignmentSorter; +import jalview.api.AlignViewportI; +import jalview.commands.CommandI; +import jalview.commands.EditCommand; +import jalview.commands.EditCommand.Action; +import jalview.commands.EditCommand.Edit; +import jalview.commands.OrderCommand; +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentOrder; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Helper methods for manipulations involving sequence mappings. + * + * @author gmcarstairs + * + */ +public final class MappingUtils +{ + + /** + * Helper method to map a CUT or PASTE command. + * + * @param edit + * the original command + * @param undo + * if true, the command is to be undone + * @param targetSeqs + * the mapped sequences to apply the mapped command to + * @param result + * the mapped EditCommand to add to + * @param mappings + */ + protected static void mapCutOrPaste(Edit edit, boolean undo, + List targetSeqs, EditCommand result, + Set mappings) + { + Action action = edit.getAction(); + if (undo) + { + action = action.getUndoAction(); + } + // TODO write this + System.err.println("MappingUtils.mapCutOrPaste not yet implemented"); + } + + /** + * Returns a new EditCommand representing the given command as mapped to the + * given sequences. If there is no mapping, returns null. + * + * @param command + * @param undo + * @param mapTo + * @param gapChar + * @param mappings + * @return + */ + public static EditCommand mapEditCommand(EditCommand command, + boolean undo, final AlignmentI mapTo, char gapChar, + Set mappings) + { + /* + * For now, only support mapping from protein edits to cDna + */ + if (!mapTo.isNucleotide()) + { + return null; + } + + /* + * Cache a copy of the target sequences so we can mimic successive edits on + * them. This lets us compute mappings for all edits in the set. + */ + Map targetCopies = new HashMap(); + for (SequenceI seq : mapTo.getSequences()) + { + SequenceI ds = seq.getDatasetSequence(); + if (ds != null) + { + final SequenceI copy = new Sequence(seq); + copy.setDatasetSequence(ds); + targetCopies.put(ds, copy); + } + } + + /* + * Compute 'source' sequences as they were before applying edits: + */ + Map originalSequences = command.priorState(undo); + + EditCommand result = new EditCommand(); + Iterator edits = command.getEditIterator(!undo); + while (edits.hasNext()) + { + Edit edit = edits.next(); + if (edit.getAction() == Action.CUT + || edit.getAction() == Action.PASTE) + { + mapCutOrPaste(edit, undo, mapTo.getSequences(), result, mappings); + } + else if (edit.getAction() == Action.INSERT_GAP + || edit.getAction() == Action.DELETE_GAP) + { + mapInsertOrDelete(edit, undo, originalSequences, + mapTo.getSequences(), targetCopies, gapChar, result, + mappings); + } + } + return result.getSize() > 0 ? result : null; + } + + /** + * Helper method to map an edit command to insert or delete gaps. + * + * @param edit + * the original command + * @param undo + * if true, the action is to undo the command + * @param originalSequences + * the sequences the command acted on + * @param targetSeqs + * @param targetCopies + * @param gapChar + * @param result + * the new EditCommand to add mapped commands to + * @param mappings + */ + protected static void mapInsertOrDelete(Edit edit, boolean undo, + Map originalSequences, + final List targetSeqs, + Map targetCopies, char gapChar, + EditCommand result, Set mappings) + { + Action action = edit.getAction(); + + /* + * Invert sense of action if an Undo. + */ + if (undo) + { + action = action.getUndoAction(); + } + final int count = edit.getNumber(); + final int editPos = edit.getPosition(); + for (SequenceI seq : edit.getSequences()) + { + /* + * Get residue position at (or to right of) edit location. Note we use our + * 'copy' of the sequence before editing for this. + */ + SequenceI ds = seq.getDatasetSequence(); + if (ds == null) + { + continue; + } + final SequenceI actedOn = originalSequences.get(ds); + final int seqpos = actedOn.findPosition(editPos); + + /* + * Determine all mappings from this position to mapped sequences. + */ + SearchResults sr = buildSearchResults(seq, seqpos, mappings); + + if (!sr.isEmpty()) + { + for (SequenceI targetSeq : targetSeqs) + { + ds = targetSeq.getDatasetSequence(); + if (ds == null) + { + continue; + } + SequenceI copyTarget = targetCopies.get(ds); + final int[] match = sr.getResults(copyTarget, 0, + copyTarget.getLength()); + if (match != null) + { + final int ratio = 3; // TODO: compute this - how? + final int mappedCount = count * ratio; + + /* + * Shift Delete start position left, as it acts on positions to its + * right. + */ + int mappedEditPos = action == Action.DELETE_GAP ? match[0] + - mappedCount : match[0]; + Edit e = result.new Edit(action, new SequenceI[] + { targetSeq }, mappedEditPos, mappedCount, gapChar); + result.addEdit(e); + + /* + * and 'apply' the edit to our copy of its target sequence + */ + if (action == Action.INSERT_GAP) + { + copyTarget.setSequence(new String(StringUtils.insertCharAt( + copyTarget.getSequence(), mappedEditPos, mappedCount, + gapChar))); + } + else if (action == Action.DELETE_GAP) + { + copyTarget.setSequence(new String(StringUtils.deleteChars( + copyTarget.getSequence(), mappedEditPos, + mappedEditPos + mappedCount))); + } + } + } + } + /* + * and 'apply' the edit to our copy of its source sequence + */ + if (action == Action.INSERT_GAP) + { + actedOn.setSequence(new String(StringUtils.insertCharAt( + actedOn.getSequence(), editPos, count, gapChar))); + } + else if (action == Action.DELETE_GAP) + { + actedOn.setSequence(new String(StringUtils.deleteChars( + actedOn.getSequence(), editPos, editPos + count))); + } + } + } + + /** + * Returns a SearchResults object describing the mapped region corresponding + * to the specified sequence position. + * + * @param seq + * @param index + * @param seqmappings + * @return + */ + public static SearchResults buildSearchResults(SequenceI seq, int index, + Set seqmappings) + { + SearchResults results; + results = new SearchResults(); + if (index >= seq.getStart() && index <= seq.getEnd()) + { + for (AlignedCodonFrame acf : seqmappings) + { + acf.markMappedRegion(seq, index, results); + } + } + return results; + } + + /** + * Returns a (possibly empty) SequenceGroup containing any sequences in the + * mapped viewport corresponding to the given group in the source viewport. + * + * @param sg + * @param mapFrom + * @param mapTo + * @return + */ + public static SequenceGroup mapSequenceGroup(SequenceGroup sg, + AlignViewportI mapFrom, AlignViewportI mapTo) + { + /* + * Note the SequenceGroup holds aligned sequences, the mappings hold dataset + * sequences. + */ + boolean targetIsNucleotide = mapTo.isNucleotide(); + AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo; + Set codonFrames = protein.getAlignment() + .getCodonFrames(); + + /* + * Copy group name, name colours, but not sequences or sequence colour + * scheme + */ + SequenceGroup mappedGroup = new SequenceGroup(sg); + mappedGroup.cs = mapTo.getGlobalColourScheme(); + mappedGroup.clear(); + // TODO set width of mapped group + + for (SequenceI selected : sg.getSequences()) + { + for (AlignedCodonFrame acf : codonFrames) + { + SequenceI mappedSequence = targetIsNucleotide ? acf + .getDnaForAaSeq(selected) : acf.getAaForDnaSeq(selected); + if (mappedSequence != null) + { + for (SequenceI seq : mapTo.getAlignment().getSequences()) + { + if (seq.getDatasetSequence() == mappedSequence) + { + mappedGroup.addSequence(seq, false); + break; + } + } + } + } + } + return mappedGroup; + } + + /** + * Returns an OrderCommand equivalent to the given one, but acting on mapped + * sequences as described by the mappings, or null if no mapping can be made. + * + * @param command + * the original order command + * @param undo + * if true, the action is to undo the sort + * @param mapTo + * the alignment we are mapping to + * @param mappings + * the mappings available + * @return + */ + public static CommandI mapOrderCommand(OrderCommand command, + boolean undo, AlignmentI mapTo, Set mappings) + { + SequenceI[] sortOrder = command.getSequenceOrder(undo); + List mappedOrder = new ArrayList(); + int j = 0; + for (SequenceI seq : sortOrder) + { + for (AlignedCodonFrame acf : mappings) + { + /* + * Try protein-to-Dna, failing that try dna-to-protein + */ + SequenceI mappedSeq = acf.getDnaForAaSeq(seq); + if (mappedSeq == null) + { + mappedSeq = acf.getAaForDnaSeq(seq); + } + if (mappedSeq != null) + { + for (SequenceI seq2 : mapTo.getSequences()) + { + if (seq2.getDatasetSequence() == mappedSeq) + { + mappedOrder.add(seq2); + j++; + break; + } + } + } + } + } + + /* + * Return null if no mappings made. + */ + if (j == 0) + { + return null; + } + + /* + * Add any unmapped sequences on the end of the sort in their original + * ordering. + */ + if (j < mapTo.getHeight()) + { + for (SequenceI seq : mapTo.getSequences()) + { + if (!mappedOrder.contains(seq)) + { + mappedOrder.add(seq); + } + } + } + + /* + * Have to sort the sequences before constructing the OrderCommand - which + * then resorts them?!? + */ + final SequenceI[] mappedOrderArray = mappedOrder + .toArray(new SequenceI[mappedOrder.size()]); + SequenceI[] oldOrder = mapTo.getSequencesArray(); + AlignmentSorter.sortBy(mapTo, new AlignmentOrder(mappedOrderArray)); + final OrderCommand result = new OrderCommand(command.getDescription(), + oldOrder, mapTo); + return result; + } + + /** + * Returns a ColumnSelection in the 'mapTo' view which corresponds to the + * given selection in the 'mapFrom' view. We assume one is nucleotide, the + * other is protein (and holds the mappings from codons to protein residues). + * + * @param colsel + * @param mapFrom + * @param mapTo + * @return + */ + public static ColumnSelection mapColumnSelection(ColumnSelection colsel, + AlignViewportI mapFrom, AlignViewportI mapTo) + { + boolean targetIsNucleotide = mapTo.isNucleotide(); + AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo; + Set codonFrames = protein.getAlignment() + .getCodonFrames(); + ColumnSelection mappedColumns = new ColumnSelection(); + char fromGapChar = mapFrom.getAlignment().getGapCharacter(); + + // FIXME allow for hidden columns + + /* + * For each mapped column, find the range of columns that residues in that + * column map to. + */ + for (Object obj : colsel.getSelected()) + { + int col = ((Integer) obj).intValue(); + int mappedToMin = Integer.MAX_VALUE; + int mappedToMax = Integer.MIN_VALUE; + + /* + * For each sequence in the 'from' alignment + */ + for (SequenceI fromSeq : mapFrom.getAlignment().getSequences()) + { + /* + * Ignore gaps (unmapped anyway) + */ + if (fromSeq.getCharAt(col) == fromGapChar) + { + continue; + } + + /* + * Get the residue position and find the mapped position. + */ + int residuePos = fromSeq.findPosition(col); + SearchResults sr = buildSearchResults(fromSeq, residuePos, + codonFrames); + for (Match m : sr.getResults()) + { + int mappedStartResidue = m.getStart(); + int mappedEndResidue = m.getEnd(); + SequenceI mappedSeq = m.getSequence(); + + /* + * Locate the aligned sequence whose dataset is mappedSeq. TODO a + * datamodel that can do this efficiently. + */ + for (SequenceI toSeq : mapTo.getAlignment().getSequences()) + { + if (toSeq.getDatasetSequence() == mappedSeq) + { + int mappedStartCol = toSeq.findIndex(mappedStartResidue); + int mappedEndCol = toSeq.findIndex(mappedEndResidue); + mappedToMin = Math.min(mappedToMin, mappedStartCol); + mappedToMax = Math.max(mappedToMax, mappedEndCol); + // System.out.println(fromSeq.getName() + " mapped to cols " + // + mappedStartCol + ":" + mappedEndCol); + break; + // note: remove break if we ever want to map one to many sequences + } + } + } + } + /* + * Add the range of mapped columns to the mapped selection (converting + * base 1 to base 0). Note that this may include intron-only regions which + * lie between the start and end ranges of the selection. + */ + for (int i = mappedToMin; i <= mappedToMax; i++) + { + mappedColumns.addElement(i - 1); + } + } + return mappedColumns; + } + +} diff --git a/src/jalview/util/QuickSort.java b/src/jalview/util/QuickSort.java index e3bb514..cedf656 100755 --- a/src/jalview/util/QuickSort.java +++ b/src/jalview/util/QuickSort.java @@ -20,29 +20,64 @@ */ package jalview.util; +/** + * A class to perform efficient sorting of arrays of objects based on arrays of + * scores or other attributes. For example, residues by frequency. + * + * @author gmcarstairs + * + */ public class QuickSort { + /** + * Sorts both arrays with respect to ascending order of the items in the first + * array. + * + * @param arr + * @param s + */ public static void sort(int[] arr, Object[] s) { sort(arr, 0, arr.length - 1, s); } + /** + * Sorts both arrays with respect to ascending order of the items in the first + * array. + * + * @param arr + * @param s + */ public static void sort(float[] arr, Object[] s) { sort(arr, 0, arr.length - 1, s); } + /** + * Sorts both arrays with respect to ascending order of the items in the first + * array. + * + * @param arr + * @param s + */ public static void sort(double[] arr, Object[] s) { sort(arr, 0, arr.length - 1, s); } + /** + * Sorts both arrays with respect to descending order of the items in the + * first array. + * + * @param arr + * @param s + */ public static void sort(String[] arr, Object[] s) { stringSort(arr, 0, arr.length - 1, s); } - public static void stringSort(String[] arr, int p, int r, Object[] s) + static void stringSort(String[] arr, int p, int r, Object[] s) { int q; @@ -54,7 +89,7 @@ public class QuickSort } } - public static void sort(float[] arr, int p, int r, Object[] s) + static void sort(float[] arr, int p, int r, Object[] s) { int q; @@ -66,7 +101,7 @@ public class QuickSort } } - public static void sort(double[] arr, int p, int r, Object[] s) + static void sort(double[] arr, int p, int r, Object[] s) { int q; @@ -78,7 +113,7 @@ public class QuickSort } } - public static void sort(int[] arr, int p, int r, Object[] s) + static void sort(int[] arr, int p, int r, Object[] s) { int q; @@ -90,7 +125,7 @@ public class QuickSort } } - private static int partition(float[] arr, int p, int r, Object[] s) + static int partition(float[] arr, int p, int r, Object[] s) { float x = arr[p]; int i = p - 1; @@ -125,7 +160,7 @@ public class QuickSort } } - private static int partition(int[] arr, int p, int r, Object[] s) + static int partition(int[] arr, int p, int r, Object[] s) { int x = arr[p]; int i = p - 1; @@ -160,7 +195,7 @@ public class QuickSort } } - private static int partition(double[] arr, int p, int r, Object[] s) + static int partition(double[] arr, int p, int r, Object[] s) { double x = arr[p]; int i = p - 1; @@ -195,7 +230,7 @@ public class QuickSort } } - private static int stringPartition(String[] arr, int p, int r, Object[] s) + static int stringPartition(String[] arr, int p, int r, Object[] s) { String x = arr[p]; int i = p - 1; diff --git a/src/jalview/util/ReverseListIterator.java b/src/jalview/util/ReverseListIterator.java new file mode 100644 index 0000000..69a7345 --- /dev/null +++ b/src/jalview/util/ReverseListIterator.java @@ -0,0 +1,42 @@ +package jalview.util; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +/** + * An iterator that traverses a list backwards. + * + * @author gmcarstairs (and checked against + * org.codehaus.groovey.runtime.ReverseListIterator) + * + * @param + */ +public class ReverseListIterator implements Iterator +{ + + private ListIterator iterator; + + public ReverseListIterator(List stuff) + { + this.iterator = stuff.listIterator(stuff.size()); + } + @Override + public boolean hasNext() + { + return iterator.hasPrevious(); + } + + @Override + public E next() + { + return iterator.previous(); + } + + @Override + public void remove() + { + iterator.remove(); + } + +} diff --git a/src/jalview/util/ShiftList.java b/src/jalview/util/ShiftList.java index 2b3a8a4..8b37f0a 100644 --- a/src/jalview/util/ShiftList.java +++ b/src/jalview/util/ShiftList.java @@ -20,7 +20,8 @@ */ package jalview.util; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * ShiftList Simple way of mapping a linear series to a new linear range with @@ -29,11 +30,11 @@ import java.util.*; */ public class ShiftList { - public Vector shifts; + private List shifts; public ShiftList() { - shifts = new Vector(); + shifts = new ArrayList(); } /** @@ -46,21 +47,23 @@ public class ShiftList */ public void addShift(int pos, int shift) { - int sidx = 0; - int[] rshift = null; - while (sidx < shifts.size() - && (rshift = (int[]) shifts.elementAt(sidx))[0] < pos) - { - sidx++; - } - if (sidx == shifts.size()) + synchronized (shifts) { - shifts.insertElementAt(new int[] - { pos, shift }, sidx); - } - else - { - rshift[1] += shift; + int sidx = 0; + int[] rshift = null; + while (sidx < shifts.size() && (rshift = shifts.get(sidx))[0] < pos) + { + sidx++; + } + if (sidx == shifts.size()) + { + shifts.add(sidx, new int[] + { pos, shift }); + } + else + { + rshift[1] += shift; + } } } @@ -81,7 +84,7 @@ public class ShiftList int sidx = 0; int rshift[]; while (sidx < shifts.size() - && (rshift = ((int[]) shifts.elementAt(sidx++)))[0] <= pos) + && (rshift = (shifts.get(sidx++)))[0] <= pos) { shifted += rshift[1]; } @@ -91,9 +94,9 @@ public class ShiftList /** * clear all shifts */ - public void clear() + public synchronized void clear() { - shifts.removeAllElements(); + shifts.clear(); } /** @@ -104,15 +107,17 @@ public class ShiftList public ShiftList getInverse() { ShiftList inverse = new ShiftList(); - if (shifts != null) + synchronized (shifts) { - for (int i = 0, j = shifts.size(); i < j; i++) + if (shifts != null) { - int[] sh = (int[]) shifts.elementAt(i); - if (sh != null) + for (int[] sh : shifts) { - inverse.shifts.addElement(new int[] - { sh[0], -sh[1] }); + if (sh != null) + { + inverse.shifts.add(new int[] + { sh[0], -sh[1] }); + } } } } @@ -120,8 +125,8 @@ public class ShiftList } /** - * parse a 1d map of position 1 getShifts() + { + return shifts; + } } diff --git a/src/jalview/util/StringUtils.java b/src/jalview/util/StringUtils.java new file mode 100644 index 0000000..0544864 --- /dev/null +++ b/src/jalview/util/StringUtils.java @@ -0,0 +1,106 @@ +package jalview.util; + + +public class StringUtils +{ + + /** + * Returns a new character array, after inserting characters into the given + * character array. + * + * @param in + * the character array to insert into + * @param position + * the 0-based position for insertion + * @param count + * the number of characters to insert + * @param ch + * the character to insert + */ + public static final char[] insertCharAt(char[] in, int position, + int count, + char ch) + { + char[] tmp = new char[in.length + count]; + + if (position >= in.length) + { + System.arraycopy(in, 0, tmp, 0, in.length); + position = in.length; + } + else + { + System.arraycopy(in, 0, tmp, 0, position); + } + + int index = position; + while (count > 0) + { + tmp[index++] = ch; + count--; + } + + if (position < in.length) + { + System.arraycopy(in, position, tmp, index, + in.length - position); + } + + return tmp; + } + + /** + * Delete + * + * @param in + * @param from + * @param to + * @return + */ + public static final char[] deleteChars(char[] in, int from, int to) + { + if (from >= in.length) + { + return in; + } + + char[] tmp; + + if (to >= in.length) + { + tmp = new char[from]; + System.arraycopy(in, 0, tmp, 0, from); + to = in.length; + } + else + { + tmp = new char[in.length - to + from]; + System.arraycopy(in, 0, tmp, 0, from); + System.arraycopy(in, to, tmp, from, in.length - to); + } + return tmp; + } + + /** + * Returns the last part of 'input' after the last occurrence of 'token'. For + * example to extract only the filename from a full path or URL. + * + * @param input + * @param token + * a delimiter which must be in regular expression format + * @return + */ + public static String getLastToken(String input, String token) + { + if (input == null) + { + return null; + } + if (token == null) + { + return input; + } + String[] st = input.split(token); + return st[st.length - 1]; + } +} diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 08b31fa..d504093 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -25,10 +25,13 @@ import jalview.api.AlignCalcManagerI; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeaturesDisplayedI; +import jalview.api.ViewStyleI; +import jalview.commands.CommandI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; +import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; @@ -38,17 +41,23 @@ import jalview.schemes.Blosum62ColourScheme; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; import jalview.schemes.ResidueProperties; +import jalview.structure.CommandListener; +import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; +import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; import java.awt.Color; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.BitSet; +import java.util.Deque; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; -import java.util.Vector; /** * base class holding visualization and analysis attributes and common logic for @@ -57,150 +66,494 @@ import java.util.Vector; * @author jimp * */ -public abstract class AlignmentViewport implements AlignViewportI +public abstract class AlignmentViewport implements AlignViewportI, + ViewStyleI, CommandListener, VamsasSource { + protected ViewStyleI viewStyle = new ViewStyle(); + /** - * alignment displayed in the viewport. Please use get/setter + * A viewport that hosts the cDna view of this (protein), or vice versa (if + * set). */ - protected AlignmentI alignment; + AlignViewportI codingComplement = null; - protected String sequenceSetID; + FeaturesDisplayedI featuresDisplayed = null; + + protected Deque historyList = new ArrayDeque(); + + protected Deque redoList = new ArrayDeque(); /** - * probably unused indicator that view is of a dataset rather than an - * alignment + * @param name + * @see jalview.api.ViewStyleI#setFontName(java.lang.String) */ - protected boolean isDataset = false; + public void setFontName(String name) + { + viewStyle.setFontName(name); + } - private Map hiddenRepSequences; + /** + * @param style + * @see jalview.api.ViewStyleI#setFontStyle(int) + */ + public void setFontStyle(int style) + { + viewStyle.setFontStyle(style); + } - protected ColumnSelection colSel = new ColumnSelection(); + /** + * @param size + * @see jalview.api.ViewStyleI#setFontSize(int) + */ + public void setFontSize(int size) + { + viewStyle.setFontSize(size); + } - public boolean autoCalculateConsensus = true; + /** + * @return + * @see jalview.api.ViewStyleI#getFontStyle() + */ + public int getFontStyle() + { + return viewStyle.getFontStyle(); + } - protected boolean autoCalculateStrucConsensus = true; + /** + * @return + * @see jalview.api.ViewStyleI#getFontName() + */ + public String getFontName() + { + return viewStyle.getFontName(); + } - protected boolean ignoreGapsInConsensusCalculation = false; + /** + * @return + * @see jalview.api.ViewStyleI#getFontSize() + */ + public int getFontSize() + { + return viewStyle.getFontSize(); + } - protected ColourSchemeI globalColourScheme = null; + /** + * @param upperCasebold + * @see jalview.api.ViewStyleI#setUpperCasebold(boolean) + */ + public void setUpperCasebold(boolean upperCasebold) + { + viewStyle.setUpperCasebold(upperCasebold); + } /** - * gui state - changes to colour scheme propagated to all groups + * @return + * @see jalview.api.ViewStyleI#isUpperCasebold() */ - private boolean colourAppliesToAllGroups; + public boolean isUpperCasebold() + { + return viewStyle.isUpperCasebold(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isSeqNameItalics() + */ + public boolean isSeqNameItalics() + { + return viewStyle.isSeqNameItalics(); + } /** - * @param value - * indicating if subsequent colourscheme changes will be propagated - * to all groups + * @param colourByReferenceSeq + * @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean) + */ + public void setColourByReferenceSeq(boolean colourByReferenceSeq) + { + viewStyle.setColourByReferenceSeq(colourByReferenceSeq); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean) */ public void setColourAppliesToAllGroups(boolean b) { - colourAppliesToAllGroups = b; + viewStyle.setColourAppliesToAllGroups(b); } /** - * - * - * @return flag indicating if colourchanges propagated to all groups + * @return + * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups() */ public boolean getColourAppliesToAllGroups() { - return colourAppliesToAllGroups; + return viewStyle.getColourAppliesToAllGroups(); } - boolean abovePIDThreshold = false; - /** - * GUI state - * - * @return true if percent identity threshold is applied to shading + * @return + * @see jalview.api.ViewStyleI#getAbovePIDThreshold() */ public boolean getAbovePIDThreshold() { - return abovePIDThreshold; + return viewStyle.getAbovePIDThreshold(); + } + + /** + * @param inc + * @see jalview.api.ViewStyleI#setIncrement(int) + */ + public void setIncrement(int inc) + { + viewStyle.setIncrement(inc); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getIncrement() + */ + public int getIncrement() + { + return viewStyle.getIncrement(); } /** - * GUI state - * - * * @param b - * indicate if percent identity threshold is applied to shading + * @see jalview.api.ViewStyleI#setConservationSelected(boolean) */ - public void setAbovePIDThreshold(boolean b) + public void setConservationSelected(boolean b) + { + viewStyle.setConservationSelected(b); + } + + /** + * @param show + * @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean) + */ + public void setShowHiddenMarkers(boolean show) { - abovePIDThreshold = b; + viewStyle.setShowHiddenMarkers(show); } - int threshold; + /** + * @return + * @see jalview.api.ViewStyleI#getShowHiddenMarkers() + */ + public boolean getShowHiddenMarkers() + { + return viewStyle.getShowHiddenMarkers(); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean) + */ + public void setScaleRightWrapped(boolean b) + { + viewStyle.setScaleRightWrapped(b); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean) + */ + public void setScaleLeftWrapped(boolean b) + { + viewStyle.setScaleLeftWrapped(b); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean) + */ + public void setScaleAboveWrapped(boolean b) + { + viewStyle.setScaleAboveWrapped(b); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getScaleLeftWrapped() + */ + public boolean getScaleLeftWrapped() + { + return viewStyle.getScaleLeftWrapped(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getScaleAboveWrapped() + */ + public boolean getScaleAboveWrapped() + { + return viewStyle.getScaleAboveWrapped(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getScaleRightWrapped() + */ + public boolean getScaleRightWrapped() + { + return viewStyle.getScaleRightWrapped(); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean) + */ + public void setAbovePIDThreshold(boolean b) + { + viewStyle.setAbovePIDThreshold(b); + } /** - * DOCUMENT ME! - * * @param thresh - * DOCUMENT ME! + * @see jalview.api.ViewStyleI#setThreshold(int) */ public void setThreshold(int thresh) { - threshold = thresh; + viewStyle.setThreshold(thresh); } /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! + * @return + * @see jalview.api.ViewStyleI#getThreshold() */ public int getThreshold() { - return threshold; + return viewStyle.getThreshold(); } - int increment; + /** + * @return + * @see jalview.api.ViewStyleI#getShowJVSuffix() + */ + public boolean getShowJVSuffix() + { + return viewStyle.getShowJVSuffix(); + } /** - * - * @param inc - * set the scalar for bleaching colourschemes according to degree of - * conservation + * @param b + * @see jalview.api.ViewStyleI#setShowJVSuffix(boolean) */ - public void setIncrement(int inc) + public void setShowJVSuffix(boolean b) { - increment = inc; + viewStyle.setShowJVSuffix(b); } /** - * GUI State - * - * @return get scalar for bleaching colourschemes by conservation + * @param state + * @see jalview.api.ViewStyleI#setWrapAlignment(boolean) */ - public int getIncrement() + public void setWrapAlignment(boolean state) + { + viewStyle.setWrapAlignment(state); + } + + /** + * @param state + * @see jalview.api.ViewStyleI#setShowText(boolean) + */ + public void setShowText(boolean state) + { + viewStyle.setShowText(state); + } + + /** + * @param state + * @see jalview.api.ViewStyleI#setRenderGaps(boolean) + */ + public void setRenderGaps(boolean state) + { + viewStyle.setRenderGaps(state); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getColourText() + */ + public boolean getColourText() + { + return viewStyle.getColourText(); + } + + /** + * @param state + * @see jalview.api.ViewStyleI#setColourText(boolean) + */ + public void setColourText(boolean state) + { + viewStyle.setColourText(state); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getWrapAlignment() + */ + public boolean getWrapAlignment() + { + return viewStyle.getWrapAlignment(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowText() + */ + public boolean getShowText() + { + return viewStyle.getShowText(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getWrappedWidth() + */ + public int getWrappedWidth() + { + return viewStyle.getWrappedWidth(); + } + + /** + * @param w + * @see jalview.api.ViewStyleI#setWrappedWidth(int) + */ + public void setWrappedWidth(int w) + { + viewStyle.setWrappedWidth(w); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getCharHeight() + */ + public int getCharHeight() + { + return viewStyle.getCharHeight(); + } + + /** + * @param h + * @see jalview.api.ViewStyleI#setCharHeight(int) + */ + public void setCharHeight(int h) + { + viewStyle.setCharHeight(h); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getCharWidth() + */ + public int getCharWidth() + { + return viewStyle.getCharWidth(); + } + + /** + * @param w + * @see jalview.api.ViewStyleI#setCharWidth(int) + */ + public void setCharWidth(int w) + { + viewStyle.setCharWidth(w); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowBoxes() + */ + public boolean getShowBoxes() + { + return viewStyle.getShowBoxes(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowUnconserved() + */ + public boolean getShowUnconserved() + { + return viewStyle.getShowUnconserved(); + } + + /** + * @param showunconserved + * @see jalview.api.ViewStyleI#setShowUnconserved(boolean) + */ + public void setShowUnconserved(boolean showunconserved) { - return increment; + viewStyle.setShowUnconserved(showunconserved); } - boolean conservationColourSelected = false; + /** + * @param default1 + * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean) + */ + public void setSeqNameItalics(boolean default1) + { + viewStyle.setSeqNameItalics(default1); + } + + /** + * @param selected + * @see jalview.api.ViewStyleI#setShowSeqFeaturesHeight(boolean) + */ + public void setShowSeqFeaturesHeight(boolean selected) + { + viewStyle.setShowSeqFeaturesHeight(selected); + } + + /** + * alignment displayed in the viewport. Please use get/setter + */ + protected AlignmentI alignment; + + @Override + public AlignmentI getAlignment() + { + return alignment; + } + + @Override + public char getGapCharacter() + { + return alignment.getGapCharacter(); + } + + protected String sequenceSetID; + + /** + * probably unused indicator that view is of a dataset rather than an + * alignment + */ + protected boolean isDataset = false; + + public void setDataset(boolean b) + { + isDataset = b; + } + + public boolean isDataset() + { + return isDataset; + } + + + private Map hiddenRepSequences; + + protected ColumnSelection colSel = new ColumnSelection(); + + public boolean autoCalculateConsensus = true; + + protected boolean autoCalculateStrucConsensus = true; - /** - * GUI state - * - * @return true if conservation based shading is enabled - */ - public boolean getConservationSelected() - { - return conservationColourSelected; - } + protected boolean ignoreGapsInConsensusCalculation = false; + + protected ColourSchemeI globalColourScheme = null; - /** - * GUI state - * - * @param b - * enable conservation based shading - */ - public void setConservationSelected(boolean b) - { - conservationColourSelected = b; - } @Override public void setGlobalColourScheme(ColourSchemeI cs) @@ -221,7 +574,8 @@ public abstract class AlignmentViewport implements AlignViewportI || cs instanceof Blosum62ColourScheme) { recalc = true; - cs.setThreshold(threshold, ignoreGapsInConsensusCalculation); + cs.setThreshold(viewStyle.getThreshold(), + ignoreGapsInConsensusCalculation); } else { @@ -248,12 +602,13 @@ public abstract class AlignmentViewport implements AlignViewportI if (getAbovePIDThreshold() || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { - sg.cs.setThreshold(threshold, getIgnoreGapsConsensus()); + sg.cs.setThreshold(viewStyle.getThreshold(), + isIgnoreGapsConsensus()); recalc = true; } else { - sg.cs.setThreshold(0, getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, isIgnoreGapsConsensus()); } if (getConservationSelected()) @@ -577,11 +932,6 @@ public abstract class AlignmentViewport implements AlignViewportI } /** - * show non-conserved residues only - */ - protected boolean showUnconserved = false; - - /** * when set, updateAlignment will always ensure sequences are of equal length */ private boolean padGaps = false; @@ -591,24 +941,6 @@ public abstract class AlignmentViewport implements AlignViewportI */ public boolean sortByTree = false; - public boolean getShowUnconserved() - { - return showUnconserved; - } - - public void setShowUnconserved(boolean showunconserved) - { - showUnconserved = showunconserved; - } - - /** - * @param showNonconserved - * the showUnconserved to set - */ - public void setShowunconserved(boolean displayNonconserved) - { - this.showUnconserved = displayNonconserved; - } /** * @@ -722,6 +1054,7 @@ public abstract class AlignmentViewport implements AlignViewportI */ protected String viewId = null; + @Override public String getViewId() { if (viewId == null) @@ -796,7 +1129,7 @@ public abstract class AlignmentViewport implements AlignViewportI } @Override - public boolean getIgnoreGapsConsensus() + public boolean isIgnoreGapsConsensus() { return ignoreGapsInConsensusCalculation; } @@ -813,7 +1146,7 @@ public abstract class AlignmentViewport implements AlignViewportI protected boolean showConsensus = true; - Hashtable sequenceColours; + private Map sequenceColours = new HashMap(); /** * Property change listener for changes in alignment @@ -1050,9 +1383,6 @@ public abstract class AlignmentViewport implements AlignViewportI } @Override - public abstract void sendSelection(); - - @Override public void invertColumnSelection() { colSel.invertColumnSelection(0, alignment.getWidth()); @@ -1074,10 +1404,8 @@ public abstract class AlignmentViewport implements AlignViewportI AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation(); for (int i = 0; i < sequences.length; i++) { - sequences[i] = new Sequence(sequences[i], annots); // construct new - // sequence with - // subset of visible - // annotation + // construct new sequence with subset of visible annotation + sequences[i] = new Sequence(sequences[i], annots); } } else @@ -1106,10 +1434,10 @@ public abstract class AlignmentViewport implements AlignViewportI @Override - public jalview.datamodel.CigarArray getViewAsCigars( + public CigarArray getViewAsCigars( boolean selectedRegionOnly) { - return new jalview.datamodel.CigarArray(alignment, colSel, + return new CigarArray(alignment, colSel, (selectedRegionOnly ? selectionGroup : null)); } @@ -1171,9 +1499,9 @@ public abstract class AlignmentViewport implements AlignViewportI @Override - public int[][] getVisibleRegionBoundaries(int min, int max) + public List getVisibleRegionBoundaries(int min, int max) { - Vector regions = new Vector(); + ArrayList regions = new ArrayList(); int start = min; int end = max; @@ -1197,7 +1525,7 @@ public abstract class AlignmentViewport implements AlignViewportI } } - regions.addElement(new int[] + regions.add(new int[] { start, end }); if (colSel != null && colSel.hasHiddenColumns()) @@ -1209,10 +1537,7 @@ public abstract class AlignmentViewport implements AlignViewportI int[][] startEnd = new int[regions.size()][2]; - regions.copyInto(startEnd); - - return startEnd; - + return regions; } @Override @@ -1551,60 +1876,34 @@ public abstract class AlignmentViewport implements AlignViewportI } oldrfs.clear(); } - /** - * show the reference sequence in the alignment view - */ - private boolean displayReferenceSeq=false; - /** - * colour according to the reference sequence defined on the alignment - */ - private boolean colourByReferenceSeq=false; - @Override public boolean isDisplayReferenceSeq() { - return alignment.hasSeqrep() && displayReferenceSeq; + return alignment.hasSeqrep() && viewStyle.isDisplayReferenceSeq(); } @Override public void setDisplayReferenceSeq(boolean displayReferenceSeq) { - this.displayReferenceSeq = displayReferenceSeq; + viewStyle.setDisplayReferenceSeq(displayReferenceSeq); } + @Override public boolean isColourByReferenceSeq() { - return alignment.hasSeqrep() && colourByReferenceSeq; - } - - public void setColourByReferenceSeq(boolean colourByReferenceSeq) - { - this.colourByReferenceSeq = colourByReferenceSeq; + return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq(); } @Override public Color getSequenceColour(SequenceI seq) { - Color sqc = Color.white; - if (sequenceColours != null) - { - sqc = (Color) sequenceColours.get(seq); - if (sqc == null) - { - sqc = Color.white; - } - } - return sqc; + Color sqc = sequenceColours.get(seq); + return (sqc == null ? Color.white : sqc); } @Override public void setSequenceColour(SequenceI seq, Color col) { - if (sequenceColours == null) - { - sequenceColours = new Hashtable(); - } - if (col == null) { sequenceColours.remove(seq); @@ -1618,10 +1917,6 @@ public abstract class AlignmentViewport implements AlignViewportI @Override public void updateSequenceIdColours() { - if (sequenceColours == null) - { - sequenceColours = new Hashtable(); - } for (SequenceGroup sg : alignment.getGroups()) { if (sg.idColour != null) @@ -1637,10 +1932,42 @@ public abstract class AlignmentViewport implements AlignViewportI @Override public void clearSequenceColours() { - sequenceColours = null; + sequenceColours.clear(); }; - FeaturesDisplayedI featuresDisplayed = null; + @Override + public AlignViewportI getCodingComplement() + { + return this.codingComplement; + } + + /** + * Set this as the (cDna/protein) complement of the given viewport. Also + * ensures the reverse relationship is set on the given viewport. + */ + @Override + public void setCodingComplement(AlignViewportI av) + { + if (this == av) + { + System.err.println("Ignoring recursive setCodingComplement request"); + } + else + { + this.codingComplement = av; + // avoid infinite recursion! + if (av.getCodingComplement() != this) + { + av.setCodingComplement(this); + } + } + } + + @Override + public boolean isNucleotide() + { + return getAlignment() == null ? false : getAlignment().isNucleotide(); + } @Override public FeaturesDisplayedI getFeaturesDisplayed() @@ -1661,11 +1988,6 @@ public abstract class AlignmentViewport implements AlignViewportI } /** - * display setting for showing/hiding sequence features on alignment view - */ - boolean showSequenceFeatures = false; - - /** * set the flag * * @param b @@ -1674,55 +1996,331 @@ public abstract class AlignmentViewport implements AlignViewportI @Override public void setShowSequenceFeatures(boolean b) { - showSequenceFeatures = b; + viewStyle.setShowSequenceFeatures(b); } @Override public boolean isShowSequenceFeatures() { - return showSequenceFeatures; + return viewStyle.isShowSequenceFeatures(); } - boolean showSeqFeaturesHeight; - @Override public void setShowSequenceFeaturesHeight(boolean selected) { - showSeqFeaturesHeight = selected; + viewStyle.setShowSeqFeaturesHeight(selected); } @Override public boolean isShowSequenceFeaturesHeight() { - return showSeqFeaturesHeight; + return viewStyle.isShowSequenceFeaturesHeight(); } - private boolean showAnnotation = true; - - private boolean rightAlignIds = false; @Override public void setShowAnnotation(boolean b) { - showAnnotation = b; + viewStyle.setShowAnnotation(b); } @Override public boolean isShowAnnotation() { - return showAnnotation; + return viewStyle.isShowAnnotation(); } @Override public boolean isRightAlignIds() { - return rightAlignIds; + return viewStyle.isRightAlignIds(); } @Override public void setRightAlignIds(boolean rightAlignIds) { - this.rightAlignIds = rightAlignIds; + viewStyle.setRightAlignIds(rightAlignIds); + } + + @Override + public boolean getConservationSelected() + { + return viewStyle.getConservationSelected(); + } + + @Override + public void setShowBoxes(boolean state) + { + viewStyle.setShowBoxes(state); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getTextColour() + */ + public Color getTextColour() + { + return viewStyle.getTextColour(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getTextColour2() + */ + public Color getTextColour2() + { + return viewStyle.getTextColour2(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getThresholdTextColour() + */ + public int getThresholdTextColour() + { + return viewStyle.getThresholdTextColour(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isConservationColourSelected() + */ + public boolean isConservationColourSelected() + { + return viewStyle.isConservationColourSelected(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isRenderGaps() + */ + public boolean isRenderGaps() + { + return viewStyle.isRenderGaps(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowColourText() + */ + public boolean isShowColourText() + { + return viewStyle.isShowColourText(); + } + /** + * @return + * @see jalview.api.ViewStyleI#isShowSeqFeaturesHeight() + */ + public boolean isShowSeqFeaturesHeight() + { + return viewStyle.isShowSeqFeaturesHeight(); + } + + /** + * @param conservationColourSelected + * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean) + */ + public void setConservationColourSelected( + boolean conservationColourSelected) + { + viewStyle.setConservationColourSelected(conservationColourSelected); + } + + /** + * @param showColourText + * @see jalview.api.ViewStyleI#setShowColourText(boolean) + */ + public void setShowColourText(boolean showColourText) + { + viewStyle.setShowColourText(showColourText); + } + + /** + * @param textColour + * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color) + */ + public void setTextColour(Color textColour) + { + viewStyle.setTextColour(textColour); + } + + /** + * @param thresholdTextColour + * @see jalview.api.ViewStyleI#setThresholdTextColour(int) + */ + public void setThresholdTextColour(int thresholdTextColour) + { + viewStyle.setThresholdTextColour(thresholdTextColour); + } + + /** + * @param textColour2 + * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color) + */ + public void setTextColour2(Color textColour2) + { + viewStyle.setTextColour2(textColour2); + } + + @Override + public ViewStyleI getViewStyle() + { + return new ViewStyle(viewStyle); + } + + @Override + public void setViewStyle(ViewStyleI settingsForView) + { + viewStyle = new ViewStyle(settingsForView); + } + + @Override + public boolean sameStyle(ViewStyleI them) + { + return viewStyle.sameStyle(them); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getIdWidth() + */ + public int getIdWidth() + { + return viewStyle.getIdWidth(); + } + + /** + * @param i + * @see jalview.api.ViewStyleI#setIdWidth(int) + */ + public void setIdWidth(int i) + { + viewStyle.setIdWidth(i); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isCentreColumnLabels() + */ + public boolean isCentreColumnLabels() + { + return viewStyle.isCentreColumnLabels(); + } + + /** + * @param centreColumnLabels + * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean) + */ + public void setCentreColumnLabels(boolean centreColumnLabels) + { + viewStyle.setCentreColumnLabels(centreColumnLabels); } + /** + * @param showdbrefs + * @see jalview.api.ViewStyleI#setShowDBRefs(boolean) + */ + public void setShowDBRefs(boolean showdbrefs) + { + viewStyle.setShowDBRefs(showdbrefs); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowDBRefs() + */ + public boolean isShowDBRefs() + { + return viewStyle.isShowDBRefs(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowNPFeats() + */ + public boolean isShowNPFeats() + { + return viewStyle.isShowNPFeats(); + } + + /** + * @param shownpfeats + * @see jalview.api.ViewStyleI#setShowNPFeats(boolean) + */ + public void setShowNPFeats(boolean shownpfeats) + { + viewStyle.setShowNPFeats(shownpfeats); + } + + public abstract StructureSelectionManager getStructureSelectionManager(); + + /** + * Add one command to the command history list. + * + * @param command + */ + public void addToHistoryList(CommandI command) + { + if (this.historyList != null) + { + this.historyList.push(command); + broadcastCommand(command, false); + } + } + + protected void broadcastCommand(CommandI command, boolean undo) + { + getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource()); + } + + /** + * Add one command to the command redo list. + * + * @param command + */ + public void addToRedoList(CommandI command) + { + if (this.redoList != null) + { + this.redoList.push(command); + } + broadcastCommand(command, true); + } + + /** + * Clear the command redo list. + */ + public void clearRedoList() + { + if (this.redoList != null) + { + this.redoList.clear(); + } + } + + public void setHistoryList(Deque list) + { + this.historyList = list; + } + + public Deque getHistoryList() + { + return this.historyList; + } + + public void setRedoList(Deque list) + { + this.redoList = list; + } + + public Deque getRedoList() + { + return this.redoList; + } + + @Override + public VamsasSource getVamsasSource() + { + return this; + } } diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index c7cee04..8c2f0da 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -329,9 +329,7 @@ public abstract class FeatureRendererModel implements for (int i = 0; i < alignment.getHeight(); i++) { SequenceI asq = alignment.getSequenceAt(i); - SequenceI dasq = asq.getDatasetSequence(); - SequenceFeature[] features = dasq != null ? dasq - .getSequenceFeatures() : asq.getSequenceFeatures(); + SequenceFeature[] features = asq.getSequenceFeatures(); if (features == null) { diff --git a/src/jalview/viewmodel/styles/ViewStyle.java b/src/jalview/viewmodel/styles/ViewStyle.java new file mode 100644 index 0000000..1e97af4 --- /dev/null +++ b/src/jalview/viewmodel/styles/ViewStyle.java @@ -0,0 +1,1007 @@ +package jalview.viewmodel.styles; + +import jalview.api.ViewStyleI; + +import java.awt.Color; +import java.lang.reflect.Method; +import java.util.HashMap; + +/** + * A container for holding alignment view properties. View properties are + * data-independent, which means they can be safely copied between views + * involving different alignment data without causing exceptions in the + * rendering system. + * + * @author jprocter + * + */ +public class ViewStyle implements ViewStyleI +{ + + private boolean abovePIDThreshold = false; + + int charHeight; + + int charWidth; + + int idWidth = -1; + + /** + * gui state - changes to colour scheme propagated to all groups + */ + private boolean colourAppliesToAllGroups; + + /** + * centre columnar annotation labels in displayed alignment annotation + */ + boolean centreColumnLabels = false; + + private boolean showdbrefs; + + private boolean shownpfeats; + + // --------END Structure Conservation + + /** + * colour according to the reference sequence defined on the alignment + */ + private boolean colourByReferenceSeq = false; + + boolean conservationColourSelected = false; + + /** + * show the reference sequence in the alignment view + */ + private boolean displayReferenceSeq = false; + + private int increment; + + /** + * display gap characters + */ + boolean renderGaps = true; + + private boolean rightAlignIds = false; + + boolean scaleAboveWrapped = false; + + boolean scaleLeftWrapped = true; + + boolean scaleRightWrapped = true; + + boolean seqNameItalics; + + /** + * show annotation tracks on the alignment + */ + private boolean showAnnotation = true; + + /** + * render each residue in a coloured box + */ + boolean showBoxes = true; + + /** + * Colour sequence text + */ + boolean showColourText = false; + + /** + * show blue triangles + */ + boolean showHiddenMarkers = true; + + /** + * show /start-end in ID panel + */ + boolean showJVSuffix = true; + + /** + * scale features height according to score + */ + boolean showSeqFeaturesHeight; + + /** + * display setting for showing/hiding sequence features on alignment view + */ + boolean showSequenceFeatures = false; + + /** + * display sequence symbols + */ + boolean showText = true; + + /** + * show non-conserved residues only + */ + protected boolean showUnconserved = false; + + Color textColour = Color.black; + + Color textColour2 = Color.white; + + /** + * PID or consensus threshold + */ + int threshold; + + /** + * threshold for switching between textColour & textColour2 + */ + int thresholdTextColour = 0; + + /** + * upper case characters in sequence are shown in bold + */ + boolean upperCasebold = false; + + /** + * name of base font for view + */ + private String fontName; + /** + * size for base font + */ + private int fontSize; + + public ViewStyle(ViewStyleI viewStyle) + { + ViewStyle.configureFrom(this, viewStyle); + } + + public ViewStyle() + { + } + + private static HashMap getters, isErs, setters; + static + { + getters = new HashMap(); + isErs = new HashMap(); + setters = new HashMap(); + // Match Getters and Setters + for (Method m : ViewStyleI.class.getMethods()) + { + if (m.getDeclaringClass() == ViewStyleI.class) + { + if (m.getName().startsWith("get")) + { + getters.put(m.getName().substring(3), m); + } + if (m.getName().startsWith("is")) + { + isErs.put(m.getName().substring(2), m); + } + if (m.getName().startsWith("set")) + { + setters.put(m.getName().substring(3), m); + } + } + } + } + + private static void configureFrom(ViewStyle us, ViewStyleI viewStyle) + { + // try and do the set thing + for (String prop : setters.keySet()) + { + Method getter = getters.get(prop); + Method setter = setters.get(prop); + if (getter == null) + { + getter = isErs.get(prop); + } + if (getter != null && setter != null) + { + try + { + setter.invoke(us, getter.invoke(viewStyle)); + } catch (Exception q) + { + System.err.println("Unexpected exception setting view property " + + prop + " by reflection"); + q.printStackTrace(); + } + + } + } + } + + private static boolean equivalent(ViewStyle us, ViewStyleI them) + { + // look for properties we can set + for (String prop : setters.keySet()) + { + Method getter = getters.get(prop); + if (getter == null) + { + getter = isErs.get(prop); + } + if (getter != null) + { + try + { + if (!getter.invoke(them).equals(getter.invoke(us))) + { + return false; + } + } catch (Exception q) + { + System.err.println("Unexpected exception testing equivalence of property " + + prop + " by reflection"); + q.printStackTrace(); + } + } + } + + return true; + } + + public boolean equals(ViewStyleI other) + { + return other == null ? false : equivalent(this, other); + } + + /** + * @return the upperCasebold + */ + @Override + public boolean isUpperCasebold() + { + return upperCasebold; + } + + /** + * @param upperCasebold + * the upperCasebold to set + */ + @Override + public void setUpperCasebold(boolean upperCasebold) + { + this.upperCasebold = upperCasebold; + } + + /** + * flag for wrapping + */ + boolean wrapAlignment = false; + + /** + * number columns in wrapped alignment + */ + int wrappedWidth; + + private int fontStyle; + + /** + * GUI state + * + * @return true if percent identity threshold is applied to shading + */ + @Override + public boolean getAbovePIDThreshold() + { + return abovePIDThreshold; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getCharHeight() + { + return charHeight; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getCharWidth() + { + return charWidth; + } + + /** + * + * + * @return flag indicating if colourchanges propagated to all groups + */ + @Override + public boolean getColourAppliesToAllGroups() + { + return colourAppliesToAllGroups; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getColourText() + { + return showColourText; + } + + /** + * GUI state + * + * @return true if conservation based shading is enabled + */ + @Override + public boolean getConservationSelected() + { + return conservationColourSelected; + } + + /** + * GUI State + * + * @return get scalar for bleaching colourschemes by conservation + */ + @Override + public int getIncrement() + { + return increment; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getScaleAboveWrapped() + { + return scaleAboveWrapped; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getScaleLeftWrapped() + { + return scaleLeftWrapped; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getScaleRightWrapped() + { + return scaleRightWrapped; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getShowBoxes() + { + return showBoxes; + } + + @Override + public boolean getShowHiddenMarkers() + { + return showHiddenMarkers; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getShowJVSuffix() + { + return showJVSuffix; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getShowText() + { + return showText; + } + + @Override + public boolean getShowUnconserved() + { + return showUnconserved; + } + + /** + * @return the textColour + */ + @Override + public Color getTextColour() + { + return textColour; + } + + /** + * @return the textColour2 + */ + @Override + public Color getTextColour2() + { + return textColour2; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getThreshold() + { + return threshold; + } + + /** + * @return the thresholdTextColour + */ + @Override + public int getThresholdTextColour() + { + return thresholdTextColour; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getWrapAlignment() + { + return wrapAlignment; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getWrappedWidth() + { + return wrappedWidth; + } + + @Override + public boolean isColourByReferenceSeq() + { + return colourByReferenceSeq; + } + + /** + * @return the conservationColourSelected + */ + @Override + public boolean isConservationColourSelected() + { + return conservationColourSelected; + } + + @Override + public boolean isDisplayReferenceSeq() + { + return displayReferenceSeq; + } + + /** + * @return the renderGaps + */ + @Override + public boolean isRenderGaps() + { + return renderGaps; + } + + @Override + public boolean isRightAlignIds() + { + return rightAlignIds; + } + + /** + * @return the seqNameItalics + */ + @Override + public boolean isSeqNameItalics() + { + return seqNameItalics; + } + + @Override + public boolean isShowAnnotation() + { + return showAnnotation; + } + + /** + * @return the showColourText + */ + @Override + public boolean isShowColourText() + { + return showColourText; + } + + /** + * @return the showSeqFeaturesHeight + */ + @Override + public boolean isShowSeqFeaturesHeight() + { + return showSeqFeaturesHeight; + } + + @Override + public boolean isShowSequenceFeatures() + { + return showSequenceFeatures; + } + + @Override + public boolean isShowSequenceFeaturesHeight() + { + + return showSeqFeaturesHeight; + } + + /** + * GUI state + * + * + * @param b + * indicate if percent identity threshold is applied to shading + */ + @Override + public void setAbovePIDThreshold(boolean b) + { + abovePIDThreshold = b; + } + + + /** + * DOCUMENT ME! + * + * @param h + * DOCUMENT ME! + */ + @Override + public void setCharHeight(int h) + { + this.charHeight = h; + } + + /** + * DOCUMENT ME! + * + * @param w + * DOCUMENT ME! + */ + @Override + public void setCharWidth(int w) + { + this.charWidth = w; + } + + + /** + * @param value + * indicating if subsequent colourscheme changes will be propagated + * to all groups + */ + @Override + public void setColourAppliesToAllGroups(boolean b) + { + colourAppliesToAllGroups = b; + } + + @Override + public void setColourByReferenceSeq(boolean colourByReferenceSeq) + { + this.colourByReferenceSeq = colourByReferenceSeq; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setColourText(boolean state) + { + showColourText = state; + } + + /** + * @param conservationColourSelected + * the conservationColourSelected to set + */ + @Override + public void setConservationColourSelected( + boolean conservationColourSelected) + { + this.conservationColourSelected = conservationColourSelected; + } + + /** + * GUI state + * + * @param b + * enable conservation based shading + */ + @Override + public void setConservationSelected(boolean b) + { + conservationColourSelected = b; + } + + @Override + public void setDisplayReferenceSeq(boolean displayReferenceSeq) + { + this.displayReferenceSeq = displayReferenceSeq; + } + + /** + * + * @param inc + * set the scalar for bleaching colourschemes according to degree of + * conservation + */ + @Override + public void setIncrement(int inc) + { + increment = inc; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setRenderGaps(boolean state) + { + renderGaps = state; + } + + @Override + public void setRightAlignIds(boolean rightAlignIds) + { + this.rightAlignIds = rightAlignIds; + } + + /** + * DOCUMENT ME! + * + * @param b + * DOCUMENT ME! + */ + @Override + public void setScaleAboveWrapped(boolean b) + { + scaleAboveWrapped = b; + } + + /** + * DOCUMENT ME! + * + * @param b + * DOCUMENT ME! + */ + @Override + public void setScaleLeftWrapped(boolean b) + { + scaleLeftWrapped = b; + } + + /** + * + * + * @param scaleRightWrapped + * - true or false + */ + + @Override + public void setScaleRightWrapped(boolean b) + { + scaleRightWrapped = b; + } + + @Override + public void setSeqNameItalics(boolean italics) + { + seqNameItalics = italics; + } + + @Override + public void setShowAnnotation(boolean b) + { + showAnnotation = b; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setShowBoxes(boolean state) + { + showBoxes = state; + } + + /** + * @param showColourText + * the showColourText to set + */ + @Override + public void setShowColourText(boolean showColourText) + { + this.showColourText = showColourText; + } + + @Override + public void setShowHiddenMarkers(boolean show) + { + showHiddenMarkers = show; + } + + /** + * DOCUMENT ME! + * + * @param b + * DOCUMENT ME! + */ + @Override + public void setShowJVSuffix(boolean b) + { + showJVSuffix = b; + } + + @Override + public void setShowSeqFeaturesHeight(boolean selected) + { + showSeqFeaturesHeight = selected; + + } + + /** + * set the flag + * + * @param b + * features are displayed if true + */ + @Override + public void setShowSequenceFeatures(boolean b) + { + showSequenceFeatures = b; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setShowText(boolean state) + { + showText = state; + } + + @Override + public void setShowUnconserved(boolean showunconserved) + { + showUnconserved = showunconserved; + } + + /** + * @param textColour + * the textColour to set + */ + @Override + public void setTextColour(Color textColour) + { + this.textColour = textColour; + } + + /** + * @param textColour2 + * the textColour2 to set + */ + @Override + public void setTextColour2(Color textColour2) + { + this.textColour2 = textColour2; + } + + /** + * DOCUMENT ME! + * + * @param thresh + * DOCUMENT ME! + */ + @Override + public void setThreshold(int thresh) + { + threshold = thresh; + } + + /** + * @param thresholdTextColour + * the thresholdTextColour to set + */ + @Override + public void setThresholdTextColour(int thresholdTextColour) + { + this.thresholdTextColour = thresholdTextColour; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setWrapAlignment(boolean state) + { + wrapAlignment = state; + } + + /** + * DOCUMENT ME! + * + * @param w + * DOCUMENT ME! + */ + @Override + public void setWrappedWidth(int w) + { + this.wrappedWidth = w; + } + + @Override + public boolean sameStyle(ViewStyleI them) + { + return equivalent(this, them); + } + + @Override + public String getFontName() + { + return fontName; + } + + @Override + public int getFontSize() + { + return fontSize; + } + + @Override + public int getFontStyle() + { + return fontStyle; + } + + @Override + public void setFontName(String name) + { + fontName = name; + } + + @Override + public void setFontSize(int size) + { + fontSize = size; + + } + + @Override + public void setFontStyle(int style) + { + fontStyle = style; + } + + @Override + public int getIdWidth() + { + return idWidth; + } + + /** + * @param idWidth + * the idWidth to set + */ + @Override + public void setIdWidth(int idWidth) + { + this.idWidth = idWidth; + } + + /** + * @return the centreColumnLabels + */ + @Override + public boolean isCentreColumnLabels() + { + return centreColumnLabels; + } + + /** + * @param centreColumnLabels + * the centreColumnLabels to set + */ + @Override + public void setCentreColumnLabels(boolean centreColumnLabels) + { + this.centreColumnLabels = centreColumnLabels; + } + + /** + * @return the showdbrefs + */ + @Override + public boolean isShowDBRefs() + { + return showdbrefs; + } + + /** + * @param showdbrefs + * the showdbrefs to set + */ + @Override + public void setShowDBRefs(boolean showdbrefs) + { + this.showdbrefs = showdbrefs; + } + + /** + * @return the shownpfeats + */ + @Override + public boolean isShowNPFeats() + { + return shownpfeats; + } + + /** + * @param shownpfeats + * the shownpfeats to set + */ + @Override + public void setShowNPFeats(boolean shownpfeats) + { + this.shownpfeats = shownpfeats; + } +} diff --git a/src/jalview/workers/ConsensusThread.java b/src/jalview/workers/ConsensusThread.java index c754ee3..f940450 100644 --- a/src/jalview/workers/ConsensusThread.java +++ b/src/jalview/workers/ConsensusThread.java @@ -158,7 +158,7 @@ public class ConsensusThread extends AlignCalcWorker implements && hconsensus != null) { AAFrequency.completeConsensus(consensus, hconsensus, 0, - hconsensus.length, alignViewport.getIgnoreGapsConsensus(), + hconsensus.length, alignViewport.isIgnoreGapsConsensus(), alignViewport.isShowSequenceLogo(), nseq); } } diff --git a/src/jalview/workers/StrucConsensusThread.java b/src/jalview/workers/StrucConsensusThread.java index 3230a36..2249081 100644 --- a/src/jalview/workers/StrucConsensusThread.java +++ b/src/jalview/workers/StrucConsensusThread.java @@ -166,7 +166,7 @@ public class StrucConsensusThread extends AlignCalcWorker implements { StructureFrequency.completeConsensus(strucConsensus, hStrucConsensus, 0, hStrucConsensus.length, - alignViewport.getIgnoreGapsConsensus(), + alignViewport.isIgnoreGapsConsensus(), alignViewport.isShowSequenceLogo(), nseq); } } diff --git a/src/jalview/ws/AWSThread.java b/src/jalview/ws/AWSThread.java index d3682d4..3359546 100644 --- a/src/jalview/ws/AWSThread.java +++ b/src/jalview/ws/AWSThread.java @@ -28,8 +28,11 @@ import jalview.datamodel.AlignmentView; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.WebserviceInfo; -import jalview.viewmodel.seqfeatures.FeatureRendererSettings; import jalview.util.MessageManager; +import jalview.viewmodel.seqfeatures.FeatureRendererSettings; + +import java.util.LinkedHashSet; +import java.util.Set; public abstract class AWSThread extends Thread { @@ -57,7 +60,7 @@ public abstract class AWSThread extends Thread /** * dataset sequence relationships to be propagated onto new results */ - protected AlignedCodonFrame[] codonframe = null; + protected Set codonframe = null; /** * are there jobs still running in this thread. @@ -87,6 +90,11 @@ public abstract class AWSThread extends Thread */ protected String WsUrl = null; + /* + * The AlignFrame from which the service was requested. + */ + private AlignFrame alignFrame; + /** * generic web service job/subjob poll loop */ @@ -124,8 +132,9 @@ public abstract class AWSThread extends Thread } catch (Exception ex) { // Deal with Transaction exceptions - wsInfo.appendProgressText(jobs[j].jobnum, - MessageManager.formatMessage("info.server_exception", new String[]{WebServiceName,ex.getMessage()})); + wsInfo.appendProgressText(jobs[j].jobnum, MessageManager + .formatMessage("info.server_exception", new Object[] + { WebServiceName, ex.getMessage() })); // always output the exception's stack trace to the log Cache.log.warn(WebServiceName + " job(" + jobs[j].jobnum + ") Server exception."); @@ -189,7 +198,7 @@ public abstract class AWSThread extends Thread { Cache.log .debug("WebServiceJob poll loop finished with no jobs created."); - wsInfo.setStatus(wsInfo.STATE_STOPPED_ERROR); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); wsInfo.appendProgressText(MessageManager.getString("info.no_jobs_ran")); wsInfo.setFinishedNoResults(); } @@ -295,13 +304,12 @@ public abstract class AWSThread extends Thread SequenceI[] alignment = al.getSequencesArray(); for (int sq = 0; sq < alignment.length; sq++) { - for (int i = 0; i < codonframe.length; i++) + for (AlignedCodonFrame acf : codonframe) { - if (codonframe[i] != null - && codonframe[i].involvesSequence(alignment[sq])) + final SequenceI seq = alignment[sq]; + if (acf != null && acf.involvesSequence(seq)) { - al.addCodonFrame(codonframe[i]); - codonframe[i] = null; + al.addCodonFrame(acf); break; } } @@ -360,7 +368,7 @@ public abstract class AWSThread extends Thread AlignmentView alview, String wsurl2) { super(); - // this.alignFrame = alframe; + this.alignFrame = alframe; currentView = alframe.getCurrentView().getAlignment(); featureSettings = alframe.getFeatureRenderer().getSettings(); defGapChar = alframe.getViewport().getGapCharacter(); @@ -369,13 +377,18 @@ public abstract class AWSThread extends Thread WsUrl = wsurl2; if (alframe != null) { - AlignedCodonFrame[] cf = alframe.getViewport().getAlignment() + Set cf = alframe.getViewport().getAlignment() .getCodonFrames(); if (cf != null) { - codonframe = new AlignedCodonFrame[cf.length]; - System.arraycopy(cf, 0, codonframe, 0, cf.length); + codonframe = new LinkedHashSet(); + codonframe.addAll(cf); } } } + + protected AlignFrame getRequestingAlignFrame() + { + return this.alignFrame; + } } diff --git a/src/jalview/ws/jws2/JPred301Client.java b/src/jalview/ws/jws2/JPred301Client.java index 8328d45..41d8a7f 100644 --- a/src/jalview/ws/jws2/JPred301Client.java +++ b/src/jalview/ws/jws2/JPred301Client.java @@ -35,6 +35,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import compbio.data.sequence.FastaSequence; import compbio.data.sequence.JpredAlignment; @@ -90,15 +92,18 @@ public class JPred301Client extends JabawsMsaInterfaceAlignCalcWorker return "calculating consensus secondary structure prediction using JPred service"; } - private static HashMap jpredRowLabels = new HashMap(); + private static Map jpredRowLabels = new HashMap(); - private static HashSet jpredRes_graph, jpredRes_ssonly; + private static final Set jpredRes_graph; + + private static final Set jpredRes_ssonly; + static { - jpredRes_ssonly = new HashSet(); + jpredRes_ssonly = new HashSet(); jpredRes_ssonly.add("jnetpred".toLowerCase()); jpredRes_ssonly.add("jnetpssm".toLowerCase()); jpredRes_ssonly.add("jnethmm".toLowerCase()); - jpredRes_graph = new HashSet(); + jpredRes_graph = new HashSet(); jpredRes_graph.add("jnetconf".toLowerCase()); jpredRes_graph.add("jnet burial".toLowerCase()); } diff --git a/src/jalview/ws/jws2/MsaWSThread.java b/src/jalview/ws/jws2/MsaWSThread.java index 2bae428..0178130 100644 --- a/src/jalview/ws/jws2/MsaWSThread.java +++ b/src/jalview/ws/jws2/MsaWSThread.java @@ -23,6 +23,7 @@ package jalview.ws.jws2; import jalview.analysis.AlignSeq; import jalview.bin.Cache; import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; import jalview.datamodel.AlignmentView; import jalview.datamodel.ColumnSelection; @@ -30,6 +31,7 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.Desktop; +import jalview.gui.SplitFrame; import jalview.gui.WebserviceInfo; import jalview.util.MessageManager; import jalview.ws.AWsJob; @@ -44,6 +46,8 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import javax.swing.JInternalFrame; + import compbio.data.msa.MsaWS; import compbio.metadata.Argument; import compbio.metadata.ChunkHolder; @@ -447,7 +451,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI * @param presorder * boolean */ - MsaWSThread(MsaWS server, String wsUrl, WebserviceInfo wsinfo, + private MsaWSThread(MsaWS server, String wsUrl, WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame, AlignmentView alview, String wsname, boolean subgaps, boolean presorder) { @@ -892,10 +896,16 @@ class MsaWSThread extends AWS2Thread implements WSClientI wsInfo.setProgressBar(null, progbar); } + /** + * Display alignment results in a new frame (or - not currently supported - + * added to an existing alignment). + * + * @param newFrame + */ void displayResults(boolean newFrame) { // view input or result data for each block - Vector alorders = new Vector(); + List alorders = new ArrayList(); SequenceI[][] results = new SequenceI[jobs.length][]; AlignmentOrder[] orders = new AlignmentOrder[jobs.length]; String lastProgram = null; @@ -907,7 +917,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI msjob = (MsaWSJob) jobs[j]; Object[] res = msjob.getAlignment(); lastProgram = msjob.getAlignmentProgram(); - alorders.add(res[1]); + alorders.add((AlignmentOrder) res[1]); results[j] = (SequenceI[]) res[0]; orders[j] = (AlignmentOrder) res[1]; @@ -944,71 +954,126 @@ class MsaWSThread extends AWS2Thread implements WSClientI if (newFrame) { - AlignFrame af = new AlignFrame(al, columnselection, - AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + displayInNewFrame(al, alorders, columnselection); - // initialise with same renderer settings as in parent alignframe. - af.getFeatureRenderer().transferSettings(this.featureSettings); - // update orders - if (alorders.size() > 0) - { - if (alorders.size() == 1) - { - af.addSortByOrderMenuItem(WebServiceName + " Ordering", - (AlignmentOrder) alorders.get(0)); - } - else - { - // construct a non-redundant ordering set - Vector names = new Vector(); - for (int i = 0, l = alorders.size(); i < l; i++) - { - String orderName = new String(" Region " + i); - int j = i + 1; + } + else + { + System.out.println("MERGE WITH OLD FRAME"); + // TODO: modify alignment in original frame, replacing old for new + // alignment using the commands.EditCommand model to ensure the update can + // be undone + } + } - while (j < l) - { - if (((AlignmentOrder) alorders.get(i)) - .equals(((AlignmentOrder) alorders.get(j)))) - { - alorders.remove(j); - l--; - orderName += "," + j; - } - else - { - j++; - } - } + /** + * Display the alignment result in a new frame. + * + * @param al + * @param alorders + * @param columnselection + */ + protected void displayInNewFrame(AlignmentI al, + List alorders, ColumnSelection columnselection) + { + AlignFrame af = new AlignFrame(al, columnselection, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - if (i == 0 && j == 1) - { - names.add(new String("")); - } - else - { - names.add(orderName); - } - } - for (int i = 0, l = alorders.size(); i < l; i++) - { - af.addSortByOrderMenuItem( - WebServiceName + ((String) names.get(i)) + " Ordering", - (AlignmentOrder) alorders.get(i)); - } - } + // initialise with same renderer settings as in parent alignframe. + af.getFeatureRenderer().transferSettings(this.featureSettings); + + if (alorders.size() > 0) + { + addSortByMenuItems(af, alorders); + } + + /* + * If alignment was requested from one half of a SplitFrame, show in a + * SplitFrame with the other pane similarly aligned. + */ + AlignFrame requestedBy = getRequestingAlignFrame(); + if (requestedBy != null && requestedBy.getSplitViewContainer() != null) + { + AlignmentI complement = requestedBy.getSplitViewContainer() + .getComplement(requestedBy); + String complementTitle = requestedBy.getSplitViewContainer() + .getComplementTitle(requestedBy); + AlignmentI copyComplement = new Alignment(complement); + copyComplement.alignAs(al); + if (copyComplement.getHeight() > 0) + { + af.setTitle(alTitle); + AlignFrame af2 = new AlignFrame(copyComplement, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + af2.setTitle(complementTitle); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + JInternalFrame splitFrame = new SplitFrame(al.isNucleotide() ? af + : af2, al.isNucleotide() ? af2 : af); + Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1); + return; } + } - Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); + /* + * Not from SplitFrame, or failed to created a complementary alignment + */ + Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + /** + * Add sort order options to the AlignFrame menus. + * + * @param af + * @param alorders + */ + protected void addSortByMenuItems(AlignFrame af, + List alorders) + { + // update orders + if (alorders.size() == 1) + { + af.addSortByOrderMenuItem(WebServiceName + " Ordering", + alorders.get(0)); } else { - System.out.println("MERGE WITH OLD FRAME"); - // TODO: modify alignment in original frame, replacing old for new - // alignment using the commands.EditCommand model to ensure the update can - // be undone + // construct a non-redundant ordering set + List names = new ArrayList(); + for (int i = 0, l = alorders.size(); i < l; i++) + { + String orderName = " Region " + i; + int j = i + 1; + + while (j < l) + { + if (alorders.get(i).equals(alorders.get(j))) + { + alorders.remove(j); + l--; + orderName += "," + j; + } + else + { + j++; + } + } + + if (i == 0 && j == 1) + { + names.add(""); + } + else + { + names.add(orderName); + } + } + for (int i = 0, l = alorders.size(); i < l; i++) + { + af.addSortByOrderMenuItem(WebServiceName + (names.get(i)) + + " Ordering", alorders.get(i)); + } } } diff --git a/src/jalview/ws/rest/RestServiceDescription.java b/src/jalview/ws/rest/RestServiceDescription.java index 6f304a9..601ebd3 100644 --- a/src/jalview/ws/rest/RestServiceDescription.java +++ b/src/jalview/ws/rest/RestServiceDescription.java @@ -87,7 +87,8 @@ public class RestServiceDescription boolean diff = (gapCharacter != other.gapCharacter); diff |= vseparable != other.vseparable; diff |= hseparable != other.hseparable; - diff |= !(urlSuffix.equals(other.urlSuffix)); + diff |= !(urlSuffix == null && other.urlSuffix == null || (urlSuffix != null + && other.urlSuffix != null && urlSuffix.equals(other.urlSuffix))); // TODO - robust diff that includes constants and reordering of URL // diff |= !(postUrl.equals(other.postUrl)); // diff |= !inputParams.equals(other.inputParams); @@ -369,7 +370,9 @@ public class RestServiceDescription { int seplen = separator.length(); if (list == null || list.equals("") || list.equals(separator)) + { return null; + } java.util.ArrayList jv = new ArrayList(); int cp = 0, pos, escape; boolean wasescaped = false, wasquoted = false; @@ -384,7 +387,6 @@ public class RestServiceDescription jv.set(jv.size() - 1, lstitem = lstitem + separator + list.substring(cp, pos + escape)); - } else { @@ -392,15 +394,9 @@ public class RestServiceDescription } cp = pos + seplen; wasescaped = escape == -1; - if (!wasescaped) - { - // last separator may be in an unmatched quote - if (java.util.regex.Pattern.matches("('[^']*')*[^']*'", lstitem)) - { - wasquoted = true; - } - } - + // last separator may be in an unmatched quote + wasquoted = (java.util.regex.Pattern.matches(".*='[^']*(?!')", + lstitem)); } if (cp < list.length()) { diff --git a/test/jalview/analysis/AAFrequencyTest.java b/test/jalview/analysis/AAFrequencyTest.java new file mode 100644 index 0000000..1c30c79 --- /dev/null +++ b/test/jalview/analysis/AAFrequencyTest.java @@ -0,0 +1,115 @@ +package jalview.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import java.util.Hashtable; + +import org.junit.Test; + +public class AAFrequencyTest +{ + private static final String C = AAFrequency.MAXCOUNT; + + private static final String R = AAFrequency.MAXRESIDUE; + + private static final String G = AAFrequency.PID_GAPS; + + private static final String N = AAFrequency.PID_NOGAPS; + + private static final String P = AAFrequency.PROFILE; + + @Test + public void testCalculate_noProfile() + { + SequenceI seq1 = new Sequence("Seq1", "CAGT"); + SequenceI seq2 = new Sequence("Seq2", "CACT"); + SequenceI seq3 = new Sequence("Seq3", "C--G"); + SequenceI seq4 = new Sequence("Seq4", "CA-t"); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3, seq4 }; + Hashtable[] result = new Hashtable[seq1.getLength()]; + + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false); + Hashtable col = result[0]; + assertEquals(100f, (Float) col.get(G), 0.0001f); + assertEquals(100f, (Float) col.get(N), 0.0001f); + assertEquals(4, col.get(C)); + assertEquals("C", col.get(R)); + assertNull(col.get(P)); + col = result[1]; + assertEquals(75f, (Float) col.get(G), 0.0001f); + assertEquals(100f, (Float) col.get(N), 0.0001f); + assertEquals(3, col.get(C)); + assertEquals("A", col.get(R)); + col = result[2]; + assertEquals(0f, (Float) col.get(G), 0.0001f); + assertEquals(0f, (Float) col.get(N), 0.0001f); + assertEquals(0, col.get(C)); + assertEquals("-", col.get(R)); + col = result[3]; + assertEquals(75f, (Float) col.get(G), 0.0001f); + assertEquals(75f, (Float) col.get(N), 0.0001f); + assertEquals(3, col.get(C)); + assertEquals("T", col.get(R)); + } + + @Test + public void testCalculate_withProfile() + { + SequenceI seq1 = new Sequence("Seq1", "CAGT"); + SequenceI seq2 = new Sequence("Seq2", "CACT"); + SequenceI seq3 = new Sequence("Seq3", "C--G"); + SequenceI seq4 = new Sequence("Seq4", "CA-t"); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3, seq4 }; + Hashtable[] result = new Hashtable[seq1.getLength()]; + + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true); + int[][] profile = (int[][]) result[0].get(P); + assertEquals(4, profile[0]['C']); + assertEquals(4, profile[1][0]); // no of seqs + assertEquals(4, profile[1][1]); // nongapped in column + + profile = (int[][]) result[1].get(P); + assertEquals(3, profile[0]['A']); + assertEquals(4, profile[1][0]); + assertEquals(3, profile[1][1]); + + profile = (int[][]) result[2].get(P); + assertEquals(1, profile[0]['G']); + assertEquals(1, profile[0]['C']); + assertEquals(4, profile[1][0]); + assertEquals(2, profile[1][1]); + + profile = (int[][]) result[3].get(P); + assertEquals(3, profile[0]['T']); + assertEquals(1, profile[0]['G']); + assertEquals(4, profile[1][0]); + assertEquals(4, profile[1][1]); + } + + @Test + public void testCalculate_withProfileTiming() + { + SequenceI seq1 = new Sequence("Seq1", "CAGT"); + SequenceI seq2 = new Sequence("Seq2", "CACT"); + SequenceI seq3 = new Sequence("Seq3", "C--G"); + SequenceI seq4 = new Sequence("Seq4", "CA-t"); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3, seq4 }; + Hashtable[] result = new Hashtable[seq1.getLength()]; + + // ensure class loaded and initialized + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true); + int reps = 100000; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + { + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true); + } + System.out.println(System.currentTimeMillis() - start); + } +} diff --git a/test/jalview/analysis/AlignmentUtilsTests.java b/test/jalview/analysis/AlignmentUtilsTests.java index 18b4252..2711a36 100644 --- a/test/jalview/analysis/AlignmentUtilsTests.java +++ b/test/jalview/analysis/AlignmentUtilsTests.java @@ -20,19 +20,65 @@ */ package jalview.analysis; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; - -import org.junit.Test; - +import jalview.analysis.AlignmentUtils.MappingResult; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; +import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; +import jalview.util.MapList; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.Test; public class AlignmentUtilsTests { + // @formatter:off + private static final String TEST_DATA = + "# STOCKHOLM 1.0\n" + + "#=GS D.melanogaster.1 AC AY119185.1/838-902\n" + + "#=GS D.melanogaster.2 AC AC092237.1/57223-57161\n" + + "#=GS D.melanogaster.3 AC AY060611.1/560-627\n" + + "D.melanogaster.1 G.AGCC.CU...AUGAUCGA\n" + + "#=GR D.melanogaster.1 SS ................((((\n" + + "D.melanogaster.2 C.AUUCAACU.UAUGAGGAU\n" + + "#=GR D.melanogaster.2 SS ................((((\n" + + "D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" + + "#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" + + "//"; + + private static final String AA_SEQS_1 = + ">Seq1Name\n" + + "K-QY--L\n" + + ">Seq2Name\n" + + "-R-FP-W-\n"; + + private static final String CDNA_SEQS_1 = + ">Seq1Name\n" + + "AC-GG--CUC-CAA-CT\n" + + ">Seq2Name\n" + + "-CG-TTA--ACG---AAGT\n"; + + private static final String CDNA_SEQS_2 = + ">Seq1Name\n" + + "GCTCGUCGTACT\n" + + ">Seq2Name\n" + + "GGGTCAGGCAGT\n"; + // @formatter:on + public static Sequence ts=new Sequence("short","ASDASDASDASDASDASDASDASDASDASDASDASDASD"); + @Test public void testExpandFlanks() { @@ -55,6 +101,471 @@ public class AlignmentUtilsTests assertTrue("Flanking sequence not the same as original dataset sequence.\n"+ung+"\n"+sq.getDatasetSequence().getSequenceAsString(),ung.equalsIgnoreCase(sq.getDatasetSequence().getSequenceAsString())); } } + } } + + /** + * Test method that returns a map of lists of sequences by sequence name. + * + * @throws IOException + */ + @Test + public void testGetSequencesByName() throws IOException + { + final String data = ">Seq1Name\nKQYL\n" + ">Seq2Name\nRFPW\n" + + ">Seq1Name\nABCD\n"; + AlignmentI al = loadAlignment(data, "FASTA"); + Map> map = AlignmentUtils + .getSequencesByName(al); + assertEquals(2, map.keySet().size()); + assertEquals(2, map.get("Seq1Name").size()); + assertEquals("KQYL", map.get("Seq1Name").get(0).getSequenceAsString()); + assertEquals("ABCD", map.get("Seq1Name").get(1).getSequenceAsString()); + assertEquals(1, map.get("Seq2Name").size()); + assertEquals("RFPW", map.get("Seq2Name").get(0).getSequenceAsString()); + } + /** + * Helper method to load an alignment and ensure dataset sequences are set up. + * + * @param data + * @param format TODO + * @return + * @throws IOException + */ + protected AlignmentI loadAlignment(final String data, String format) throws IOException + { + Alignment a = new FormatAdapter().readFile(data, + AppletFormatAdapter.PASTE, format); + a.setDataset(null); + return a; + } + /** + * Test mapping of protein to cDNA. + * + * @throws IOException + */ + @Test + public void testMapProteinToCdna() throws IOException + { + // protein: Human + Mouse, 3 residues + AlignmentI protein = loadAlignment( + ">Human\nKQY\n>Mouse\nAFP\n>Worm\nRST\n", + "FASTA"); + // cDNA: Mouse, Human, Mouse, 9 bases + // @formatter:off + String dnaData = + ">Mouse\nGAAATCCAG\n" + + ">Human\nTTCGATTAC\n" + + ">Mouse\nGTCGTTTGC\n" + + ">Mouse\nGTCGTTTGCgac\n" + // not mapped - wrong length + ">Fly\nGTCGTTTGC\n"; // not mapped - no name match + // @formatter:on + AlignmentI cdna1 = loadAlignment( + dnaData, + "FASTA"); + MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna1); + assertEquals(mapped, MappingResult.Mapped); + + /* + * Check two mappings (one for Mouse, one for Human) + */ + assertEquals(2, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); + + /* + * Inspect mapping for Human protein + */ + AlignedCodonFrame humanMapping = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); + assertEquals(1, humanMapping.getdnaSeqs().length); + assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(), + humanMapping.getdnaSeqs()[0]); + Mapping[] protMappings = humanMapping.getProtMappings(); + assertEquals(1, protMappings.length); + MapList mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + /* + * Inspect mappings for Mouse protein + */ + AlignedCodonFrame mouseMapping1 = protein.getCodonFrame( + protein.getSequenceAt(1)).get(0); + assertEquals(2, mouseMapping1.getdnaSeqs().length); + assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(), + mouseMapping1.getdnaSeqs()[0]); + assertEquals(cdna1.getSequenceAt(2).getDatasetSequence(), + mouseMapping1.getdnaSeqs()[1]); + protMappings = mouseMapping1.getProtMappings(); + assertEquals(2, protMappings.length); + for (int i = 0; i < 2; i++) + { + mapList = protMappings[i].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + } + } + + /** + * Test mapping of protein to cDNA which may include start and/or stop codons. + * + * @throws IOException + */ + @Test + public void testMapProteinToCdna_stopStartCodons() throws IOException + { + // protein: Human + Mouse, 3 residues + AlignmentI protein = loadAlignment( + ">Human\nKQY\n>Mouse\nAFP\n>Worm\nRST\n", "FASTA"); + // @formatter:off + String dnaData = + ">Mouse\natgGAAATCCAG\n" + // Mouse with start codon + ">Human\nTTCGATtactaa\n" + // Human with stop codon TAA + ">Mouse\nGTCGTTTGctaG\n" + // Mouse with stop codon TAG + ">Human\nGTCGTTTgctGa\n" + // Human with stop codon TGA + ">Mouse\nATGGTCGTTTGCtag\n"; // Mouse with start and stop codons + // @formatter:on + AlignmentI cdna1 = loadAlignment( + dnaData, + "FASTA"); + MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna1); + assertEquals(mapped, MappingResult.Mapped); + + /* + * Check two mappings (one for Mouse, one for Human) + */ + assertEquals(2, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); + + /* + * Inspect mapping for Human protein - should map to 2nd and 4th cDNA seqs + */ + AlignedCodonFrame humanMapping = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); + assertEquals(2, humanMapping.getdnaSeqs().length); + assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(), + humanMapping.getdnaSeqs()[0]); + assertEquals(cdna1.getSequenceAt(3).getDatasetSequence(), + humanMapping.getdnaSeqs()[1]); + Mapping[] protMappings = humanMapping.getProtMappings(); + // two mappings, both to cDNA with stop codon + assertEquals(2, protMappings.length); + + MapList mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + mapList = protMappings[1].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + /* + * Inspect mapping for Mouse protein - should map to 1st/3rd/5th cDNA seqs + */ + AlignedCodonFrame mouseMapping = protein.getCodonFrame( + protein.getSequenceAt(1)).get(0); + assertEquals(3, mouseMapping.getdnaSeqs().length); + assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(), + mouseMapping.getdnaSeqs()[0]); + assertEquals(cdna1.getSequenceAt(2).getDatasetSequence(), + mouseMapping.getdnaSeqs()[1]); + assertEquals(cdna1.getSequenceAt(4).getDatasetSequence(), + mouseMapping.getdnaSeqs()[2]); + + // three mappings + protMappings = mouseMapping.getProtMappings(); + assertEquals(3, protMappings.length); + + // first mapping to cDNA with start codon + mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 4, 12 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + // second mapping to cDNA with stop codon + mapList = protMappings[1].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + // third mapping to cDNA with start and stop codon + mapList = protMappings[2].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 4, 12 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + } + + /** + * Test for the alignSequenceAs method that takes two sequences and a mapping. + */ + @Test + public void testAlignSequenceAs_withMapping_noIntrons() + { + MapList map = new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1); + + /* + * No existing gaps in dna: + */ + checkAlignSequenceAs("GGGAAA", "-A-L-", false, false, map, + "---GGG---AAA"); + + /* + * Now introduce gaps in dna but ignore them when realigning. + */ + checkAlignSequenceAs("-G-G-G-A-A-A-", "-A-L-", false, false, map, + "---GGG---AAA"); + + /* + * Now include gaps in dna when realigning. First retaining 'mapped' gaps + * only, i.e. those within the exon region. + */ + checkAlignSequenceAs("-G-G--G-A--A-A-", "-A-L-", true, false, map, + "---G-G--G---A--A-A"); + + /* + * Include all gaps in dna when realigning (within and without the exon + * region). The leading gap, and the gaps between codons, are subsumed by + * the protein alignment gap. + */ + checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", true, true, map, + "---G-GG---AA-A-"); + + /* + * Include only unmapped gaps in dna when realigning (outside the exon + * region). The leading gap, and the gaps between codons, are subsumed by + * the protein alignment gap. + */ + checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", false, true, map, + "---GGG---AAA-"); + } + + /** + * Test for the alignSequenceAs method that takes two sequences and a mapping. + */ + @Test + public void testAlignSequenceAs_withMapping_withIntrons() + { + /* + * Exons at codon 2 (AAA) and 4 (TTT) + */ + MapList map = new MapList(new int[] + { 4, 6, 10, 12 }, new int[] + { 1, 2 }, 3, 1); + + /* + * Simple case: no gaps in dna + */ + checkAlignSequenceAs("GGGAAACCCTTTGGG", "--A-L-", false, false, map, + "GGG---AAACCCTTTGGG"); + + /* + * Add gaps to dna - but ignore when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---AC-CC-T-TT-GG-G-", "--A-L-", + false, false, map, "GGG---AAACCCTTTGGG"); + + /* + * Add gaps to dna - include within exons only when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + true, false, map, "GGG---A--A---ACCCT-TTGGG"); + + /* + * Include gaps outside exons only when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + false, true, map, "-G-G-GAAAC-CCTTT-GG-G-"); + + /* + * Include gaps following first intron if we are 'preserving mapped gaps' + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-"); + + /* + * Include all gaps in dna when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-"); + } + + /** + * Test for the case where not all of the protein sequence is mapped to cDNA. + */ + @Test + public void testAlignSequenceAs_withMapping_withUnmappedProtein() + { + + /* + * Exons at codon 2 (AAA) and 4 (TTT) mapped to A and P + */ + final MapList map = new MapList(new int[] + { 4, 6, 10, 12 }, new int[] + { 1, 1, 3, 3 }, 3, 1); + + + /* + * Expect alignment does nothing (aborts realignment). Change this test + * first if different behaviour wanted. + */ + checkAlignSequenceAs("GGGAAACCCTTTGGG", "-A-L-P-", false, + false, map, "GGGAAACCCTTTGGG"); + } + + /** + * Helper method that performs and verifies the method under test. + * + * @param dnaSeq + * @param proteinSeq + * @param preserveMappedGaps + * @param preserveUnmappedGaps + * @param map + * @param expected + */ + protected void checkAlignSequenceAs(final String dnaSeq, + final String proteinSeq, final boolean preserveMappedGaps, + final boolean preserveUnmappedGaps, MapList map, + final String expected) + { + SequenceI dna = new Sequence("Seq1", dnaSeq); + dna.createDatasetSequence(); + SequenceI protein = new Sequence("Seq1", proteinSeq); + protein.createDatasetSequence(); + AlignedCodonFrame acf = new AlignedCodonFrame(); + acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map); + + AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', + preserveMappedGaps, preserveUnmappedGaps); + assertEquals(expected, dna.getSequenceAsString()); } + + /** + * Test for the alignSequenceAs method where we preserve gaps in introns only. + */ + @Test + public void testAlignSequenceAs_keepIntronGapsOnly() + { + + /* + * Intron GGGAAA followed by exon CCCTTT + */ + MapList map = new MapList(new int[] + { 7, 12 }, new int[] + { 1, 2 }, 3, 1); + + checkAlignSequenceAs("GG-G-AA-A-C-CC-T-TT", "AL", + false, true, map, "GG-G-AA-ACCCTTT"); + } + + /** + * Test for the method that generates an aligned translated sequence from one + * mapping. + */ + @Test + public void testGetAlignedTranslation_dnaLikeProtein() + { + // dna alignment will be replaced + SequenceI dna = new Sequence("Seq1", "T-G-CC-A--T-TAC-CAG-"); + dna.createDatasetSequence(); + // protein alignment will be 'applied' to dna + SequenceI protein = new Sequence("Seq1", "-CH-Y--Q-"); + protein.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + AlignedCodonFrame acf = new AlignedCodonFrame(); + acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map); + + final SequenceI aligned = AlignmentUtils + .getAlignedTranslation(protein, '-', acf); + assertEquals("---TGCCAT---TAC------CAG---", aligned.getSequenceAsString()); + assertSame(aligned.getDatasetSequence(), dna.getDatasetSequence()); + } + + /** + * Test the method that realigns protein to match mapped codon alignment. + */ + @Test + public void testAlignProteinAsDna() + { + // seq1 codons are [1,2,3] [4,5,6] [7,8,9] [10,11,12] + SequenceI dna1 = new Sequence("Seq1", "TGCCATTACCAG-"); + // seq2 codons are [1,3,4] [5,6,7] [8,9,10] [11,12,13] + SequenceI dna2 = new Sequence("Seq2", "T-GCCATTACCAG"); + // seq3 codons are [1,2,3] [4,5,7] [8,9,10] [11,12,13] + SequenceI dna3 = new Sequence("Seq3", "TGCCA-TTACCAG"); + AlignmentI dna = new Alignment(new SequenceI[] + { dna1, dna2, dna3 }); + dna.setDataset(null); + + // protein alignment will be realigned like dna + SequenceI prot1 = new Sequence("Seq1", "CHYQ"); + SequenceI prot2 = new Sequence("Seq2", "CHYQ"); + SequenceI prot3 = new Sequence("Seq3", "CHYQ"); + AlignmentI protein = new Alignment(new SequenceI[] + { prot1, prot2, prot3 }); + protein.setDataset(null); + + MapList map = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + AlignedCodonFrame acf = new AlignedCodonFrame(); + acf.addMap(dna1.getDatasetSequence(), prot1.getDatasetSequence(), map); + acf.addMap(dna2.getDatasetSequence(), prot2.getDatasetSequence(), map); + acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map); + protein.setCodonFrames(Collections.singleton(acf)); + + /* + * Translated codon order is [1,2,3] [1,3,4] [4,5,6] [4,5,7] [5,6,7] [7,8,9] + * [8,9,10] [10,11,12] [11,12,13] + */ + AlignmentUtils.alignProteinAsDna(protein, dna); + assertEquals("C-H--Y-Q-", prot1.getSequenceAsString()); + assertEquals("-C--H-Y-Q", prot2.getSequenceAsString()); + assertEquals("C--H--Y-Q", prot3.getSequenceAsString()); + } + } diff --git a/test/jalview/analysis/DnaAlignmentGenerator.java b/test/jalview/analysis/DnaAlignmentGenerator.java new file mode 100644 index 0000000..1b8964f --- /dev/null +++ b/test/jalview/analysis/DnaAlignmentGenerator.java @@ -0,0 +1,253 @@ +package jalview.analysis; + +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.io.FastaFile; + +import java.util.Arrays; +import java.util.Random; + +/** + * Generates, and outputs in Fasta format, a random DNA alignment for given + * sequence length and count. Will regenerate the same alignment each time if + * the same random seed is used (so may be used for reproducible unit tests). + * Not guaranteed to reproduce the same results between versions, as the rules + * may get tweaked to produce more 'realistic' results. + * + * Arguments: + *

    + *
  • length (number of bases in each sequence)
  • + *
  • height (number of sequences)
  • + *
  • a whole number random seed
  • + *
  • percentage of gaps to include (0-100)
  • + *
  • percentage chance of variation of each position (0-100)
  • + *
+ * + * @author gmcarstairs + * + */ +public class DnaAlignmentGenerator +{ + private static final char GAP = '-'; + + private static final char ZERO = '0'; + + private static final char[] BASES = new char[] + { 'G', 'T', 'C', 'A' }; + + private Random random; + + /** + * Outputs a DNA 'alignment' where each position is a random choice from + * 'GTCA-'. + * + * @param args + */ + public static void main(String[] args) + { + if (args.length != 5) + { + usage(); + return; + } + int width = Integer.parseInt(args[0]); + int height = Integer.parseInt(args[1]); + long randomSeed = Long.valueOf(args[2]); + int gapPercentage = Integer.valueOf(args[3]); + int changePercentage = Integer.valueOf(args[4]); + AlignmentI al = new DnaAlignmentGenerator().generate(width, height, + randomSeed, gapPercentage, changePercentage); + + System.out.println("; " + height + " sequences of " + width + + " bases with " + gapPercentage + "% gaps and " + + changePercentage + "% mutations (random seed = " + randomSeed + + ")"); + System.out.println(new FastaFile().print(al.getSequencesArray())); + } + + /** + * Print parameter help. + */ + private static void usage() + { + System.out.println("Usage:"); + System.out.println("arg0: number of (non-gap) bases per sequence"); + System.out.println("arg1: number sequences"); + System.out + .println("arg2: an integer as random seed (same seed = same results)"); + System.out.println("arg3: percentage of gaps to (randomly) generate"); + System.out + .println("arg4: percentage of 'mutations' to (randomly) generate"); + System.out.println("Example: DnaAlignmentGenerator 12 15 387 10 5"); + System.out + .println("- 15 sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387"); + + } + + /** + * Default constructor + */ + public DnaAlignmentGenerator() + { + + } + + /** + * Outputs a DNA 'alignment' of given width and height, where each position is + * a random choice from 'GTCA-'. + * + * @param width + * @param height + * @param randomSeed + * @param changePercentage + * @param gapPercentage + */ + public AlignmentI generate(int width, int height, long randomSeed, + int gapPercentage, int changePercentage) + { + SequenceI[] seqs = new SequenceI[height]; + random = new Random(randomSeed); + seqs[0] = generateSequence(1, width, gapPercentage); + for (int seqno = 1; seqno < height; seqno++) + { + seqs[seqno] = generateAnotherSequence(seqs[0].getSequence(), + seqno + 1, width, changePercentage); + } + AlignmentI al = new Alignment(seqs); + return al; + } + + /** + * Outputs a DNA 'sequence' of given length, with some random gaps included. + * + * @param seqno + * @param length + * @param gapPercentage + */ + private SequenceI generateSequence(int seqno, int length, + int gapPercentage) + { + StringBuilder seq = new StringBuilder(length); + + /* + * Loop till we've added 'length' bases (excluding gaps) + */ + for (int count = 0; count < length;) + { + boolean addGap = random.nextInt(100) < gapPercentage; + char c = addGap ? GAP : BASES[random.nextInt(Integer.MAX_VALUE) % 4]; + seq.append(c); + if (!addGap) + { + count++; + } + } + final String seqName = "SEQ" + seqno; + final String seqString = seq.toString(); + SequenceI sq = new Sequence(seqName, seqString); + sq.createDatasetSequence(); + return sq; + } + + /** + * Generate a sequence approximately aligned to the first one. + * + * @param ds + * @param seqno + * @param width + * number of bases + * @param changePercentage + * @return + */ + private SequenceI generateAnotherSequence(char[] ds, int seqno, + int width, int changePercentage) + { + int length = ds.length; + char[] seq = new char[length]; + Arrays.fill(seq, ZERO); + int gapsWanted = length - width; + int gapsAdded = 0; + + /* + * First 'randomly' mimic gaps in model sequence. + */ + for (int pos = 0; pos < length; pos++) + { + if (ds[pos] == GAP) + { + /* + * Add a gap at the same position with changePercentage likelihood + */ + seq[pos] = randomCharacter(GAP, changePercentage); + if (seq[pos] == GAP) + { + gapsAdded++; + } + } + } + + /* + * Next scatter any remaining gaps (if any) at random. This gives an even + * distribution. + */ + while (gapsAdded < gapsWanted) + { + boolean added = false; + while (!added) + { + int pos = random.nextInt(length); + if (seq[pos] != GAP) + { + seq[pos] = GAP; + added = true; + gapsAdded++; + } + } + } + + /* + * Finally fill in the rest with randomly mutated bases. + */ + for (int pos = 0; pos < length; pos++) + { + if (seq[pos] == ZERO) + { + char c = randomCharacter(ds[pos], changePercentage); + seq[pos] = c; + } + } + final String seqName = "SEQ" + seqno; + final String seqString = new String(seq); + SequenceI sq = new Sequence(seqName, seqString); + sq.createDatasetSequence(); + return sq; + } + + /** + * Returns a random character that is changePercentage% likely to match the + * given type (as base or gap). + * + * @param changePercentage + * + * @param c + * @return + */ + private char randomCharacter(char c, int changePercentage) + { + final boolean mutation = random.nextInt(100) < changePercentage; + + if (!mutation) + { + return c; + } + + char newchar = c; + while (newchar == c) + { + newchar = BASES[random.nextInt(Integer.MAX_VALUE) % 4]; + } + return newchar; + } +} diff --git a/test/jalview/analysis/DnaTest.java b/test/jalview/analysis/DnaTest.java new file mode 100644 index 0000000..01ed183 --- /dev/null +++ b/test/jalview/analysis/DnaTest.java @@ -0,0 +1,445 @@ +package jalview.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import jalview.api.AlignViewportI; +import jalview.datamodel.AlignedCodon; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignViewport; +import jalview.io.FormatAdapter; + +import java.io.IOException; + +import org.junit.Test; + +public class DnaTest +{ + // @formatter:off + // AA encoding codons as ordered on the Jalview help page Amino Acid Table + private static String fasta = ">B\n" + "GCT" + "GCC" + "GCA" + "GCG" + + "TGT" + "TGC" + "GAT" + "GAC" + "GAA" + "GAG" + "TTT" + "TTC" + + "GGT" + "GGC" + "GGA" + "GGG" + "CAT" + "CAC" + "ATT" + "ATC" + + "ATA" + "AAA" + "AAG" + "TTG" + "TTA" + "CTT" + "CTC" + "CTA" + + "CTG" + "ATG" + "AAT" + "AAC" + "CCT" + "CCC" + "CCA" + "CCG" + + "CAA" + "CAG" + "CGT" + "CGC" + "CGA" + "CGG" + "AGA" + "AGG" + + "TCT" + "TCC" + "TCA" + "TCG" + "AGT" + "AGC" + "ACT" + "ACC" + + "ACA" + "ACG" + "GTT" + "GTC" + "GTA" + "GTG" + "TGG" + "TAT" + + "TAC" + "TAA" + "TAG" + "TGA"; + + private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n" + + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n" + + ">gi|27804621|gb|AY178912.1|/1-259\n" + + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n" + + ">gi|27804623|gb|AY178913.1|/1-259\n" + + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" + + ">gi|27804627|gb|AY178915.1|/1-260\n" + + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n" + + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n" + + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n" + + ">gi|27804631|gb|AY178917.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n" + + ">gi|27804635|gb|AY178919.1|/1-261\n" + + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n" + + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n" + + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" + + ">gi|27804641|gb|AY178922.1|/1-261\n" + + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n" + + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n" + + ">gi|27804647|gb|AY178925.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n" + + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n" + + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n" + + ">gi|27804649|gb|AY178926.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n" + + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n" + + ">gi|27804653|gb|AY178928.1|/1-261\n" + + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" + + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n" + + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n" + + ">gi|27804659|gb|AY178931.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n"; + // @formatter:on + + /** + * Corner case for this test is the presence of codons after codons that were + * not translated. + * + * @throws IOException + */ + @Test + public void testTranslateCdna_withUntranslatableCodons() + throws IOException + { + AlignmentI alf = new FormatAdapter().readFile( + JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE, + "FASTA"); + ColumnSelection cs = new ColumnSelection(); + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, new int[] + { 0, alf.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + assertNotNull("Couldn't do a full width translation of test data.", + translated); + } + + /** + * Test variant in which 15 column blocks at a time are translated (the rest + * hidden). + * + * @throws IOException + */ + @Test + public void testTranslateCdna_withUntranslatableCodonsAndHiddenColumns() + throws IOException + { + AlignmentI alf = new FormatAdapter().readFile( + JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE, + "FASTA"); + int vwidth = 15; + for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth) + { + ColumnSelection cs = new ColumnSelection(); + if (ipos > 0) + { + cs.hideColumns(0, ipos - 1); + } + cs.hideColumns(ipos + vwidth, alf.getWidth()); + int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth()); + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, vcontigs); + AlignmentI transAlf = dna.translateCdna(); + + assertTrue("Translation failed (ipos=" + ipos + + ") No alignment data.", transAlf != null); + assertTrue("Translation failed (ipos=" + ipos + ") Empty alignment.", + transAlf.getHeight() > 0); + assertTrue("Translation failed (ipos=" + ipos + ") Translated " + + transAlf.getHeight() + " sequences from " + alf.getHeight() + + " sequences", alf.getHeight() == transAlf.getHeight()); + } + } + + /** + * Test simple translation to Amino Acids (with STOP codons translated to X). + * + * @throws IOException + */ + @Test + public void testTranslateCdna_simple() throws IOException + { + AlignmentI alf = new FormatAdapter().readFile(fasta, + FormatAdapter.PASTE, "FASTA"); + ColumnSelection cs = new ColumnSelection(); + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, new int[] + { 0, alf.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + String aa = translated.getSequenceAt(0).getSequenceAsString(); + assertEquals( + "AAAACCDDEEFFGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVWYYXXX", + aa); + } + + /** + * Test translation excluding hidden columns. + * + * @throws IOException + */ + @Test + public void testTranslateCdna_hiddenColumns() throws IOException + { + AlignmentI alf = new FormatAdapter().readFile(fasta, + FormatAdapter.PASTE, "FASTA"); + ColumnSelection cs = new jalview.datamodel.ColumnSelection(); + cs.hideColumns(6, 14); // hide codons 3/4/5 + cs.hideColumns(24, 35); // hide codons 9-12 + cs.hideColumns(177, 191); // hide codons 60-64 + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, new int[] + { 0, alf.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + String aa = translated.getSequenceAt(0).getSequenceAsString(); + assertEquals("AACDDGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVW", aa); + } + + /** + * Use this test to help debug into any cases of interest. + */ + @Test + public void testCompareCodonPos_oneOnly() + { + assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1 + } + + /** + * Tests for method that compares 'alignment' of two codon position triplets. + */ + @Test + public void testCompareCodonPos() + { + /* + * Returns 0 for any null argument + */ + assertEquals(0, Dna.compareCodonPos(new AlignedCodon(1, 2, 3), null)); + assertEquals(0, Dna.compareCodonPos(null, new AlignedCodon(1, 2, 3))); + + /* + * Work through 27 combinations. First 9 cases where first position matches. + */ + assertMatches("AAA", "GGG"); // 2 and 3 match + assertFollows("AA-A", "GGG"); // 2 matches, 3 shifted seq1 + assertPrecedes("AAA", "GG-G"); // 2 matches, 3 shifted seq2 + assertFollows("A-AA", "GG-G"); // 2 shifted seq1, 3 matches + assertFollows("A-A-A", "GG-G"); // 2 shifted seq1, 3 shifted seq1 + assertPrecedes("A-AA", "GG--G"); // 2 shifted seq1, 3 shifted seq2 + assertPrecedes("AA-A", "G-GG"); // 2 shifted seq2, 3 matches + assertFollows("AA--A", "G-GG"); // 2 shifted seq2, 3 shifted seq1 + assertPrecedes("AAA", "G-GG"); // 2 shifted seq2, 3 shifted seq2 + + /* + * 9 cases where first position is shifted in first sequence. + */ + assertFollows("-AAA", "G-GG"); // 2 and 3 match + assertFollows("-AA-A", "G-GG"); // 2 matches, 3 shifted seq1 + // 'enclosing' case: pick first to start precedes + assertFollows("-AAA", "G-G-G"); // 2 matches, 3 shifted seq2 + assertFollows("-A-AA", "G-G-G"); // 2 shifted seq1, 3 matches + assertFollows("-A-A-A", "G-G-G"); // 2 shifted seq1, 3 shifted seq1 + // 'enclosing' case: pick first to start precedes + assertFollows("-A-AA", "G-G--G"); // 2 shifted seq1, 3 shifted seq2 + assertFollows("-AA-A", "G--GG"); // 2 shifted seq2, 3 matches + assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1 + assertPrecedes("-AAA", "G--GG"); // 2 shifted seq2, 3 shifted seq2 + + /* + * 9 cases where first position is shifted in second sequence. + */ + assertPrecedes("A-AA", "-GGG"); // 2 and 3 match + assertPrecedes("A-A-A", "-GGG"); // 2 matches, 3 shifted seq1 + assertPrecedes("A-AA", "-GG-G"); // 2 matches, 3 shifted seq2 + assertPrecedes("A--AA", "-GG-G"); // 2 shifted seq1, 3 matches + // 'enclosing' case with middle base deciding: + assertFollows("A--AA", "-GGG"); // 2 shifted seq1, 3 shifted seq1 + assertPrecedes("A--AA", "-GG--G"); // 2 shifted seq1, 3 shifted seq2 + assertPrecedes("AA-A", "-GGG"); // 2 shifted seq2, 3 matches + assertPrecedes("AA--A", "-GGG"); // 2 shifted seq2, 3 shifted seq1 + assertPrecedes("AAA", "-GGG"); // 2 shifted seq2, 3 shifted seq2 + } + + /** + * This test generates a random cDNA alignment and its translation, then + * reorders the cDNA and retranslates, and verifies that the translations are + * the same (apart from ordering). + */ + @Test + public void testTranslateCdna_sequenceOrderIndependent() + { + /* + * Generate cDNA - 8 sequences of 12 bases each. + */ + AlignmentI cdna = new DnaAlignmentGenerator().generate(12, 8, 97, 5, 5); + ColumnSelection cs = new ColumnSelection(); + AlignViewportI av = new AlignViewport(cdna, cs); + Dna dna = new Dna(av, new int[] + { 0, cdna.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + + /* + * Jumble the cDNA sequences and translate. + */ + SequenceI[] sorted = new SequenceI[cdna.getHeight()]; + final int[] jumbler = new int[] + { 6, 7, 3, 4, 2, 0, 1, 5 }; + int seqNo = 0; + for (int i : jumbler) + { + sorted[seqNo++] = cdna.getSequenceAt(i); + } + AlignmentI cdnaReordered = new Alignment(sorted); + av = new AlignViewport(cdnaReordered, cs); + dna = new Dna(av, new int[] + { 0, cdna.getWidth() - 1 }); + AlignmentI translated2 = dna.translateCdna(); + + /* + * Check translated sequences are the same in both alignments. + */ + System.out.println("Original"); + System.out.println(translated.toString()); + System.out.println("Sorted"); + System.out.println(translated2.toString()); + + int sortedSequenceIndex = 0; + for (int originalSequenceIndex : jumbler) + { + final String translation1 = translated.getSequenceAt( + originalSequenceIndex).getSequenceAsString(); + final String translation2 = translated2.getSequenceAt(sortedSequenceIndex) + .getSequenceAsString(); + assertEquals(translation2, translation1); + sortedSequenceIndex++; + } + } + + /** + * Test that all the cases in testCompareCodonPos have a 'symmetric' + * comparison (without checking the actual comparison result). + */ + @Test + public void testCompareCodonPos_isSymmetric() + { + assertSymmetric("AAA", "GGG"); + assertSymmetric("AA-A", "GGG"); + assertSymmetric("AAA", "GG-G"); + assertSymmetric("A-AA", "GG-G"); + assertSymmetric("A-A-A", "GG-G"); + assertSymmetric("A-AA", "GG--G"); + assertSymmetric("AA-A", "G-GG"); + assertSymmetric("AA--A", "G-GG"); + assertSymmetric("AAA", "G-GG"); + assertSymmetric("-AAA", "G-GG"); + assertSymmetric("-AA-A", "G-GG"); + assertSymmetric("-AAA", "G-G-G"); + assertSymmetric("-A-AA", "G-G-G"); + assertSymmetric("-A-A-A", "G-G-G"); + assertSymmetric("-A-AA", "G-G--G"); + assertSymmetric("-AA-A", "G--GG"); + assertSymmetric("-AA--A", "G--GG"); + assertSymmetric("-AAA", "G--GG"); + assertSymmetric("A-AA", "-GGG"); + assertSymmetric("A-A-A", "-GGG"); + assertSymmetric("A-AA", "-GG-G"); + assertSymmetric("A--AA", "-GG-G"); + assertSymmetric("A--AA", "-GGG"); + assertSymmetric("A--AA", "-GG--G"); + assertSymmetric("AA-A", "-GGG"); + assertSymmetric("AA--A", "-GGG"); + assertSymmetric("AAA", "-GGG"); + } + + private void assertSymmetric(String codon1, String codon2) + { + assertEquals("Comparison of '" + codon1 + "' and '" + codon2 + + " not symmetric", Integer.signum(compare(codon1, codon2)), + -Integer.signum(compare(codon2, codon1))); + } + + /** + * Assert that the first sequence should map to the same position as the + * second in a translated alignment. Also checks that this is true if the + * order of the codons is reversed. + * + * @param codon1 + * @param codon2 + */ + private void assertMatches(String codon1, String codon2) + { + assertEquals("Expected '" + codon1 + "' matches '" + codon2 + "'", 0, + compare(codon1, codon2)); + assertEquals("Expected '" + codon2 + "' matches '" + codon1 + "'", 0, + compare(codon2, codon1)); + } + + /** + * Assert that the first sequence should precede the second in a translated + * alignment + * + * @param codon1 + * @param codon2 + */ + private void assertPrecedes(String codon1, String codon2) + { + assertEquals("Expected '" + codon1 + "' precedes '" + codon2 + "'", + -1, compare(codon1, codon2)); + } + + /** + * Assert that the first sequence should follow the second in a translated + * alignment + * + * @param codon1 + * @param codon2 + */ + private void assertFollows(String codon1, String codon2) + { + assertEquals("Expected '" + codon1 + "' follows '" + codon2 + "'", 1, + compare(codon1, codon2)); + } + + /** + * Convert two nucleotide strings to base positions and pass to + * Dna.compareCodonPos, return the result. + * + * @param s1 + * @param s2 + * @return + */ + private int compare(String s1, String s2) + { + final AlignedCodon cd1 = convertCodon(s1); + final AlignedCodon cd2 = convertCodon(s2); + System.out.println("K: " + s1 + " " + cd1.toString()); + System.out.println("G: " + s2 + " " + cd2.toString()); + System.out.println(); + return Dna.compareCodonPos(cd1, cd2); + } + + /** + * Convert a string e.g. "-GC-T" to base positions e.g. [1, 2, 4]. The string + * should have exactly 3 non-gap characters, and use '-' for gaps. + * + * @param s + * @return + */ + private AlignedCodon convertCodon(String s) + { + int[] codon = new int[3]; + int i = 0; + for (int j = 0; j < s.length(); j++) + { + if (s.charAt(j) != '-') + { + codon[i++] = j; + } + } + return new AlignedCodon(codon[0], codon[1], codon[2]); + } + + /** + * Weirdly, maybe worth a test to prove the helper method of this test class. + */ + @Test + public void testConvertCodon() + { + assertEquals("[0, 1, 2]", convertCodon("AAA").toString()); + assertEquals("[0, 2, 5]", convertCodon("A-A--A").toString()); + assertEquals("[1, 3, 4]", convertCodon("-A-AA-").toString()); + } +} diff --git a/test/jalview/analysis/DnaTranslation.java b/test/jalview/analysis/DnaTranslation.java deleted file mode 100644 index 708ee21..0000000 --- a/test/jalview/analysis/DnaTranslation.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) - * Copyright (C) 2014 The Jalview Authors - * - * This file is part of Jalview. - * - * Jalview is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 - * of the License, or (at your option) any later version. - * - * Jalview is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jalview. If not, see . - * The Jalview Authors are detailed in the 'AUTHORS' file. - */ -package jalview.analysis; - -import static org.junit.Assert.*; -import jalview.datamodel.ColumnSelection; - -import java.io.IOException; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -public class DnaTranslation -{ - - private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n" - + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n" - + ">gi|27804621|gb|AY178912.1|/1-259\n" - + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n" - + ">gi|27804623|gb|AY178913.1|/1-259\n" - + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" - + ">gi|27804627|gb|AY178915.1|/1-260\n" - + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n" - + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n" - + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n" - + ">gi|27804631|gb|AY178917.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n" - + ">gi|27804635|gb|AY178919.1|/1-261\n" - + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n" - + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n" - + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" - + ">gi|27804641|gb|AY178922.1|/1-261\n" - + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n" - + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n" - + ">gi|27804647|gb|AY178925.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n" - + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n" - + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n" - + ">gi|27804649|gb|AY178926.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n" - + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n" - + ">gi|27804653|gb|AY178928.1|/1-261\n" - + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" - + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n" - + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n" - + ">gi|27804659|gb|AY178931.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n"; - - @Test - public void translationWithUntranslatableCodonsTest() - { - // Corner case for this test is the presence of codons after codons that - // were not translated. - jalview.datamodel.AlignmentI alf = null; - try - { - alf = new jalview.io.FormatAdapter().readFile( - JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE, - "FASTA"); - } catch (IOException x) - { - x.printStackTrace(); - fail("Unexpected IOException (" + x.getMessage() - + ") - check test environment"); - } - { - // full translation - ColumnSelection cs = new jalview.datamodel.ColumnSelection(); - assertNotNull("Couldn't do a full width translation of test data.", - jalview.analysis.Dna.CdnaTranslate( - alf.getSequencesArray(), - cs.getVisibleSequenceStrings(0, alf.getWidth(), - alf.getSequencesArray()), new int[] - { 0, alf.getWidth() - 1 }, alf.getGapCharacter(), - null, alf.getWidth(), null)); - } - int vwidth = 15; // translate in 15 base stretches - for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth) - { - ColumnSelection cs = new jalview.datamodel.ColumnSelection(); - if (ipos > 0) - { - cs.hideColumns(0, ipos - 1); - } - cs.hideColumns(ipos + vwidth, alf.getWidth()); - int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth()); - String[] sel = cs.getVisibleSequenceStrings(0, alf.getWidth(), - alf.getSequencesArray()); - jalview.datamodel.AlignmentI transAlf = jalview.analysis.Dna - .CdnaTranslate(alf.getSequencesArray(), sel, vcontigs, - alf.getGapCharacter(), null, alf.getWidth(), null); - - assertTrue("Translation failed (ipos=" + ipos - + ") No alignment data.", transAlf != null); - assertTrue("Translation failed (ipos=" + ipos + ") Empty algnment.", - transAlf.getHeight() > 0); - assertTrue("Translation failed (ipos=" + ipos + ") Translated " - + transAlf.getHeight() + " sequences from " + alf.getHeight() - + " sequences", alf.getHeight() == transAlf.getHeight()); - } - - } -} diff --git a/test/jalview/analysis/TestAlignSeq.java b/test/jalview/analysis/TestAlignSeq.java index ca4f18d..6f331ff 100644 --- a/test/jalview/analysis/TestAlignSeq.java +++ b/test/jalview/analysis/TestAlignSeq.java @@ -20,7 +20,9 @@ */ package jalview.analysis; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; @@ -74,4 +76,13 @@ public class TestAlignSeq } } + @Test + public void testExtractGaps() + { + assertNull(AlignSeq.extractGaps(null, null)); + assertNull(AlignSeq.extractGaps(". -", null)); + assertNull(AlignSeq.extractGaps(null, "AB-C")); + + assertEquals("ABCD", AlignSeq.extractGaps(" .-", ". -A-B.C D.")); + } } diff --git a/test/jalview/commands/EditCommandTest.java b/test/jalview/commands/EditCommandTest.java index fc821b9..6ea05e6 100644 --- a/test/jalview/commands/EditCommandTest.java +++ b/test/jalview/commands/EditCommandTest.java @@ -1,6 +1,7 @@ package jalview.commands; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; import jalview.commands.EditCommand.Action; import jalview.commands.EditCommand.Edit; import jalview.datamodel.Alignment; @@ -8,6 +9,8 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; +import java.util.Map; + import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -33,9 +36,13 @@ public class EditCommandTest testee = new EditCommand(); seqs = new SequenceI[4]; seqs[0] = new Sequence("seq0", "abcdefghjk"); + seqs[0].setDatasetSequence(new Sequence("seq0ds", "abcdefghjk")); seqs[1] = new Sequence("seq1", "fghjklmnopq"); + seqs[1].setDatasetSequence(new Sequence("seq1ds", "fghjklmnopq")); seqs[2] = new Sequence("seq2", "qrstuvwxyz"); + seqs[2].setDatasetSequence(new Sequence("seq2ds", "qrstuvwxyz")); seqs[3] = new Sequence("seq3", "1234567890"); + seqs[3].setDatasetSequence(new Sequence("seq3ds", "1234567890")); al = new Alignment(seqs); al.setGapCharacter('?'); } @@ -227,6 +234,373 @@ public class EditCommandTest assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString()); assertEquals("1234567890", seqs[3].getSequenceAsString()); seqs[1] = new Sequence("seq1", "fghjZXYnopq"); + } + + /** + * Test that the addEdit command correctly merges insert gap commands when + * possible. + */ + @Test + public void testAddEdit_multipleInsertGap() + { + /* + * 3 insert gap in a row (aka mouse drag right): + */ + Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { seqs[0] }, 1, 1, al); + testee.addEdit(e); + SequenceI edited = new Sequence("seq0", "a?bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 2, 1, al); + testee.addEdit(e); + edited = new Sequence("seq0", "a??bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 3, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction()); + assertEquals(1, testee.getEdit(0).getPosition()); + assertEquals(3, testee.getEdit(0).getNumber()); + + /* + * Add a non-contiguous edit - should not be merged. + */ + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 5, 2, al); + testee.addEdit(e); + assertEquals(2, testee.getSize()); + assertEquals(5, testee.getEdit(1).getPosition()); + assertEquals(2, testee.getEdit(1).getNumber()); + + /* + * Add a Delete after the Insert - should not be merged. + */ + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 6, 2, al); + testee.addEdit(e); + assertEquals(3, testee.getSize()); + assertEquals(Action.DELETE_GAP, testee.getEdit(2).getAction()); + assertEquals(6, testee.getEdit(2).getPosition()); + assertEquals(2, testee.getEdit(2).getNumber()); + } + + /** + * Test that the addEdit command correctly merges delete gap commands when + * possible. + */ + @Test + public void testAddEdit_multipleDeleteGap() + { + /* + * 3 delete gap in a row (aka mouse drag left): + */ + seqs[0].setSequence("a???bcdefghjk"); + Edit e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { seqs[0] }, 4, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + + SequenceI edited = new Sequence("seq0", "a??bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 3, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + + edited = new Sequence("seq0", "a?bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 2, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction()); + assertEquals(2, testee.getEdit(0).getPosition()); + assertEquals(3, testee.getEdit(0).getNumber()); + + /* + * Add a non-contiguous edit - should not be merged. + */ + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 2, 1, al); + testee.addEdit(e); + assertEquals(2, testee.getSize()); + assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction()); + assertEquals(2, testee.getEdit(1).getPosition()); + assertEquals(1, testee.getEdit(1).getNumber()); + + /* + * Add an Insert after the Delete - should not be merged. + */ + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 1, 1, al); + testee.addEdit(e); + assertEquals(3, testee.getSize()); + assertEquals(Action.INSERT_GAP, testee.getEdit(2).getAction()); + assertEquals(1, testee.getEdit(2).getPosition()); + assertEquals(1, testee.getEdit(2).getNumber()); + } + + /** + * Test that the addEdit command correctly handles 'remove gaps' edits for the + * case when they appear contiguous but are acting on different sequences. + * They should not be merged. + */ + @Test + public void testAddEdit_removeAllGaps() + { + seqs[0].setSequence("a???bcdefghjk"); + Edit e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { seqs[0] }, 4, 1, al); + testee.addEdit(e); + + seqs[1].setSequence("f??ghjklmnopq"); + Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { seqs[1] }, 3, 1, al); + testee.addEdit(e2); + assertEquals(2, testee.getSize()); + assertSame(e, testee.getEdit(0)); + assertSame(e2, testee.getEdit(1)); + } + + /** + * Test that the addEdit command correctly merges insert gap commands acting + * on a multi-sequence selection. + */ + @Test + public void testAddEdit_groupInsertGaps() + { + /* + * 2 insert gap in a row (aka mouse drag right), on two sequences: + */ + Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { seqs[0], seqs[1] }, 1, 1, al); + testee.addEdit(e); + SequenceI seq1edited = new Sequence("seq0", "a?bcdefghjk"); + seq1edited.setDatasetSequence(seqs[0].getDatasetSequence()); + SequenceI seq2edited = new Sequence("seq1", "f?ghjklmnopq"); + seq2edited.setDatasetSequence(seqs[1].getDatasetSequence()); + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { seq1edited, seq2edited }, 2, 1, al); + testee.addEdit(e); + + assertEquals(1, testee.getSize()); + assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction()); + assertEquals(1, testee.getEdit(0).getPosition()); + assertEquals(2, testee.getEdit(0).getNumber()); + assertEquals(seqs[0].getDatasetSequence(), testee.getEdit(0) + .getSequences()[0].getDatasetSequence()); + assertEquals(seqs[1].getDatasetSequence(), testee.getEdit(0) + .getSequences()[1].getDatasetSequence()); + } + + /** + * Test for 'undoing' a series of gap insertions. + *
    + *
  • Start: ABCDEF insert 2 at pos 1
  • + *
  • next: A--BCDEF insert 1 at pos 4
  • + *
  • next: A--B-CDEF insert 2 at pos 0
  • + *
  • last: --A--B-CDEF
  • + *
+ */ + @Test + public void testPriorState_multipleInserts() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "--A--B-CDEF"); + SequenceI ds = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-'); + command.addEdit(e); + e = command.new Edit(Action.INSERT_GAP, seqs, 4, 1, '-'); + command.addEdit(e); + e = command.new Edit(Action.INSERT_GAP, seqs, 0, 2, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test for 'undoing' a series of gap deletions. + *
    + *
  • Start: A-B-C delete 1 at pos 1
  • + *
  • Next: AB-C delete 1 at pos 2
  • + *
  • End: ABC
  • + *
+ */ + @Test + public void testPriorState_removeAllGaps() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "ABC"); + SequenceI ds = new Sequence("", "ABC"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'); + command.addEdit(e); + e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("A-B-C", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test for 'undoing' a single delete edit. + */ + @Test + public void testPriorState_singleDelete() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "ABCDEF"); + SequenceI ds = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 2, 2, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("AB--CDEF", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test 'undoing' a single gap insertion edit command. + */ + @Test + public void testPriorState_singleInsert() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "AB---CDEF"); + SequenceI ds = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.INSERT_GAP, seqs, 2, 3, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test that mimics 'remove all gaps' action. This generates delete gap edits + * for contiguous gaps in each sequence separately. + */ + @Test + public void testPriorState_removeGapsMultipleSeqs() + { + EditCommand command = new EditCommand(); + String original1 = "--ABC-DEF"; + String original2 = "FG-HI--J"; + String original3 = "M-NOPQ"; + + /* + * Two edits for the first sequence + */ + SequenceI seq = new Sequence("", "ABC-DEF"); + SequenceI ds1 = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds1); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 2, '-'); + command.addEdit(e); + seq = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds1); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 3, 1, '-'); + command.addEdit(e); + + /* + * Two edits for the second sequence + */ + seq = new Sequence("", "FGHI--J"); + SequenceI ds2 = new Sequence("", "FGHIJ"); + seq.setDatasetSequence(ds2); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-'); + command.addEdit(e); + seq = new Sequence("", "FGHIJ"); + seq.setDatasetSequence(ds2); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-'); + command.addEdit(e); + + /* + * One edit for the third sequence. + */ + seq = new Sequence("", "MNOPQ"); + SequenceI ds3 = new Sequence("", "MNOPQ"); + seq.setDatasetSequence(ds3); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals(original1, unwound.get(ds1).getSequenceAsString()); + assertEquals(original2, unwound.get(ds2).getSequenceAsString()); + assertEquals(original3, unwound.get(ds3).getSequenceAsString()); + } + + /** + * Test that mimics 'remove all gapped columns' action. This generates a + * series Delete Gap edits that each act on all sequences that share a gapped + * column region. + */ + @Test + public void testPriorState_removeGappedCols() + { + EditCommand command = new EditCommand(); + String original1 = "--ABC--DEF"; + String original2 = "-G-HI--J"; + String original3 = "-M-NO--PQ"; + + /* + * First edit deletes the first column. + */ + SequenceI seq1 = new Sequence("", "-ABC--DEF"); + SequenceI ds1 = new Sequence("", "ABCDEF"); + seq1.setDatasetSequence(ds1); + SequenceI seq2 = new Sequence("", "G-HI--J"); + SequenceI ds2 = new Sequence("", "GHIJ"); + seq2.setDatasetSequence(ds2); + SequenceI seq3 = new Sequence("", "M-NO--PQ"); + SequenceI ds3 = new Sequence("", "MNOPQ"); + seq3.setDatasetSequence(ds3); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3 }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 1, '-'); + command.addEdit(e); + + /* + * Second edit deletes what is now columns 4 and 5. + */ + seq1 = new Sequence("", "-ABCDEF"); + seq1.setDatasetSequence(ds1); + seq2 = new Sequence("", "G-HIJ"); + seq2.setDatasetSequence(ds2); + seq3 = new Sequence("", "M-NOPQ"); + seq3.setDatasetSequence(ds3); + seqs = new SequenceI[] + { seq1, seq2, seq3 }; + e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-'); + command.addEdit(e); + Map unwound = command.priorState(false); + assertEquals(original1, unwound.get(ds1).getSequenceAsString()); + assertEquals(original2, unwound.get(ds2).getSequenceAsString()); + assertEquals(original3, unwound.get(ds3).getSequenceAsString()); + assertEquals(ds1, unwound.get(ds1).getDatasetSequence()); + assertEquals(ds2, unwound.get(ds2).getDatasetSequence()); + assertEquals(ds3, unwound.get(ds3).getDatasetSequence()); } } diff --git a/test/jalview/datamodel/AlignedCodonFrameTest.java b/test/jalview/datamodel/AlignedCodonFrameTest.java new file mode 100644 index 0000000..25d0155 --- /dev/null +++ b/test/jalview/datamodel/AlignedCodonFrameTest.java @@ -0,0 +1,112 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import jalview.util.MapList; + +import java.util.Arrays; + +import org.junit.Test; + +public class AlignedCodonFrameTest +{ + + /** + * Test the method that locates the first aligned sequence that has a mapping. + */ + @Test + public void testFindAlignedSequence() + { + AlignmentI cdna = new Alignment(new SequenceI[] + {}); + final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC"); + seq1.createDatasetSequence(); + cdna.addSequence(seq1); + final Sequence seq2 = new Sequence("Seq2", "-TA-GG-GG"); + seq2.createDatasetSequence(); + cdna.addSequence(seq2); + + AlignmentI aa = new Alignment(new SequenceI[] + {}); + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + aa.addSequence(aseq1); + final Sequence aseq2 = new Sequence("Seq2", "-LY-"); + aseq2.createDatasetSequence(); + aa.addSequence(aseq2); + + /* + * Mapping from first DNA sequence to second AA sequence. + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + + assertNull(acf.findAlignedSequence(seq1, aa)); + + MapList map = new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq2.getDatasetSequence(), map); + + /* + * DNA seq1 maps to AA seq2 + */ + assertEquals(aa.getSequenceAt(1), + acf.findAlignedSequence(cdna + .getSequenceAt(0).getDatasetSequence(), aa)); + + assertEquals(cdna.getSequenceAt(0), + acf.findAlignedSequence(aa + .getSequenceAt(1).getDatasetSequence(), cdna)); + } + + /** + * Test the method that locates the mapped codon for a protein position. + */ + @Test + public void testGetMappedRegion() + { + // introns lower case, exons upper case + final Sequence seq1 = new Sequence("Seq1", "c-G-TA-gC-gT-T"); + seq1.createDatasetSequence(); + final Sequence seq2 = new Sequence("Seq2", "-TA-gG-Gg-CG-a"); + seq2.createDatasetSequence(); + + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + final Sequence aseq2 = new Sequence("Seq2", "-LY-"); + aseq2.createDatasetSequence(); + + /* + * First with no mappings + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + + assertNull(acf.getMappedRegion(seq1, aseq1, 1)); + + /* + * Set up the mappings for the exons (upper-case bases) + */ + MapList map = new MapList(new int[] + { 2, 4, 6, 6, 8, 9 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + map = new MapList(new int[] + { 1, 2, 4, 5, 7, 8 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq2.getDatasetSequence(), aseq2.getDatasetSequence(), map); + + assertEquals("[2, 4]", + Arrays.toString(acf.getMappedRegion(seq1, aseq1, 1))); + assertEquals("[6, 6, 8, 9]", + Arrays.toString(acf.getMappedRegion(seq1, aseq1, 2))); + assertEquals("[1, 2, 4, 4]", + Arrays.toString(acf.getMappedRegion(seq2, aseq2, 1))); + assertEquals("[5, 5, 7, 8]", + Arrays.toString(acf.getMappedRegion(seq2, aseq2, 2))); + + /* + * No mapping from sequence 1 to sequence 2 + */ + assertNull(acf.getMappedRegion(seq1, aseq2, 1)); + } +} diff --git a/test/jalview/datamodel/AlignedCodonIteratorTest.java b/test/jalview/datamodel/AlignedCodonIteratorTest.java new file mode 100644 index 0000000..671c51d --- /dev/null +++ b/test/jalview/datamodel/AlignedCodonIteratorTest.java @@ -0,0 +1,135 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; +import jalview.util.MapList; + +import java.util.Iterator; + +import org.junit.Test; + +/** + * Unit tests for Mapping$AlignedCodonIterator + * + * @author gmcarstairs + * + */ +public class AlignedCodonIteratorTest +{ + /** + * Test normal case for iterating over aligned codons. + */ + @Test + public void testNext() + { + SequenceI from = new Sequence("Seq1", "-CgC-C-cCtAG-AtG-Gc"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "-PQ-R-"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 1, 3, 4, 6, 6, 8, 10, 12, 13 }, new int[] + { 1, 3 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[1, 3, 5]", codon.toString()); + assertEquals("P", codon.product); + codon = codons.next(); + assertEquals("[8, 10, 11]", codon.toString()); + assertEquals("Q", codon.product); + codon = codons.next(); + assertEquals("[13, 15, 17]", codon.toString()); + assertEquals("R", codon.product); + assertFalse(codons.hasNext()); + } + + /** + * Test weird case where the mapping skips over a peptide. + */ + @Test + public void testNext_unmappedPeptide() + { + SequenceI from = new Sequence("Seq1", "-CgC-C-cCtAG-AtG-Gc"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "-PQ-TR-"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 1, 3, 4, 6, 6, 8, 10, 12, 13 }, new int[] + { 1, 2, 4, 4 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[1, 3, 5]", codon.toString()); + assertEquals("P", codon.product); + codon = codons.next(); + assertEquals("[8, 10, 11]", codon.toString()); + assertEquals("Q", codon.product); + codon = codons.next(); + assertEquals("[13, 15, 17]", codon.toString()); + assertEquals("R", codon.product); + assertFalse(codons.hasNext()); + } + + /** + * Test for exception thrown for an incomplete codon. + */ + @Test + public void testNext_incompleteCodon() + { + SequenceI from = new Sequence("Seq1", "-CgC-C-cCgTt"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "-PQ-R-"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 1, 3, 4, 6, 6, 8, 8 }, new int[] + { 1, 3 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[1, 3, 5]", codon.toString()); + assertEquals("P", codon.product); + try + { + codon = codons.next(); + fail("expected exception"); + } catch (IncompleteCodonException e) + { + // expected + } + } + + /** + * Test normal case for iterating over aligned codons. + */ + @Test + public void testAnother() + { + SequenceI from = new Sequence("Seq1", "TGCCATTACCAG-"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "CHYQ"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[0, 1, 2]", codon.toString()); + assertEquals("C", codon.product); + codon = codons.next(); + assertEquals("[3, 4, 5]", codon.toString()); + assertEquals("H", codon.product); + codon = codons.next(); + assertEquals("[6, 7, 8]", codon.toString()); + assertEquals("Y", codon.product); + codon = codons.next(); + assertEquals("[9, 10, 11]", codon.toString()); + assertEquals("Q", codon.product); + assertFalse(codons.hasNext()); + } +} diff --git a/test/jalview/datamodel/AlignedCodonTest.java b/test/jalview/datamodel/AlignedCodonTest.java new file mode 100644 index 0000000..60368b1 --- /dev/null +++ b/test/jalview/datamodel/AlignedCodonTest.java @@ -0,0 +1,28 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class AlignedCodonTest +{ + + @Test + public void testEquals() + { + AlignedCodon ac = new AlignedCodon(1, 3, 4); + assertTrue(ac.equals(null)); + assertFalse(ac.equals("hello")); + assertFalse(ac.equals(new AlignedCodon(1, 3, 5))); + assertTrue(ac.equals(new AlignedCodon(1, 3, 4))); + assertTrue(ac.equals(ac)); + } + + @Test + public void testToString() { + AlignedCodon ac = new AlignedCodon(1, 3, 4); + assertEquals("[1, 3, 4]", ac.toString()); + } +} diff --git a/test/jalview/datamodel/AlignmentTest.java b/test/jalview/datamodel/AlignmentTest.java index 93170b7..3b3d926 100644 --- a/test/jalview/datamodel/AlignmentTest.java +++ b/test/jalview/datamodel/AlignmentTest.java @@ -4,6 +4,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; +import jalview.util.MapList; import java.io.IOException; import java.util.Iterator; @@ -32,10 +34,45 @@ public class AlignmentTest "D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" + "#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" + "//"; + + private static final String AA_SEQS_1 = + ">Seq1Name\n" + + "K-QY--L\n" + + ">Seq2Name\n" + + "-R-FP-W-\n"; + + private static final String CDNA_SEQS_1 = + ">Seq1Name\n" + + "AC-GG--CUC-CAA-CT\n" + + ">Seq2Name\n" + + "-CG-TTA--ACG---AAGT\n"; + + private static final String CDNA_SEQS_2 = + ">Seq1Name\n" + + "GCTCGUCGTACT\n" + + ">Seq2Name\n" + + "GGGTCAGGCAGT\n"; // @formatter:on + private AlignmentI al; - private Alignment al; + /** + * Helper method to load an alignment and ensure dataset sequences are set up. + * + * @param data + * @param format + * TODO + * @return + * @throws IOException + */ + protected AlignmentI loadAlignment(final String data, String format) + throws IOException + { + Alignment a = new FormatAdapter().readFile(data, + AppletFormatAdapter.PASTE, format); + a.setDataset(null); + return a; + } /* * Read in Stockholm format test data including secondary structure @@ -44,13 +81,12 @@ public class AlignmentTest @Before public void setUp() throws IOException { - al = new jalview.io.FormatAdapter().readFile(TEST_DATA, - AppletFormatAdapter.PASTE, "STH"); - for (int i = 0; i < al.getSequencesArray().length; ++i) + al = loadAlignment(TEST_DATA, "STH"); + int i = 0; + for (AlignmentAnnotation ann : al.getAlignmentAnnotation()) { - al.addAnnotation(al.getSequenceAt(i).getAnnotation()[0]); - al.getSequenceAt(i).getAnnotation()[0].setCalcId("CalcIdFor" - + al.getSequenceAt(i).getName()); + ann.setCalcId("CalcIdFor" + al.getSequenceAt(i).getName()); + i++; } } @@ -68,4 +104,174 @@ public class AlignmentTest assertEquals("D.melanogaster.2", ann.sequenceRef.getName()); assertFalse(iter.hasNext()); } + + @Test + public void testDeleteAllAnnotations_includingAutocalculated() + { + AlignmentAnnotation aa = new AlignmentAnnotation("Consensus", + "Consensus", 0.5); + aa.autoCalculated = true; + al.addAnnotation(aa); + AlignmentAnnotation[] anns = al.getAlignmentAnnotation(); + assertEquals("Wrong number of annotations before deleting", 4, + anns.length); + al.deleteAllAnnotations(true); + assertEquals("Not all deleted", 0, al.getAlignmentAnnotation().length); + } + + @Test + public void testDeleteAllAnnotations_excludingAutocalculated() + { + AlignmentAnnotation aa = new AlignmentAnnotation("Consensus", + "Consensus", 0.5); + aa.autoCalculated = true; + al.addAnnotation(aa); + AlignmentAnnotation[] anns = al.getAlignmentAnnotation(); + assertEquals("Wrong number of annotations before deleting", 4, + anns.length); + al.deleteAllAnnotations(false); + assertEquals("Not just one annotation left", 1, + al.getAlignmentAnnotation().length); + } + + /** + * Tests for realigning as per a supplied alignment: Dna as Dna. + * + * Note: AlignedCodonFrame's state variables are named for protein-to-cDNA + * mapping, but can be exploited for a general 'sequence-to-sequence' mapping + * as here. + * + * @throws IOException + */ + @Test + public void testAlignAs_dnaAsDna() throws IOException + { + // aligned cDNA: + AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA"); + // unaligned cDNA: + AlignmentI al2 = loadAlignment(CDNA_SEQS_2, "FASTA"); + + /* + * Make mappings between sequences. The 'aligned cDNA' is playing the role + * of what would normally be protein here. + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList ml = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 12 }, 1, 1); + acf.addMap(al2.getSequenceAt(0), al1.getSequenceAt(0), ml); + acf.addMap(al2.getSequenceAt(1), al1.getSequenceAt(1), ml); + al1.addCodonFrame(acf); + + ((Alignment) al2).alignAs(al1, false, true); + assertEquals("GC-TC--GUC-GTA-CT", al2.getSequenceAt(0) + .getSequenceAsString()); + assertEquals("-GG-GTC--AGG---CAGT", al2.getSequenceAt(1) + .getSequenceAsString()); + } + + /** + * Aligning protein from cDNA yet to be implemented, does nothing. + * + * @throws IOException + */ + @Test + public void testAlignAs_proteinAsCdna() throws IOException + { + AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA"); + AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA"); + String before0 = al2.getSequenceAt(0).getSequenceAsString(); + String before1 = al2.getSequenceAt(1).getSequenceAsString(); + + ((Alignment) al2).alignAs(al1, false, true); + assertEquals(before0, al2.getSequenceAt(0).getSequenceAsString()); + assertEquals(before1, al2.getSequenceAt(1).getSequenceAsString()); + } + + /** + * Test aligning cdna as per protein alignment. + * + * @throws IOException + */ + @Test + public void testAlignAs_cdnaAsProtein() throws IOException + { + /* + * Load alignments and add mappings for cDNA to protein + */ + AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA"); + AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA"); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList ml = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml); + acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml); + al2.addCodonFrame(acf); + + /* + * Realign DNA; currently keeping existing gaps in introns only + */ + ((Alignment) al1).alignAs(al2, false, true); + assertEquals("ACG---GCUCCA------ACT", al1.getSequenceAt(0) + .getSequenceAsString()); + assertEquals("---CGT---TAACGA---AGT", al1.getSequenceAt(1) + .getSequenceAsString()); + } + + /** + * Test aligning dna as per protein alignment, for the case where there are + * introns (i.e. some dna sites have no mapping from a peptide). + * + * @throws IOException + */ + @Test + public void testAlignAs_dnaAsProtein_withIntrons() throws IOException + { + /* + * Load alignments and add mappings for cDNA to protein + */ + String dna1 = "A-Aa-gG-GCC-cT-TT"; + String dna2 = "c--CCGgg-TT--T-AA-A"; + AlignmentI al1 = loadAlignment(">Seq1\n" + dna1 + "\n>Seq2\n" + dna2 + + "\n", "FASTA"); + AlignmentI al2 = loadAlignment(">Seq1\n-P--YK\n>Seq2\nG-T--F\n", + "FASTA"); + AlignedCodonFrame acf = new AlignedCodonFrame(); + // Seq1 has intron at dna positions 3,4,9 so splice is AAG GCC TTT + // Seq2 has intron at dna positions 1,5,6 so splice is CCG TTT AAA + MapList ml1 = new MapList(new int[] + { 1, 2, 5, 8, 10, 12 }, new int[] + { 1, 3 }, 3, 1); + acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml1); + MapList ml2 = new MapList(new int[] + { 2, 4, 7, 12 }, new int[] + { 1, 3 }, 3, 1); + acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml2); + al2.addCodonFrame(acf); + + /* + * Align ignoring gaps in dna introns and exons + */ + ((Alignment) al1).alignAs(al2, false, false); + assertEquals("---AAagG------GCCcTTT", al1.getSequenceAt(0) + .getSequenceAsString()); + // note 1 gap in protein corresponds to 'gg-' in DNA (3 positions) + assertEquals("cCCGgg-TTT------AAA", al1.getSequenceAt(1) + .getSequenceAsString()); + + /* + * Reset and realign, preserving gaps in dna introns and exons + */ + al1.getSequenceAt(0).setSequence(dna1); + al1.getSequenceAt(1).setSequence(dna2); + ((Alignment) al1).alignAs(al2, true, true); + // String dna1 = "A-Aa-gG-GCC-cT-TT"; + // String dna2 = "c--CCGgg-TT--T-AA-A"; + // assumption: we include 'the greater of' protein/dna gap lengths, not both + assertEquals("---A-Aa-gG------GCC-cT-TT", al1.getSequenceAt(0) + .getSequenceAsString()); + assertEquals("c--CCGgg-TT--T------AA-A", al1.getSequenceAt(1) + .getSequenceAsString()); + } } diff --git a/test/jalview/datamodel/ColumnSelectionTest.java b/test/jalview/datamodel/ColumnSelectionTest.java new file mode 100644 index 0000000..228156a --- /dev/null +++ b/test/jalview/datamodel/ColumnSelectionTest.java @@ -0,0 +1,48 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +public class ColumnSelectionTest +{ + + @Test + public void testAddElement() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(5); + List sel = cs.getSelected(); + assertEquals(2, sel.size()); + assertEquals(new Integer(2), sel.get(0)); + assertEquals(new Integer(5), sel.get(1)); + } + + /** + * Test the remove method - in particular to verify that remove(int i) removes + * the element whose value is i, _NOT_ the i'th element. + */ + @Test + public void testRemoveElement() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(5); + + // removing elements not in the list has no effect + cs.removeElement(0); + cs.removeElement(1); + List sel = cs.getSelected(); + assertEquals(2, sel.size()); + assertEquals(new Integer(2), sel.get(0)); + assertEquals(new Integer(5), sel.get(1)); + + // removing an element in the list removes it + cs.removeElement(2); + assertEquals(1, sel.size()); + assertEquals(new Integer(5), sel.get(0)); + } +} diff --git a/test/jalview/datamodel/SearchResultsTest.java b/test/jalview/datamodel/SearchResultsTest.java new file mode 100644 index 0000000..15b0314 --- /dev/null +++ b/test/jalview/datamodel/SearchResultsTest.java @@ -0,0 +1,24 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SearchResultsTest +{ + + @Test + public void testToString() + { + SequenceI seq = new Sequence("", "abcdefghijklm"); + SearchResults sr = new SearchResults(); + sr.addResult(seq, 1, 1); + assertEquals("a", sr.toString()); + sr.addResult(seq, 3, 5); + assertEquals("acde", sr.toString()); + + seq = new Sequence("", "pqrstuvwxy"); + sr.addResult(seq, 6, 7); + assertEquals("acdeuv", sr.toString()); + } +} diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index 40476a0..1ef1d07 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.util.Arrays; import java.util.List; import org.junit.Before; @@ -135,4 +136,178 @@ public class SequenceTest assertSame(annotation2, anns[1]); } + + @Test + public void testGetStartGetEnd() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(1, seq.getStart()); + assertEquals(6, seq.getEnd()); + + seq = new Sequence("test", "--AB-C-DEF--"); + assertEquals(1, seq.getStart()); + assertEquals(6, seq.getEnd()); + + seq = new Sequence("test", "----"); + assertEquals(1, seq.getStart()); + assertEquals(0, seq.getEnd()); // ?? + } + + /** + * Tests for the method that returns an alignment column position (base 1) for + * a given sequence position (base 1). + */ + @Test + public void testFindIndex() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(0, seq.findIndex(0)); + assertEquals(1, seq.findIndex(1)); + assertEquals(5, seq.findIndex(5)); + assertEquals(6, seq.findIndex(6)); + assertEquals(6, seq.findIndex(9)); + + seq = new Sequence("test", "-A--B-C-D-E-F--"); + assertEquals(2, seq.findIndex(1)); + assertEquals(5, seq.findIndex(2)); + assertEquals(7, seq.findIndex(3)); + + // before start returns 0 + assertEquals(0, seq.findIndex(0)); + assertEquals(0, seq.findIndex(-1)); + + // beyond end returns last residue column + assertEquals(13, seq.findIndex(99)); + + } + + /** + * Tests for the method that returns a dataset sequence position (base 1) for + * an aligned column position (base 0). + */ + @Test + public void testFindPosition() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(1, seq.findPosition(0)); + assertEquals(6, seq.findPosition(5)); + // assertEquals(-1, seq.findPosition(6)); // fails + + seq = new Sequence("test", "AB-C-D--"); + assertEquals(1, seq.findPosition(0)); + assertEquals(2, seq.findPosition(1)); + // gap position 'finds' residue to the right (not the left as per javadoc) + assertEquals(3, seq.findPosition(2)); + assertEquals(3, seq.findPosition(3)); + assertEquals(4, seq.findPosition(4)); + assertEquals(4, seq.findPosition(5)); + // returns 1 more than sequence length if off the end ?!? + assertEquals(5, seq.findPosition(6)); + assertEquals(5, seq.findPosition(7)); + + seq = new Sequence("test", "--AB-C-DEF--"); + assertEquals(1, seq.findPosition(0)); + assertEquals(1, seq.findPosition(1)); + assertEquals(1, seq.findPosition(2)); + assertEquals(2, seq.findPosition(3)); + assertEquals(3, seq.findPosition(4)); + assertEquals(3, seq.findPosition(5)); + assertEquals(4, seq.findPosition(6)); + assertEquals(4, seq.findPosition(7)); + assertEquals(5, seq.findPosition(8)); + assertEquals(6, seq.findPosition(9)); + assertEquals(7, seq.findPosition(10)); + assertEquals(7, seq.findPosition(11)); + } + + @Test + public void testDeleteChars() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(1, seq.getStart()); + assertEquals(6, seq.getEnd()); + seq.deleteChars(2, 3); + assertEquals("ABDEF", seq.getSequenceAsString()); + assertEquals(1, seq.getStart()); + assertEquals(5, seq.getEnd()); + + seq = new Sequence("test", "ABCDEF"); + seq.deleteChars(0, 2); + assertEquals("CDEF", seq.getSequenceAsString()); + assertEquals(3, seq.getStart()); + assertEquals(6, seq.getEnd()); + } + + @Test + public void testInsertCharAt() + { + // non-static methods: + SequenceI seq = new Sequence("test", "ABCDEF"); + seq.insertCharAt(0, 'z'); + assertEquals("zABCDEF", seq.getSequenceAsString()); + seq.insertCharAt(2, 2, 'x'); + assertEquals("zAxxBCDEF", seq.getSequenceAsString()); + + // for static method see StringUtilsTest + } + + /** + * Test the method that returns an array of aligned sequence positions where + * the array index is the data sequence position (both base 0). + */ + @Test + public void testGapMap() + { + SequenceI seq = new Sequence("test", "-A--B-CD-E--F-"); + seq.createDatasetSequence(); + assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap())); + } + + /** + * Test the method that gets sequence features, either from the sequence or + * its dataset. + */ + @Test + public void testGetSequenceFeatures() + { + SequenceI seq = new Sequence("test", "GATCAT"); + seq.createDatasetSequence(); + + assertNull(seq.getSequenceFeatures()); + + /* + * SequenceFeature on sequence + */ + SequenceFeature sf = new SequenceFeature(); + seq.addSequenceFeature(sf); + SequenceFeature[] sfs = seq.getSequenceFeatures(); + assertEquals(1, sfs.length); + assertSame(sf, sfs[0]); + + /* + * SequenceFeature on sequence and dataset sequence; returns that on + * sequence + */ + SequenceFeature sf2 = new SequenceFeature(); + seq.getDatasetSequence().addSequenceFeature(sf2); + sfs = seq.getSequenceFeatures(); + assertEquals(1, sfs.length); + assertSame(sf, sfs[0]); + + /* + * SequenceFeature on dataset sequence only + */ + seq.setSequenceFeatures(null); + sfs = seq.getSequenceFeatures(); + assertEquals(1, sfs.length); + assertSame(sf2, sfs[0]); + + /* + * Corrupt case - no SequenceFeature, dataset's dataset is the original + * sequence. Test shows no infinite loop results. + */ + seq.getDatasetSequence().setSequenceFeatures(null); + seq.getDatasetSequence().setDatasetSequence(seq); // loop! + assertNull(seq.getSequenceFeatures()); + } } diff --git a/test/jalview/ext/rbvi/chimera/ChimeraConnect.java b/test/jalview/ext/rbvi/chimera/ChimeraConnect.java index be4e5ea..ad4f997 100644 --- a/test/jalview/ext/rbvi/chimera/ChimeraConnect.java +++ b/test/jalview/ext/rbvi/chimera/ChimeraConnect.java @@ -1,13 +1,14 @@ package jalview.ext.rbvi.chimera; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; -import java.util.Arrays; import java.util.Collection; import org.junit.Test; -import ext.edu.ucsf.rbvi.strucviz2.*; +import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager; +import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel; +import ext.edu.ucsf.rbvi.strucviz2.StructureManager; public class ChimeraConnect { @@ -15,9 +16,10 @@ public class ChimeraConnect @Test public void test() { - StructureManager csm; + StructureManager csm; ext.edu.ucsf.rbvi.strucviz2.ChimeraManager cm = new ChimeraManager(csm = new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true)); - assertTrue("Couldn't launch chimera",cm.launchChimera(csm.getChimeraPaths())); + assertTrue("Couldn't launch chimera", + cm.launchChimera(StructureManager.getChimeraPaths())); int n=0; while (n++<100) { diff --git a/test/jalview/gui/AnnotationChooserTest.java b/test/jalview/gui/AnnotationChooserTest.java index 944ab9c..2b890d2 100644 --- a/test/jalview/gui/AnnotationChooserTest.java +++ b/test/jalview/gui/AnnotationChooserTest.java @@ -3,6 +3,8 @@ package jalview.gui; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; +import jalview.bin.Cache; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; @@ -52,6 +54,12 @@ public class AnnotationChooserTest @Before public void setUp() throws IOException { + // pin down annotation sort order for test + Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS, + SequenceAnnotationOrder.NONE.name()); + Cache.applicationProperties.setProperty( + Preferences.SHOW_AUTOCALC_ABOVE, Boolean.TRUE.toString()); + AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA, AppletFormatAdapter.PASTE, "FASTA"); af = new AlignFrame(al, 700, 500); @@ -490,6 +498,7 @@ public class AnnotationChooserTest @Test public void testSelectType_showForSelected() { + // sequences 1 and 2 have annotations IUPred and Jmol selectSequences(1, 2); testee = new AnnotationChooser(parentPanel); final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0); @@ -505,6 +514,7 @@ public class AnnotationChooserTest setSelected(selectedSequencesCheckbox, true); setSelected(hideCheckbox, true); setSelected(getTypeCheckbox("JMol"), true); + assertTrue(anns[5].visible); // JMol for seq3 assertFalse(anns[7].visible); // JMol for seq1 // ...now show them... @@ -738,8 +748,8 @@ public class AnnotationChooserTest assertTrue(anns[0].visible); // Conservation assertTrue(anns[1].visible); // Quality assertTrue(anns[2].visible); // Consensus - assertFalse(anns[3].visible); // IUPRED - assertTrue(anns[4].visible); // Beauty (not seq-related) + assertTrue(anns[3].visible); // Beauty (not seq-related) + assertFalse(anns[4].visible); // IUPRED assertFalse(anns[5].visible); // JMol assertFalse(anns[6].visible); // IUPRED assertFalse(anns[7].visible); // JMol diff --git a/test/jalview/gui/JvSwingUtilsTest.java b/test/jalview/gui/JvSwingUtilsTest.java new file mode 100644 index 0000000..11e6ea5 --- /dev/null +++ b/test/jalview/gui/JvSwingUtilsTest.java @@ -0,0 +1,41 @@ +package jalview.gui; + +import static org.junit.Assert.assertEquals; + +import javax.swing.JScrollBar; + +import org.junit.Test; + +public class JvSwingUtilsTest +{ + + @Test + public void testGetScrollBarProportion() + { + /* + * orientation, value, extent (width), min, max + */ + JScrollBar sb = new JScrollBar(0, 125, 50, 0, 450); + + /* + * operating range is 25 - 425 (400 wide) so value 125 is 100/400ths of this + * range + */ + assertEquals(0.25f, JvSwingUtils.getScrollBarProportion(sb), 0.001f); + } + + @Test + public void testGetScrollValueForProportion() + { + /* + * orientation, value, extent (width), min, max + */ + JScrollBar sb = new JScrollBar(0, 125, 50, 0, 450); + + /* + * operating range is 25 - 425 (400 wide) so value 125 is a quarter of this + * range + */ + assertEquals(125, JvSwingUtils.getScrollValueForProportion(sb, 0.25f)); + } +} diff --git a/test/jalview/gui/PaintRefresherTest.java b/test/jalview/gui/PaintRefresherTest.java new file mode 100644 index 0000000..1da7c8c --- /dev/null +++ b/test/jalview/gui/PaintRefresherTest.java @@ -0,0 +1,116 @@ +package jalview.gui; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.Alignment; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.viewmodel.AlignmentViewport; + +import java.awt.Component; +import java.util.List; +import java.util.Map; + +import javax.swing.JPanel; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class PaintRefresherTest +{ + // TODO would prefer PaintRefresher to be a single rather than static + @Before + public void setUp() + { + PaintRefresher.components.clear(); + } + + @After + public void tearDown() + { + PaintRefresher.components.clear(); + } + + @Test + public void testRegister() + { + JPanel jp = new JPanel(); + JPanel jp2 = new JPanel(); + JPanel jp3 = new JPanel(); + JPanel jp4 = new JPanel(); + PaintRefresher.Register(jp, "22"); + PaintRefresher.Register(jp, "22"); + PaintRefresher.Register(jp2, "22"); + PaintRefresher.Register(jp3, "33"); + PaintRefresher.Register(jp3, "44"); + PaintRefresher.Register(jp4, "44"); + + Map> registered = PaintRefresher.components; + assertEquals(3, registered.size()); + assertEquals(2, registered.get("22").size()); + assertEquals(1, registered.get("33").size()); + assertEquals(2, registered.get("44").size()); + assertTrue(registered.get("22").contains(jp)); + assertTrue(registered.get("22").contains(jp2)); + assertTrue(registered.get("33").contains(jp3)); + assertTrue(registered.get("44").contains(jp3)); + assertTrue(registered.get("44").contains(jp4)); + } + + @Test + public void testRemoveComponent() + { + Map> registered = PaintRefresher.components; + + // no error with an empty PaintRefresher + JPanel jp = new JPanel(); + JPanel jp2 = new JPanel(); + PaintRefresher.RemoveComponent(jp); + assertTrue(registered.isEmpty()); + + /* + * Add then remove one item + */ + PaintRefresher.Register(jp, "11"); + PaintRefresher.RemoveComponent(jp); + assertTrue(registered.isEmpty()); + + /* + * Add one item under two ids, then remove it. It is removed from both ids, + * and the now empty id is removed. + */ + PaintRefresher.Register(jp, "11"); + PaintRefresher.Register(jp, "22"); + PaintRefresher.Register(jp2, "22"); + PaintRefresher.RemoveComponent(jp); + // "11" is removed as now empty, only 22/jp2 left + assertEquals(1, registered.size()); + assertEquals(1, registered.get("22").size()); + assertTrue(registered.get("22").contains(jp2)); + } + + @Test + public void testGetAssociatedPanels() + { + SequenceI [] seqs = new SequenceI[]{new Sequence("", "ABC")}; + Alignment al = new Alignment(seqs); + + /* + * AlignFrame constructor has side-effects: AlignmentPanel is constructed, + * and SeqCanvas, IdPanel, AlignmentPanel are all registered under the + * sequence set id of the viewport. + */ + AlignmentViewport av = new AlignViewport(al); + AlignFrame af = new AlignFrame(al, 4, 1); + AlignmentPanel ap1 = af.alignPanel; + AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(av + .getSequenceSetId()); + assertEquals(1, panels.length); + assertSame(ap1, panels[0]); + + panels = PaintRefresher.getAssociatedPanels(av.getSequenceSetId() + 1); + assertEquals(0, panels.length); + } +} diff --git a/test/jalview/io/AnnotatedPDBFileInputTest.java b/test/jalview/io/AnnotatedPDBFileInputTest.java index 30b6d55..29d5549 100644 --- a/test/jalview/io/AnnotatedPDBFileInputTest.java +++ b/test/jalview/io/AnnotatedPDBFileInputTest.java @@ -7,8 +7,12 @@ import static org.junit.Assert.assertTrue; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; +import jalview.gui.Desktop; +import jalview.structure.StructureMapping; +import jalview.structure.StructureSelectionManager; import java.io.File; import java.util.Vector; @@ -73,6 +77,48 @@ public class AnnotatedPDBFileInputTest } } + /** + * Check sequence features have been added + */ + @Test + public void checkPDBSequenceFeatures() + { + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + StructureMapping[] mappings = ssm.getMapping("1gaq"); + // suspect we really want to make assertions on sequence features + // in these mappings' sequencess + /* + * 1GAQ/A + */ + SequenceFeature[] sf = al.getSequenceAt(0).getSequenceFeatures(); + assertEquals(296, sf.length); + assertEquals("RESNUM", sf[0].getType()); + assertEquals("GLU:19 1gaqA", sf[0].getDescription()); + assertEquals("RESNUM", sf[295].getType()); + assertEquals("TYR:314 1gaqA", sf[295].getDescription()); + + /* + * 1GAQ/B + */ + sf = al.getSequenceAt(1).getSequenceFeatures(); + assertEquals(98, sf.length); + assertEquals("RESNUM", sf[0].getType()); + assertEquals("ALA:1 1gaqB", sf[0].getDescription()); + assertEquals("RESNUM", sf[97].getType()); + assertEquals("ALA:98 1gaqB", sf[97].getDescription()); + + /* + * 1GAQ/C + */ + sf = al.getSequenceAt(2).getSequenceFeatures(); + assertEquals(296, sf.length); + assertEquals("RESNUM", sf[0].getType()); + assertEquals("GLU:19 1gaqC", sf[0].getDescription()); + assertEquals("RESNUM", sf[295].getType()); + assertEquals("TYR:314 1gaqC", sf[295].getDescription()); + } + @Test public void checkAnnotationWiring() { diff --git a/test/jalview/io/Jalview2xmlTests.java b/test/jalview/io/Jalview2xmlTests.java index 75626e9..6892e5f 100644 --- a/test/jalview/io/Jalview2xmlTests.java +++ b/test/jalview/io/Jalview2xmlTests.java @@ -23,6 +23,7 @@ package jalview.io; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import jalview.api.AlignmentViewPanel; +import jalview.api.ViewStyleI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -34,6 +35,7 @@ import jalview.schemes.ColourSchemeI; import java.io.File; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -239,13 +241,13 @@ public class Jalview2xmlTests @Test public void gatherViewsHere() throws Exception { - int origCount = Desktop.getAlignframes() == null ? 0 : Desktop - .getAlignframes().length; + int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop + .getAlignFrames().length; AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded( "examples/exampleFile_2_7.jar", FormatAdapter.FILE); assertTrue("Didn't read in the example file correctly.", af != null); assertTrue("Didn't gather the views in the example file.", - Desktop.getAlignframes().length == 1 + origCount); + Desktop.getAlignFrames().length == 1 + origCount); } @@ -306,4 +308,37 @@ public class Jalview2xmlTests } } + + @Test + public void testCopyViewSettings() throws Exception + { + AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded( + "examples/exampleFile_2_7.jar", FormatAdapter.FILE); + Assert.assertTrue("Didn't read in the example file correctly.", af != null); + AlignmentViewPanel sps = null, groups = null; + for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels()) + { + if ("Spinach Feredoxin Structure".equals(ap.getViewName())) + { + sps = ap; + } + if (ap.getViewName().contains("MAFFT")) + { + groups = ap; + } + } + assertTrue("Couldn't find the structure view", sps != null); + assertTrue("Couldn't find the MAFFT view", groups != null); + + ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle(); + ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle(); + Assert.assertFalse(structureStyle.sameStyle(groupStyle)); + + groups.getAlignViewport().setViewStyle(structureStyle); + Assert.assertFalse(groupStyle.sameStyle(groups.getAlignViewport() + .getViewStyle())); + Assert.assertTrue(structureStyle.sameStyle(groups.getAlignViewport() + .getViewStyle())); + + } } diff --git a/test/jalview/structure/StructureSelectionManagerTest.java b/test/jalview/structure/StructureSelectionManagerTest.java new file mode 100644 index 0000000..487ef2c --- /dev/null +++ b/test/jalview/structure/StructureSelectionManagerTest.java @@ -0,0 +1,175 @@ +package jalview.structure; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.AlignedCodonFrame; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +public class StructureSelectionManagerTest +{ + private StructureSelectionManager ssm; + + @Before + public void setUp() + { + ssm = new StructureSelectionManager(); + } + + @Test + public void testAddMapping() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + + /* + * One mapping only. + */ + ssm.addMapping(acf1); + assertEquals(1, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertEquals(1, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + + /* + * A second mapping. + */ + ssm.addMapping(acf2); + assertEquals(2, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertEquals(2, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + + /* + * A second reference to the first mapping. + */ + ssm.addMapping(acf1); + assertEquals(2, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertEquals(2, ssm.seqMappingRefCounts.size()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + } + + @Test + public void testAddMappings() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + AlignedCodonFrame acf3 = new AlignedCodonFrame(); + + Set set1 = new HashSet(); + set1.add(acf1); + set1.add(acf2); + Set set2 = new HashSet(); + set2.add(acf2); + set2.add(acf3); + + /* + * Adding both sets adds acf2 twice and acf1 and acf3 once each. + */ + ssm.addMappings(set1); + ssm.addMappings(set2); + + assertEquals(3, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertTrue(ssm.seqmappings.contains(acf3)); + assertEquals(3, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf2).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf3).intValue()); + } + + @Test + public void testRemoveMapping() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + ssm.addMapping(acf1); + + /* + * Add one and remove it. + */ + ssm.removeMapping(acf1); + ssm.removeMapping(acf2); + assertEquals(0, ssm.seqmappings.size()); + assertEquals(0, ssm.seqMappingRefCounts.size()); + + /* + * Add one twice and remove it once. + */ + ssm.addMapping(acf1); + ssm.addMapping(acf2); + ssm.addMapping(acf1); + ssm.removeMapping(acf1); + assertEquals(2, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertEquals(2, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + + /* + * Remove both once more to clear the set. + */ + ssm.removeMapping(acf1); + ssm.removeMapping(acf2); + assertEquals(0, ssm.seqmappings.size()); + assertEquals(0, ssm.seqMappingRefCounts.size()); + } + + @Test + public void testRemoveMappings() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + AlignedCodonFrame acf3 = new AlignedCodonFrame(); + + /* + * Initial ref counts are 3/2/1: + */ + ssm.addMapping(acf1); + ssm.addMapping(acf1); + ssm.addMapping(acf1); + ssm.addMapping(acf2); + ssm.addMapping(acf2); + ssm.addMapping(acf3); + + Set set1 = new HashSet(); + set1.add(acf1); + set1.add(acf2); + Set set2 = new HashSet(); + set2.add(acf2); + set2.add(acf3); + + /* + * Remove one ref each to acf1, acf2, counts are now 2/1/1: + */ + ssm.removeMappings(set1); + assertEquals(3, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertTrue(ssm.seqmappings.contains(acf3)); + assertEquals(3, ssm.seqMappingRefCounts.size()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf3).intValue()); + + /* + * Remove one ref each to acf2, acf3 - they are removed + */ + ssm.removeMappings(set2); + assertEquals(1, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertEquals(1, ssm.seqMappingRefCounts.size()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf1).intValue()); + } +} diff --git a/test/jalview/util/ComparisonTest.java b/test/jalview/util/ComparisonTest.java new file mode 100644 index 0000000..bfc2610 --- /dev/null +++ b/test/jalview/util/ComparisonTest.java @@ -0,0 +1,89 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import org.junit.Test; + +public class ComparisonTest +{ + + @Test + public void testIsGap() + { + assertTrue(Comparison.isGap('-')); + assertTrue(Comparison.isGap('.')); + assertTrue(Comparison.isGap(' ')); + assertFalse(Comparison.isGap('X')); + assertFalse(Comparison.isGap('x')); + assertFalse(Comparison.isGap('*')); + assertFalse(Comparison.isGap('G')); + } + + /** + * Test for isNucleotide is that sequences in a dataset are more than 85% + * AGCTU. Test is not case-sensitive and ignores gaps. + */ + @Test + public void testIsNucleotide() { + SequenceI seq = new Sequence("eightypercent", "agctuAGCPV"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("eightyfivepercent", "agctuAGCPVagctuAGCUV"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("nineypercent", "agctuAGCgVagctuAGCUV"); + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("eightyfivepercentgapped", + "--agc--tuA--GCPV-a---gct-uA-GC---UV"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("nineypercentgapped", + "ag--ct-u-A---GC---g----Vag--c---tuAGCUV"); + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("allgap", "---------"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("DNA", "ACTugGCCAG"); + SequenceI seq2 = new Sequence("Protein", "FLIMVSPTYW"); + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq, seq, seq, seq, seq, seq, seq, seq, seq, seq2 })); // 90% DNA + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq, seq, seq, seq, seq, seq, seq, seq, seq2, seq2 })); // 80% DNA + + seq = new Sequence("ProteinThatLooksLikeDNA", "WYATGCCTGAgtcgt"); + // 12/14 = 85.7% + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq })); + + assertFalse(Comparison.isNucleotide(null)); + } + + /** + * Test percentage identity calculation for two sequences. + */ + @Test + public void testPID_matchGaps() + { + String seq1 = "ABCDEF"; + String seq2 = "abcdef"; + assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f); + + // comparison range defaults to length of first sequence + seq2 = "abcdefghijklmnopqrstuvwxyz"; + assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f); + + seq2 = "a---bcdef"; + } +} diff --git a/test/jalview/util/MapListTest.java b/test/jalview/util/MapListTest.java new file mode 100644 index 0000000..f69fe40 --- /dev/null +++ b/test/jalview/util/MapListTest.java @@ -0,0 +1,501 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class MapListTest +{ + + @Test + public void testSomething() + { + MapList ml = new MapList(new int[] + { 1, 5, 10, 15, 25, 20 }, new int[] + { 51, 1 }, 1, 3); + MapList ml1 = new MapList(new int[] + { 1, 3, 17, 4 }, new int[] + { 51, 1 }, 1, 3); + MapList ml2 = new MapList(new int[] + { 1, 60 }, new int[] + { 1, 20 }, 3, 1); + // test internal consistency + int to[] = new int[51]; + testMap(ml, 1, 60); + MapList mldna = new MapList(new int[] + { 2, 2, 6, 8, 12, 16 }, new int[] + { 1, 3 }, 3, 1); + int[] frm = mldna.locateInFrom(1, 1); + testLocateFrom(mldna, 1, 1, new int[] + { 2, 2, 6, 7 }); + testMap(mldna, 1, 3); + /* + * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[] + * toofrom=ml.shiftFrom(too[0]); + * System.out.println("ShiftFrom("+from+")=="+too[0]+" % + * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); } + */ + } + + private static void testLocateFrom(MapList mldna, int i, int j, int[] ks) + { + int[] frm = mldna.locateInFrom(i, j); + Assert.assertEquals("Failed test locate from " + i + " to " + j, + Arrays.toString(frm), Arrays.toString(ks)); + } + + /** + * test routine. not incremental. + * + * @param ml + * @param fromS + * @param fromE + */ + private void testMap(MapList ml, int fromS, int fromE) + { + // todo convert to JUnit style tests + for (int from = 1; from <= 25; from++) + { + int[] too = ml.shiftFrom(from); + System.out.print("ShiftFrom(" + from + ")=="); + if (too == null) + { + System.out.print("NaN\n"); + } + else + { + System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")"); + System.out.print("\t+--+\t"); + int[] toofrom = ml.shiftTo(too[0]); + if (toofrom != null) + { + if (toofrom[0] != from) + { + System.err.println("Mapping not reflexive:" + from + " " + + too[0] + "->" + toofrom[0]); + } + System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] + + " % " + toofrom[1] + " (" + toofrom[2] + ")"); + } + else + { + System.out.println("ShiftTo(" + too[0] + ")==" + + "NaN! - not Bijective Mapping!"); + } + } + } + int mmap[][] = ml.makeFromMap(); + System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + + mmap[0][2] + " " + mmap[0][3] + " "); + for (int i = 1; i <= mmap[1].length; i++) + { + if (mmap[1][i - 1] == -1) + { + System.out.print(i + "=XXX"); + + } + else + { + System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); + } + if (i % 20 == 0) + { + System.out.print("\n"); + } + else + { + System.out.print(","); + } + } + // test range function + System.out.print("\nTest locateInFrom\n"); + { + int f = mmap[0][2], t = mmap[0][3]; + while (f <= t) + { + System.out.println("Range " + f + " to " + t); + int rng[] = ml.locateInFrom(f, t); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + System.out.print("\nReversed\n"); + rng = ml.locateInFrom(t, f); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + System.out.print("\n"); + f++; + t--; + } + } + System.out.print("\n"); + mmap = ml.makeToMap(); + System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + + mmap[0][2] + " " + mmap[0][3] + " "); + for (int i = 1; i <= mmap[1].length; i++) + { + if (mmap[1][i - 1] == -1) + { + System.out.print(i + "=XXX"); + + } + else + { + System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); + } + if (i % 20 == 0) + { + System.out.print("\n"); + } + else + { + System.out.print(","); + } + } + System.out.print("\n"); + // test range function + System.out.print("\nTest locateInTo\n"); + { + int f = mmap[0][2], t = mmap[0][3]; + while (f <= t) + { + System.out.println("Range " + f + " to " + t); + int rng[] = ml.locateInTo(f, t); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + System.out.print("\nReversed\n"); + rng = ml.locateInTo(t, f); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + f++; + t--; + System.out.print("\n"); + } + } + } + + /** + * Tests for method that locates ranges in the 'from' map for given range in + * the 'to' map. + */ + @Test + public void testLocateInFrom_noIntrons() + { + /* + * Simple mapping with no introns + */ + int[] codons = new int[] + { 1, 12 }; + int[] protein = new int[] + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1))); + assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2))); + assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3))); + assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); + assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2))); + assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3))); + assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4))); + assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3))); + assertEquals("[4, 12]", Arrays.toString(ml.locateInFrom(2, 4))); + assertEquals("[7, 12]", Arrays.toString(ml.locateInFrom(3, 4))); + assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); + + assertNull(ml.locateInFrom(0, 0)); + assertNull(ml.locateInFrom(1, 5)); + assertNull(ml.locateInFrom(-1, 1)); + } + + /** + * Tests for method that locates ranges in the 'from' map for given range in + * the 'to' map. + */ + @Test + public void testLocateInFrom_withIntrons() + { + /* + * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. + * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 + */ + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals("[2, 3, 5, 5]", Arrays.toString(ml.locateInFrom(1, 1))); + assertEquals("[6, 7, 9, 9]", Arrays.toString(ml.locateInFrom(2, 2))); + assertEquals("[10, 10, 12, 12, 14, 14]", + Arrays.toString(ml.locateInFrom(3, 3))); + assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4))); + } + + /** + * Tests for method that locates ranges in the 'to' map for given range in the + * 'from' map. + */ + @Test + public void testLocateInTo_noIntrons() + { + /* + * Simple mapping with no introns + */ + int[] codons = new int[] + { 1, 12 }; + int[] protein = new int[] + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 3))); + assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); + assertEquals("[3, 3]", Arrays.toString(ml.locateInTo(7, 9))); + assertEquals("[4, 4]", Arrays.toString(ml.locateInTo(10, 12))); + assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 6))); + assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(1, 9))); + assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 12))); + assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); + assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(4, 12))); + + /* + * A part codon is treated as if a whole one. + */ + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2))); + assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 4))); + assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(2, 8))); + assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11))); + assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11))); + + assertNull(ml.locateInTo(0, 0)); + assertNull(ml.locateInTo(1, 13)); + assertNull(ml.locateInTo(-1, 1)); + } + + /** + * Tests for method that locates ranges in the 'to' map for given range in the + * 'from' map. + */ + @Test + public void testLocateInTo_withIntrons() + { + /* + * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. + * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 + */ + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + /* + * Mapped proteins at positions 1, 3, 4, 6 in the sequence + */ + int[] protein = + { 1, 1, 3, 4, 6, 6 }; + MapList ml = new MapList(codons, protein, 3, 1); + + /* + * Can't map from an unmapped position + */ + assertNull(ml.locateInTo(1, 2)); + assertNull(ml.locateInTo(2, 4)); + assertNull(ml.locateInTo(4, 4)); + + /* + * Valid range or subrange of codon1 maps to protein1. + */ + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 2))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 3))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 5))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 3))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 5))); + + // codon position 6 starts the next protein: + assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.locateInTo(3, 6))); + + // codon positions 7 to 17 (part) cover proteins 2/3/4 at positions 3/4/6 + assertEquals("[3, 4, 6, 6]", Arrays.toString(ml.locateInTo(7, 17))); + + } + + /** + * Test equals method. + */ + @Test + public void testEquals() + { + int[] codons = new int[] + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = new int[] + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + MapList ml1 = new MapList(codons, protein, 3, 1); // same values + MapList ml2 = new MapList(codons, protein, 2, 1); // fromRatio differs + MapList ml3 = new MapList(codons, protein, 3, 2); // toRatio differs + codons[2] = 4; + MapList ml6 = new MapList(codons, protein, 3, 1); // fromShifts differ + protein[1] = 3; + MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ + + assertTrue(ml.equals(ml)); + assertTrue(ml.equals(ml1)); + assertTrue(ml1.equals(ml)); + + assertFalse(ml.equals(null)); + assertFalse(ml.equals("hello")); + assertFalse(ml.equals(ml2)); + assertFalse(ml.equals(ml3)); + assertFalse(ml.equals(ml6)); + assertFalse(ml.equals(ml7)); + assertFalse(ml6.equals(ml7)); + + try + { + MapList ml4 = new MapList(codons, null, 3, 1); // toShifts null + assertFalse(ml.equals(ml4)); + } catch (NullPointerException e) + { + // actually thrown by constructor before equals can be called + } + try + { + MapList ml5 = new MapList(null, protein, 3, 1); // fromShifts null + assertFalse(ml.equals(ml5)); + } catch (NullPointerException e) + { + // actually thrown by constructor before equals can be called + } + } + + /** + * Test for the method that flattens a list of ranges into a single array. + */ + @Test + public void testGetRanges() + { + List ranges = new ArrayList(); + ranges.add(new int[] + { 2, 3 }); + ranges.add(new int[] + { 5, 6 }); + assertEquals("[2, 3, 5, 6]", Arrays.toString(MapList.getRanges(ranges))); + } + + /** + * Check state after construction + */ + @Test + public void testConstructor() + { + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = + { 1, 1, 3, 4, 6, 6 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals(3, ml.getFromRatio()); + assertEquals(2, ml.getFromLowest()); + assertEquals(18, ml.getFromHighest()); + assertEquals(1, ml.getToLowest()); + assertEquals(6, ml.getToHighest()); + assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", + prettyPrint(ml.getFromRanges())); + assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml.getToRanges())); + + /* + * Also copy constructor + */ + MapList ml2 = new MapList(ml); + assertEquals(3, ml2.getFromRatio()); + assertEquals(2, ml2.getFromLowest()); + assertEquals(18, ml2.getFromHighest()); + assertEquals(1, ml2.getToLowest()); + assertEquals(6, ml2.getToHighest()); + assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", + prettyPrint(ml2.getFromRanges())); + assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml2.getToRanges())); + } + + /** + * Convert a List of {[i, j], [k, l], ...} to "[[i, j], [k, l], ...]" + * + * @param ranges + * @return + */ + private String prettyPrint(List ranges) + { + StringBuilder sb = new StringBuilder(ranges.size() * 5); + boolean first = true; + sb.append("{"); + for (int[] range : ranges) + { + if (!first) + { + sb.append(", "); + } + sb.append(Arrays.toString(range)); + first = false; + } + sb.append("}"); + return sb.toString(); + } + + /** + * Test the method that creates an inverse mapping + */ + @Test + public void testGetInverse() + { + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = + { 1, 1, 3, 4, 6, 6 }; + + MapList ml = new MapList(codons, protein, 3, 1); + MapList ml2 = ml.getInverse(); + assertEquals(ml.getFromRatio(), ml2.getToRatio()); + assertEquals(ml.getFromRatio(), ml2.getToRatio()); + assertEquals(ml.getToHighest(), ml2.getFromHighest()); + assertEquals(ml.getFromHighest(), ml2.getToHighest()); + assertEquals(prettyPrint(ml.getFromRanges()), + prettyPrint(ml2.getToRanges())); + assertEquals(prettyPrint(ml.getToRanges()), + prettyPrint(ml2.getFromRanges())); + } +} diff --git a/test/jalview/util/MappingUtilsTest.java b/test/jalview/util/MappingUtilsTest.java new file mode 100644 index 0000000..f0f3be7 --- /dev/null +++ b/test/jalview/util/MappingUtilsTest.java @@ -0,0 +1,400 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import jalview.api.AlignViewportI; +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.gui.AlignViewport; +import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; + +import java.awt.Color; +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import org.junit.Test; + +public class MappingUtilsTest +{ + private AlignViewportI dnaView; + private AlignViewportI proteinView; + + /** + * Simple test of mapping with no intron involved. + */ + @Test + public void testBuildSearchResults() + { + final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC"); + seq1.createDatasetSequence(); + + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + + /* + * Map dna bases 1-6 to protein residues 1-2 + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + Set acfList = Collections.singleton(acf); + + /* + * Check protein residue 1 maps to codon 1-3, 2 to codon 4-6 + */ + SearchResults sr = MappingUtils.buildSearchResults(aseq1, 1, acfList); + assertEquals(1, sr.getResults().size()); + Match m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(1, m.getStart()); + assertEquals(3, m.getEnd()); + sr = MappingUtils.buildSearchResults(aseq1, 2, acfList); + assertEquals(1, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(4, m.getStart()); + assertEquals(6, m.getEnd()); + + /* + * Check inverse mappings, from codons 1-3, 4-6 to protein 1, 2 + */ + for (int i = 1; i < 7; i++) + { + sr = MappingUtils.buildSearchResults(seq1, i, acfList); + assertEquals(1, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(aseq1.getDatasetSequence(), m.getSequence()); + int residue = i > 3 ? 2 : 1; + assertEquals(residue, m.getStart()); + assertEquals(residue, m.getEnd()); + } + } + + /** + * Simple test of mapping with introns involved. + */ + @Test + public void testBuildSearchResults_withIntro() + { + final Sequence seq1 = new Sequence("Seq1", "C-G-TAGA-GCAGCTT"); + seq1.createDatasetSequence(); + + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + + /* + * Map dna bases [2, 4, 5], [7, 9, 11] to protein residues 1 and 2 + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 2, 2, 4, 5, 7, 7, 9, 9, 11, 11 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + Set acfList = Collections.singleton(acf); + + /* + * Check protein residue 1 maps to [2, 4, 5] + */ + SearchResults sr = MappingUtils.buildSearchResults(aseq1, 1, acfList); + assertEquals(2, sr.getResults().size()); + Match m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(2, m.getStart()); + assertEquals(2, m.getEnd()); + m = sr.getResults().get(1); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(4, m.getStart()); + assertEquals(5, m.getEnd()); + + /* + * Check protein residue 2 maps to [7, 9, 11] + */ + sr = MappingUtils.buildSearchResults(aseq1, 2, acfList); + assertEquals(3, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(7, m.getStart()); + assertEquals(7, m.getEnd()); + m = sr.getResults().get(1); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(9, m.getStart()); + assertEquals(9, m.getEnd()); + m = sr.getResults().get(2); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(11, m.getStart()); + assertEquals(11, m.getEnd()); + + /* + * Check inverse mappings, from codons to protein + */ + for (int i = 1; i < 14; i++) + { + sr = MappingUtils.buildSearchResults(seq1, i, acfList); + int residue = (i == 2 || i == 4 || i == 5) ? 1 : (i == 7 || i == 9 + || i == 11 ? 2 : 0); + if (residue == 0) + { + assertEquals(0, sr.getResults().size()); + continue; + } + assertEquals(1, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(aseq1.getDatasetSequence(), m.getSequence()); + assertEquals(residue, m.getStart()); + assertEquals(residue, m.getEnd()); + } + } + + /** + * Test mapping a sequence group. + * + * @throws IOException + */ + @Test + public void testMapSequenceGroup() throws IOException + { + /* + * Set up dna and protein Seq1/2/3 with mappings (held on the protein + * viewport). + */ + AlignmentI cdna = loadAlignment(">Seq1\nACG\n>Seq2\nTGA\n>Seq3\nTAC\n", + "FASTA"); + cdna.setDataset(null); + AlignmentI protein = loadAlignment(">Seq1\nK\n>Seq2\nL\n>Seq3\nQ\n", + "FASTA"); + protein.setDataset(null); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 1, 3 }, new int[] + { 1, 1 }, 3, 1); + for (int seq = 0; seq < 3; seq++) + { + acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), protein + .getSequenceAt(seq).getDatasetSequence(), map); + } + Set acfList = Collections.singleton(acf); + + AlignViewportI dnaView = new AlignViewport(cdna); + AlignViewportI proteinView = new AlignViewport(protein); + protein.setCodonFrames(acfList); + + /* + * Select Seq1 and Seq3 in the protein + */ + SequenceGroup sg = new SequenceGroup(); + sg.setColourText(true); + sg.setIdColour(Color.GREEN); + sg.setOutlineColour(Color.LIGHT_GRAY); + sg.addSequence(protein.getSequenceAt(0), false); + sg.addSequence(protein.getSequenceAt(2), false); + + /* + * Verify the mapped sequence group in dna + */ + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, proteinView, dnaView); + assertTrue(mappedGroup.getColourText()); + assertSame(sg.getIdColour(), mappedGroup.getIdColour()); + assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); + assertEquals(2, mappedGroup.getSequences().size()); + assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0)); + assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(1)); + + /* + * Verify mapping sequence group from dna to protein + */ + sg.clear(); + sg.addSequence(cdna.getSequenceAt(1), false); + sg.addSequence(cdna.getSequenceAt(0), false); + mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); + assertTrue(mappedGroup.getColourText()); + assertSame(sg.getIdColour(), mappedGroup.getIdColour()); + assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); + assertEquals(2, mappedGroup.getSequences().size()); + assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(0)); + assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(1)); + } + + /** + * Helper method to load an alignment and ensure dataset sequences are set up. + * + * @param data + * @param format + * TODO + * @return + * @throws IOException + */ + protected AlignmentI loadAlignment(final String data, String format) + throws IOException + { + Alignment a = new FormatAdapter().readFile(data, + AppletFormatAdapter.PASTE, format); + a.setDataset(null); + return a; + } + + /** + * Test mapping a column selection in protein to its dna equivalent + * + * @throws IOException + */ + @Test + public void testMapColumnSelection_proteinToDna() throws IOException + { + setupMappedAlignments(); + + ColumnSelection colsel = new ColumnSelection(); + + /* + * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3 + * in dna respectively, overall 0-4 + */ + colsel.addElement(0); + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, + proteinView, dnaView); + assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString()); + + /* + * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna + */ + colsel.clear(); + colsel.addElement(1); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[0, 1, 2, 3]", cs.getSelected().toString()); + + /* + * Column 2 in protein picks up gaps only - no mapping + */ + colsel.clear(); + colsel.addElement(2); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[]", cs.getSelected().toString()); + + /* + * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns + * 6-9, 6-10, 5-8 respectively, overall to 5-10 + */ + colsel.clear(); + colsel.addElement(3); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[5, 6, 7, 8, 9, 10]", cs.getSelected().toString()); + + /* + * Combine selection of columns 1 and 3 to get a discontiguous mapped + * selection + */ + colsel.clear(); + colsel.addElement(1); + colsel.addElement(3); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[0, 1, 2, 3, 5, 6, 7, 8, 9, 10]", cs.getSelected() + .toString()); + } + + /** + * @throws IOException + */ + protected void setupMappedAlignments() throws IOException + { + /* + * Set up dna and protein Seq1/2/3 with mappings (held on the protein + * viewport). Lower case for introns. + */ + AlignmentI cdna = loadAlignment(">Seq1\nAC-GctGtC-T\n" + + ">Seq2\nTc-GA-G-T-Tc\n" + ">Seq3\nTtTT-AaCGg-\n", + "FASTA"); + cdna.setDataset(null); + AlignmentI protein = loadAlignment( + ">Seq1\n-K-P\n>Seq2\nL--Q\n>Seq3\nG--S\n", + "FASTA"); + protein.setDataset(null); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 1, 3, 6, 6, 8, 9 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(cdna.getSequenceAt(0).getDatasetSequence(), protein + .getSequenceAt(0).getDatasetSequence(), map); + map = new MapList(new int[] + { 1, 1, 3, 4, 5, 7 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(cdna.getSequenceAt(1).getDatasetSequence(), protein + .getSequenceAt(1).getDatasetSequence(), map); + map = new MapList(new int[] + { 1, 1, 3, 4, 5, 5, 7, 8 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(cdna.getSequenceAt(2).getDatasetSequence(), protein + .getSequenceAt(2).getDatasetSequence(), map); + Set acfList = Collections.singleton(acf); + + dnaView = new AlignViewport(cdna); + proteinView = new AlignViewport(protein); + protein.setCodonFrames(acfList); + } + + /** + * Test mapping a column selection including hidden columns + * + * @throws IOException + */ + @Test + public void testMapColumnSelection_hiddenColumns() throws IOException + { + setupMappedAlignments(); + + ColumnSelection colsel = new ColumnSelection(); + + /* + * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3 + * in dna respectively, overall 0-4 + */ + colsel.addElement(0); + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, + proteinView, dnaView); + assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString()); + + fail("write me"); + } + + /** + * Test mapping a column selection in dna to its protein equivalent + * + * @throws IOException + */ + @Test + public void testMapColumnSelection_dnaToProtein() throws IOException + { + setupMappedAlignments(); + + ColumnSelection colsel = new ColumnSelection(); + + /* + * Column 0 in dna picks up first bases which map to residue 1, columns 0-1 + * in protein. + */ + colsel.addElement(0); + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, dnaView, + proteinView); + assertEquals("[0, 1]", cs.getSelected().toString()); + + /* + * Columns 3-5 in dna map to the first residues in protein Seq1, Seq2, and + * the first two in Seq3. Overall to columns 0, 1, 3 (col2 is all gaps). + */ + colsel.addElement(3); + colsel.addElement(4); + colsel.addElement(5); + cs = MappingUtils.mapColumnSelection(colsel, dnaView, proteinView); + assertEquals("[0, 1, 3]", cs.getSelected().toString()); + } +} diff --git a/test/jalview/util/QuickSortTest.java b/test/jalview/util/QuickSortTest.java new file mode 100644 index 0000000..03aa463 --- /dev/null +++ b/test/jalview/util/QuickSortTest.java @@ -0,0 +1,98 @@ +package jalview.util; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class QuickSortTest +{ + private static final String c1 = "Blue"; + + private static final String c2 = "Yellow"; + + private static final String c3 = "Orange"; + + private static final String c4 = "Green"; + + private Object[] things; + + private final Object[] sortedThings = new Object[] + { c4, c2, c1, c3 }; + + @Before + public void setUp() + { + things = new Object[] + { c1, c2, c3, c4 }; + } + + @Test + public void testSort_byIntValues() + { + int[] values = new int[] + { 3, 2, 4, 1 }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new int[] + { 1, 2, 3, 4 }, values)); + assertTrue(Arrays.equals(sortedThings, things)); + } + + @Test + public void testSort_byFloatValues() + { + float[] values = new float[] + { 3f, 2f, 4f, 1f }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new float[] + { 1f, 2f, 3f, 4f }, values)); + assertTrue(Arrays.equals(sortedThings, things)); + } + + @Test + public void testSort_byDoubleValues() + { + double[] values = new double[] + { 3d, 2d, 4d, 1d }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new double[] + { 1d, 2d, 3d, 4d }, values)); + assertTrue(Arrays.equals(sortedThings, things)); + } + + /** + * Sort by String is descending order, case-sensitive + */ + @Test + public void testSort_byStringValues() + { + String[] values = new String[] + { "JOHN", "henry", "lucy", "ALISON" }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new String[] + { "lucy", "henry", "JOHN", "ALISON" }, values)); + assertTrue(Arrays.equals(new Object[] + { c3, c2, c1, c4 }, things)); + } + + /** + * Test whether sort is stable i.e. equal values retain their mutual ordering. + */ + @Test + @Ignore + public void testSort_withDuplicates() + { + int[] values = new int[] + { 3, 4, 2, 4, 1 }; + Object [] things = new Object [] {"A", "X", "Y", "B", "Z"}; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new int[] + { 1, 2, 3, 4, 4 }, values)); + // this fails - do we care? + assertTrue(Arrays.equals(new Object[] + { "Z", "Y", "A", "X", "B" }, things)); + } +} diff --git a/test/jalview/util/ShiftListTest.java b/test/jalview/util/ShiftListTest.java new file mode 100644 index 0000000..f680d6c --- /dev/null +++ b/test/jalview/util/ShiftListTest.java @@ -0,0 +1,35 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class ShiftListTest +{ + + @Test + public void testParseMap() + { + assertNull(ShiftList.parseMap(null)); + assertNull(ShiftList.parseMap(new int[] + {})); + + /* + * Gap map showing residues in aligned positions 2,3,6,8,9,10,12 + */ + int[] gm = new int[] + { 2, 3, 6, 8, 9, 10, 12 }; + List shifts = ShiftList.parseMap(gm).getShifts(); + assertEquals(4, shifts.size()); + + // TODO are these results (which pass) correct?? + assertEquals("[0, 2]", Arrays.toString(shifts.get(0))); + assertEquals("[4, 2]", Arrays.toString(shifts.get(1))); + assertEquals("[7, 1]", Arrays.toString(shifts.get(2))); + assertEquals("[11, 1]", Arrays.toString(shifts.get(3))); + } +} diff --git a/test/jalview/util/StringUtilsTest.java b/test/jalview/util/StringUtilsTest.java new file mode 100644 index 0000000..22a4130 --- /dev/null +++ b/test/jalview/util/StringUtilsTest.java @@ -0,0 +1,71 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +public class StringUtilsTest +{ + + @Test + public void testInsertCharAt() + { + char[] c1 = "ABC".toCharArray(); + char[] expected = new char[] + { 'A', 'B', 'C', 'w', 'w' }; + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 3, 2, 'w'))); + expected = new char[] + { 'A', 'B', 'C', 'w', 'w' }; + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 4, 2, 'w'))); + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 5, 2, 'w'))); + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 6, 2, 'w'))); + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 7, 2, 'w'))); + } + + @Test + public void testDeleteChars() + { + char[] c1 = "ABC".toCharArray(); + + // delete second position + assertTrue(Arrays.equals(new char[] + { 'A', 'C' }, StringUtils.deleteChars(c1, 1, 2))); + + // delete positions 1 and 2 + assertTrue(Arrays.equals(new char[] + { 'C' }, StringUtils.deleteChars(c1, 0, 2))); + + // delete positions 1-3 + assertTrue(Arrays.equals(new char[] + {}, StringUtils.deleteChars(c1, 0, 3))); + + // delete position 3 + assertTrue(Arrays.equals(new char[] + { 'A', 'B' }, StringUtils.deleteChars(c1, 2, 3))); + + // out of range deletion is ignore + assertTrue(Arrays.equals(c1, StringUtils.deleteChars(c1, 3, 4))); + } + + @Test + public void testGetLastToken() + { + assertNull(StringUtils.getLastToken(null, null)); + assertNull(StringUtils.getLastToken(null, "/")); + assertEquals("a", StringUtils.getLastToken("a", null)); + + assertEquals("abc", StringUtils.getLastToken("abc", "/")); + assertEquals("c", StringUtils.getLastToken("abc", "b")); + assertEquals("file1.dat", StringUtils.getLastToken( + "file://localhost:8080/data/examples/file1.dat", "/")); + } +} diff --git a/test/jalview/viewmodel/styles/TestviewStyle.java b/test/jalview/viewmodel/styles/TestviewStyle.java new file mode 100644 index 0000000..88ea82e --- /dev/null +++ b/test/jalview/viewmodel/styles/TestviewStyle.java @@ -0,0 +1,23 @@ +package jalview.viewmodel.styles; + +import org.junit.Assert; +import org.junit.Test; + +public class TestviewStyle +{ + + @Test + public void testSetterGetter() + { + ViewStyle orig = new ViewStyle(); + orig.setCharHeight(23); + orig.setWrappedWidth(253); + orig.setWrapAlignment(true); + ViewStyle copy = new ViewStyle(orig); + orig.setWrapAlignment(false); + Assert.assertEquals(copy.getCharHeight(), orig.getCharHeight()); + Assert.assertEquals(copy.getWrappedWidth(), orig.getWrappedWidth()); + Assert.assertEquals(copy.getWrapAlignment(), !orig.getWrapAlignment()); + } + +}