updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
authorjprocter <Jim Procter>
Sun, 10 Sep 2006 12:48:27 +0000 (12:48 +0000)
committerjprocter <Jim Procter>
Sun, 10 Sep 2006 12:48:27 +0000 (12:48 +0000)
198 files changed:
src/MCview/AppletPDBCanvas.java
src/MCview/AppletPDBViewer.java
src/MCview/Atom.java
src/MCview/Bond.java
src/MCview/MCMatrix.java
src/MCview/PDBCanvas.java
src/MCview/PDBChain.java
src/MCview/PDBViewer.java
src/MCview/PDBfile.java
src/MCview/Residue.java
src/MCview/Zsort.java
src/ext/vamsas/MuscleWS.java
src/ext/vamsas/MuscleWSService.java
src/ext/vamsas/MuscleWSServiceLocator.java
src/ext/vamsas/MuscleWSSoapBindingStub.java
src/jalview/analysis/AAFrequency.java
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/AlignmentSorter.java
src/jalview/analysis/Conservation.java
src/jalview/analysis/NJTree.java
src/jalview/analysis/PCA.java
src/jalview/analysis/SeqsetUtils.java
src/jalview/analysis/SequenceIdMatcher.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/AnnotationColourChooser.java
src/jalview/appletgui/AnnotationLabels.java
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/ColumnSelection.java [deleted file]
src/jalview/appletgui/CutAndPasteTransfer.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/FeatureSettings.java
src/jalview/appletgui/Finder.java
src/jalview/appletgui/FontChooser.java
src/jalview/appletgui/IdCanvas.java
src/jalview/appletgui/IdPanel.java
src/jalview/appletgui/IdwidthAdjuster.java
src/jalview/appletgui/OverviewPanel.java
src/jalview/appletgui/PCAPanel.java
src/jalview/appletgui/PaintRefresher.java
src/jalview/appletgui/PairwiseAlignPanel.java
src/jalview/appletgui/RedundancyPanel.java
src/jalview/appletgui/RotatableCanvas.java
src/jalview/appletgui/ScalePanel.java
src/jalview/appletgui/SeqCanvas.java
src/jalview/appletgui/SeqPanel.java
src/jalview/appletgui/SequenceRenderer.java
src/jalview/appletgui/SliderPanel.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/appletgui/TreePanel.java
src/jalview/appletgui/UserDefinedColours.java
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/datamodel/AlignmentI.java
src/jalview/datamodel/AlignmentOrder.java
src/jalview/datamodel/Annotation.java
src/jalview/datamodel/BinaryNode.java
src/jalview/datamodel/BinarySequence.java
src/jalview/datamodel/DBRefEntry.java
src/jalview/datamodel/GraphLine.java
src/jalview/datamodel/HiddenSequences.java
src/jalview/datamodel/HistoryItem.java
src/jalview/datamodel/PDBEntry.java
src/jalview/datamodel/Provenance.java
src/jalview/datamodel/ProvenanceEntry.java
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceFeature.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/datamodel/SequenceI.java
src/jalview/datamodel/SequenceNode.java
src/jalview/datamodel/SequencePoint.java
src/jalview/datamodel/UniprotEntry.java
src/jalview/datamodel/UniprotFile.java
src/jalview/datamodel/UniprotSequence.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationColourChooser.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/ColumnSelection.java [deleted file]
src/jalview/gui/CutAndPasteTransfer.java
src/jalview/gui/Desktop.java
src/jalview/gui/EPSOptions.java
src/jalview/gui/FeatureRenderer.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/Finder.java
src/jalview/gui/FontChooser.java
src/jalview/gui/IdCanvas.java
src/jalview/gui/IdPanel.java
src/jalview/gui/IdwidthAdjuster.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/OverviewPanel.java
src/jalview/gui/PCAPanel.java
src/jalview/gui/PaintRefresher.java
src/jalview/gui/PairwiseAlignPanel.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/Preferences.java
src/jalview/gui/RedundancyPanel.java
src/jalview/gui/RotatableCanvas.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/SequenceFetcher.java
src/jalview/gui/SequenceRenderer.java
src/jalview/gui/SliderPanel.java
src/jalview/gui/SplashScreen.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/TreePanel.java
src/jalview/gui/UserDefinedColours.java
src/jalview/gui/WebserviceInfo.java
src/jalview/io/AlignFile.java
src/jalview/io/AnnotationReader.java [deleted file]
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/BLCFile.java
src/jalview/io/ClustalFile.java
src/jalview/io/EBIFetchClient.java
src/jalview/io/FastaFile.java
src/jalview/io/FileLoader.java
src/jalview/io/FileParse.java
src/jalview/io/FormatAdapter.java
src/jalview/io/HTMLOutput.java
src/jalview/io/IdentifyFile.java
src/jalview/io/JPredFile.java
src/jalview/io/JalviewFileChooser.java
src/jalview/io/JalviewFileFilter.java
src/jalview/io/JalviewFileView.java
src/jalview/io/MSFfile.java
src/jalview/io/ModellerDescription.java
src/jalview/io/NewickFile.java
src/jalview/io/PIRFile.java
src/jalview/io/PfamFile.java
src/jalview/io/PileUpfile.java
src/jalview/io/SequenceFeatureFetcher.java [deleted file]
src/jalview/io/VamsasDatastore.java
src/jalview/io/WSWUBlastClient.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GAlignmentPanel.java
src/jalview/jbgui/GCutAndPasteTransfer.java
src/jalview/jbgui/GDesktop.java
src/jalview/jbgui/GFinder.java
src/jalview/jbgui/GFontChooser.java
src/jalview/jbgui/GPCAPanel.java
src/jalview/jbgui/GPairwiseAlignPanel.java
src/jalview/jbgui/GPreferences.java
src/jalview/jbgui/GSequenceLink.java
src/jalview/jbgui/GSliderPanel.java
src/jalview/jbgui/GTreePanel.java
src/jalview/jbgui/GUserDefinedColours.java
src/jalview/jbgui/GWebserviceInfo.java
src/jalview/math/Matrix.java
src/jalview/math/RotatableMatrix.java
src/jalview/schemes/AnnotationColourGradient.java
src/jalview/schemes/Blosum62ColourScheme.java
src/jalview/schemes/BuriedColourScheme.java
src/jalview/schemes/ClustalxColourScheme.java
src/jalview/schemes/ColourSchemeI.java
src/jalview/schemes/ColourSchemeProperty.java
src/jalview/schemes/Consensus.java
src/jalview/schemes/HelixColourScheme.java
src/jalview/schemes/HydrophobicColourScheme.java
src/jalview/schemes/NucleotideColourScheme.java
src/jalview/schemes/PIDColourScheme.java
src/jalview/schemes/ResidueColourScheme.java
src/jalview/schemes/ResidueProperties.java
src/jalview/schemes/ScoreColourScheme.java
src/jalview/schemes/StrandColourScheme.java
src/jalview/schemes/TaylorColourScheme.java
src/jalview/schemes/TurnColourScheme.java
src/jalview/schemes/UserColourScheme.java
src/jalview/schemes/ZappoColourScheme.java
src/jalview/util/BrowserLauncher.java
src/jalview/util/Comparison.java
src/jalview/util/DBRefUtils.java
src/jalview/util/ImageMaker.java
src/jalview/util/QuickSort.java
src/jalview/ws/Discoverer.java
src/jalview/ws/JPredClient.java
src/jalview/ws/MsaWSClient.java
src/jalview/ws/WSClient.java
src/jalview/ws/WSClientI.java
src/vamsas/IMsaWS.java
src/vamsas/objects/simple/Alignment.java
src/vamsas/objects/simple/Alignment_Helper.java
src/vamsas/objects/simple/MsaResult.java
src/vamsas/objects/simple/MsaResult_Helper.java
src/vamsas/objects/simple/Object.java
src/vamsas/objects/simple/Object_Helper.java
src/vamsas/objects/simple/SequenceSet.java
src/vamsas/objects/simple/SequenceSet_Helper.java
src/vamsas/objects/simple/WsJobId.java
src/vamsas/objects/simple/WsJobId_Helper.java

index 107d98d..9689468 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import jalview.analysis.AlignSeq;\r
-\r
-import jalview.datamodel.*;\r
-\r
-// JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-\r
-public class AppletPDBCanvas extends Panel implements MouseListener, MouseMotionListener\r
-{\r
-\r
-    MCMatrix idmat = new MCMatrix(3, 3);\r
-    MCMatrix objmat = new MCMatrix(3, 3);\r
-    boolean redrawneeded = true;\r
-    int omx = 0;\r
-    int mx = 0;\r
-    int omy = 0;\r
-    int my = 0;\r
-    public PDBfile pdb;\r
-    int bsize;\r
-    Image img;\r
-    Graphics ig;\r
-    Dimension prefsize;\r
-    float[] centre = new float[3];\r
-    float[] width = new float[3];\r
-    float maxwidth;\r
-    float scale;\r
-    String inStr;\r
-    String inType;\r
-    boolean bysequence = true;\r
-    boolean depthcue = true;\r
-    boolean wire = false;\r
-    boolean bymolecule = false;\r
-    boolean zbuffer = true;\r
-    boolean dragging;\r
-    int xstart;\r
-    int xend;\r
-    int ystart;\r
-    int yend;\r
-    int xmid;\r
-    int ymid;\r
-    Font font = new Font("Helvetica", Font.PLAIN, 10);\r
-    jalview.appletgui.SeqCanvas seqcanvas;\r
-    public Sequence sequence;\r
-    final StringBuffer mappingDetails = new StringBuffer();\r
-    String appletToolTip = null;\r
-    int toolx, tooly;\r
-    PDBChain mainchain;\r
-    Vector highlightRes;\r
-    boolean pdbAction = false;\r
-    Bond highlightBond1, highlightBond2;\r
-    boolean errorLoading = false;\r
-    boolean seqColoursReady = false;\r
-    jalview.appletgui.FeatureRenderer fr;\r
-\r
-    public AppletPDBCanvas(jalview.appletgui.SeqCanvas seqcanvas, Sequence seq)\r
-    {\r
-      this.seqcanvas = seqcanvas;\r
-      this.sequence = seq;\r
-\r
-      seqcanvas.setPDBCanvas(this);\r
-      addKeyListener(new KeyAdapter()\r
-      {\r
-\r
-        public void keyPressed(KeyEvent evt)\r
-        {\r
-          doKeyPressed(evt);\r
-        }\r
-      });\r
-    }\r
-\r
-\r
-  public void setPDBFile(PDBfile pdb)\r
-   {\r
-        int max = -10;\r
-        int maxchain = -1;\r
-        int pdbstart = 0;\r
-        int pdbend = 0;\r
-        int seqstart = 0;\r
-        int seqend = 0;\r
-        AlignSeq maxAlignseq = null;;\r
-\r
-        for (int i = 0; i < pdb.chains.size(); i++)\r
-        {\r
-\r
-          mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());\r
-          mappingDetails.append("\nNo of residues = " + ((PDBChain) pdb.chains.elementAt(i)).residues.size()+"\n\n");\r
-\r
-            // Now lets compare the sequences to get\r
-            // the start and end points.\r
-            // Align the sequence to the pdb\r
-            AlignSeq as = new AlignSeq(sequence,\r
-                    ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
-            as.calcScoreMatrix();\r
-            as.traceAlignment();\r
-            PrintStream ps = new PrintStream(System.out)\r
-           {\r
-              public void print(String x) {\r
-                   mappingDetails.append(x);\r
-               }\r
-               public void println()\r
-               {\r
-                 mappingDetails.append("\n");\r
-               }\r
-            };\r
-\r
-            as.printAlignment(ps);\r
-\r
-            if (as.maxscore > max) {\r
-                max = as.maxscore;\r
-                maxchain = i;\r
-\r
-                pdbstart = as.seq2start;\r
-                pdbend = as.seq2end;\r
-                seqstart = as.seq1start + sequence.getStart()-1;\r
-                seqend = as.seq1end + sequence.getEnd()-1;\r
-                maxAlignseq = as;\r
-            }\r
-\r
-            mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);\r
-            mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);\r
-        }\r
-\r
-        mainchain = (PDBChain) pdb.chains.elementAt(maxchain);\r
-\r
-        mainchain.pdbstart = pdbstart;\r
-        mainchain.pdbend = pdbend;\r
-        mainchain.seqstart = seqstart;\r
-        mainchain.seqend = seqend;\r
-        mainchain.isVisible = true;\r
-        mainchain.makeExactMapping(maxAlignseq, sequence);\r
-\r
-        this.pdb = pdb;\r
-        this.prefsize = new Dimension(getSize().width, getSize().height);\r
-\r
-        //Initialize the matrices to identity\r
-        for (int i = 0; i < 3; i++) {\r
-            for (int j = 0; j < 3; j++) {\r
-                if (i != j) {\r
-                    idmat.addElement(i, j, 0);\r
-                    objmat.addElement(i, j, 0);\r
-                } else {\r
-                    idmat.addElement(i, j, 1);\r
-                    objmat.addElement(i, j, 1);\r
-                }\r
-            }\r
-        }\r
-\r
-        addMouseMotionListener(this);\r
-        addMouseListener(this);\r
-\r
-\r
-        findCentre();\r
-        findWidth();\r
-\r
-        setupBonds();\r
-\r
-        scale = findScale();\r
-    }\r
-\r
-\r
-    Vector visiblebonds;\r
-    void setupBonds()\r
-    {\r
-      seqColoursReady = false;\r
-      // Sort the bonds by z coord\r
-      visiblebonds = new Vector();\r
-\r
-      for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-      {\r
-        if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
-        {\r
-          Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-          for (int i = 0; i < tmp.size(); i++)\r
-          {\r
-            visiblebonds.addElement(tmp.elementAt(i));\r
-          }\r
-        }\r
-      }\r
-      updateSeqColours();\r
-      seqColoursReady = true;\r
-      redrawneeded = true;\r
-      repaint();\r
-    }\r
-\r
-\r
-    public void findWidth() {\r
-        float[] max = new float[3];\r
-        float[] min = new float[3];\r
-\r
-        max[0] = (float) -1e30;\r
-        max[1] = (float) -1e30;\r
-        max[2] = (float) -1e30;\r
-\r
-        min[0] = (float) 1e30;\r
-        min[1] = (float) 1e30;\r
-        min[2] = (float) 1e30;\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
-            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                for (int i = 0; i < bonds.size(); i++) {\r
-                    Bond tmp = (Bond) bonds.elementAt(i);\r
-\r
-                    if (tmp.start[0] >= max[0]) {\r
-                        max[0] = tmp.start[0];\r
-                    }\r
-\r
-                    if (tmp.start[1] >= max[1]) {\r
-                        max[1] = tmp.start[1];\r
-                    }\r
-\r
-                    if (tmp.start[2] >= max[2]) {\r
-                        max[2] = tmp.start[2];\r
-                    }\r
-\r
-                    if (tmp.start[0] <= min[0]) {\r
-                        min[0] = tmp.start[0];\r
-                    }\r
-\r
-                    if (tmp.start[1] <= min[1]) {\r
-                        min[1] = tmp.start[1];\r
-                    }\r
-\r
-                    if (tmp.start[2] <= min[2]) {\r
-                        min[2] = tmp.start[2];\r
-                    }\r
-\r
-                    if (tmp.end[0] >= max[0]) {\r
-                        max[0] = tmp.end[0];\r
-                    }\r
-\r
-                    if (tmp.end[1] >= max[1]) {\r
-                        max[1] = tmp.end[1];\r
-                    }\r
-\r
-                    if (tmp.end[2] >= max[2]) {\r
-                        max[2] = tmp.end[2];\r
-                    }\r
-\r
-                    if (tmp.end[0] <= min[0]) {\r
-                        min[0] = tmp.end[0];\r
-                    }\r
-\r
-                    if (tmp.end[1] <= min[1]) {\r
-                        min[1] = tmp.end[1];\r
-                    }\r
-\r
-                    if (tmp.end[2] <= min[2]) {\r
-                        min[2] = tmp.end[2];\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        width[0] = (float) Math.abs(max[0] - min[0]);\r
-        width[1] = (float) Math.abs(max[1] - min[1]);\r
-        width[2] = (float) Math.abs(max[2] - min[2]);\r
-\r
-        maxwidth = width[0];\r
-\r
-        if (width[1] > width[0]) {\r
-            maxwidth = width[1];\r
-        }\r
-\r
-        if (width[2] > width[1]) {\r
-            maxwidth = width[2];\r
-        }\r
-\r
-       // System.out.println("Maxwidth = " + maxwidth);\r
-    }\r
-\r
-    public float findScale() {\r
-        int dim;\r
-        int width;\r
-        int height;\r
-\r
-        if (getSize().width != 0) {\r
-            width = getSize().width;\r
-            height = getSize().height;\r
-        } else {\r
-            width = prefsize.width;\r
-            height = prefsize.height;\r
-        }\r
-\r
-        if (width < height) {\r
-            dim = width;\r
-        } else {\r
-            dim = height;\r
-        }\r
-\r
-        return (float) (dim / (1.5d * maxwidth));\r
-    }\r
-\r
-    public void findCentre() {\r
-        float xtot = 0;\r
-        float ytot = 0;\r
-        float ztot = 0;\r
-\r
-        int bsize = 0;\r
-\r
-        //Find centre coordinate\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
-            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                bsize += bonds.size();\r
-\r
-                for (int i = 0; i < bonds.size(); i++) {\r
-                    xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
-                        ((Bond) bonds.elementAt(i)).end[0];\r
-\r
-                    ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
-                        ((Bond) bonds.elementAt(i)).end[1];\r
-\r
-                    ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
-                        ((Bond) bonds.elementAt(i)).end[2];\r
-                }\r
-            }\r
-        }\r
-\r
-        centre[0] = xtot / (2 * (float) bsize);\r
-        centre[1] = ytot / (2 * (float) bsize);\r
-        centre[2] = ztot / (2 * (float) bsize);\r
-    }\r
-\r
-    public void paint(Graphics g)\r
-    {\r
-\r
-      if(errorLoading)\r
-      {\r
-        g.setColor(Color.white);\r
-        g.fillRect(0,0,getSize().width, getSize().height);\r
-        g.setColor(Color.black);\r
-        g.setFont(new Font("Verdana", Font.BOLD, 14));\r
-        g.drawString("Error loading PDB data!!", 50, getSize().height/2);\r
-        return;\r
-      }\r
-\r
-      if( !seqColoursReady )\r
-      {\r
-        g.setColor(Color.black);\r
-        g.setFont(new Font("Verdana", Font.BOLD, 14));\r
-        g.drawString("Fetching PDB data...", 50, getSize().height/2);\r
-        return;\r
-      }\r
-\r
-\r
-\r
-        //Only create the image at the beginning -\r
-        //this saves much memory usage\r
-        if ((img == null) || (prefsize.width != getSize().width) ||\r
-                (prefsize.height != getSize().height)) {\r
-\r
-         try{     prefsize.width = getSize().width;\r
-           prefsize.height = getSize().height;\r
-\r
-           scale = findScale();\r
-           img = createImage(prefsize.width, prefsize.height);\r
-           ig = img.getGraphics();\r
-\r
-           redrawneeded = true;\r
-         }catch(Exception ex)\r
-         {\r
-           ex.printStackTrace();\r
-         }\r
-        }\r
-\r
-\r
-        if (redrawneeded)\r
-        {\r
-          drawAll(ig, prefsize.width, prefsize.height);\r
-          redrawneeded = false;\r
-        }\r
-        if(appletToolTip!=null)\r
-        {\r
-          ig.setColor(Color.red);\r
-          ig.drawString(appletToolTip, toolx, tooly);\r
-        }\r
-\r
-        g.drawImage(img, 0, 0, this);\r
-\r
-        pdbAction = false;\r
-    }\r
-\r
-    public void drawAll(Graphics g, int width, int height)\r
-    {\r
-      ig.setColor(Color.black);\r
-      ig.fillRect(0, 0, width, height);\r
-      drawScene(ig);\r
-      drawLabels(ig);\r
-    }\r
-\r
-   void setColours(jalview.schemes.ColourSchemeI cs)\r
-   {\r
-     bysequence = false;\r
-     pdb.setColours(cs);\r
-     redrawneeded = true;\r
-     repaint();\r
-   }\r
-    public void updateSeqColours()\r
-    {\r
-      if (pdbAction)\r
-      {\r
-        return;\r
-      }\r
-\r
-      if(bysequence && pdb!=null)\r
-      {\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-        {\r
-          colourBySequence((PDBChain) pdb.chains.elementAt(ii));\r
-        }\r
-      }\r
-\r
-      redrawneeded=true;\r
-      repaint();\r
-    }\r
-\r
-\r
-    int findTrueIndex(int pos)\r
-    {\r
-      // returns the alignment position for a residue\r
-      int j = sequence.getStart();\r
-      int i = 0;\r
-\r
-      while ( (i < sequence.getLength()) && (j <= sequence.getEnd()) && (j <= pos+1))\r
-      {\r
-        if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))\r
-        {\r
-          j++;\r
-        }\r
-\r
-        i++;\r
-      }\r
-\r
-      if(i>1)\r
-         i--;\r
-\r
-      if ( (j == sequence.getEnd()) && (j < pos))\r
-      {\r
-        return sequence.getEnd() + 1;\r
-      }\r
-      else\r
-      {\r
-        return i;\r
-      }\r
-    }\r
-\r
-\r
-    // This method has been taken out of PDBChain to allow\r
-    // Applet and Application specific sequence renderers to be used\r
-    void colourBySequence(PDBChain chain)\r
-    {\r
-      boolean showFeatures = false;\r
-\r
-      if(seqcanvas.getViewport().getShowSequenceFeatures())\r
-        {\r
-          if(fr==null)\r
-          {\r
-            fr = new jalview.appletgui.FeatureRenderer(seqcanvas.getViewport());\r
-          }\r
-          fr.transferSettings( seqcanvas.getFeatureRenderer());\r
-          showFeatures = true;\r
-        }\r
-\r
-      for (int i = 0; i < chain.bonds.size(); i++)\r
-      {\r
-        Bond tmp = (Bond) chain.bonds.elementAt(i);\r
-        tmp.startCol = Color.lightGray;\r
-        tmp.endCol = Color.lightGray;\r
-        if(chain!=mainchain)\r
-          continue;\r
-\r
-        if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
-            (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))\r
-        {\r
-\r
-          int index = findTrueIndex(tmp.at1.alignmentMapping);\r
-                //sequence.findIndex(tmp.at1.alignmentMapping);\r
-            if (index != -1)\r
-            {\r
-              tmp.startCol = seqcanvas.getSequenceRenderer().\r
-                  getResidueBoxColour( sequence, index);\r
-\r
-              if(showFeatures)\r
-              tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);\r
-            }\r
-        }\r
-\r
-        int index =  findTrueIndex(tmp.at2.alignmentMapping);\r
-            //sequence.findIndex( tmp.at2.alignmentMapping );\r
-        if (index != -1)\r
-        {\r
-          tmp.endCol = seqcanvas.getSequenceRenderer().\r
-              getResidueBoxColour( sequence, index);\r
-\r
-          if(showFeatures)\r
-          tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);\r
-        }\r
-      }\r
-    }\r
-\r
-\r
-    Zsort zsort;\r
-    public void drawScene(Graphics g)\r
-    {\r
-        if (zbuffer)\r
-        {\r
-          if(zsort ==null)\r
-            zsort = new Zsort();\r
-\r
-          zsort.Zsort(visiblebonds);\r
-        }\r
-\r
-\r
-        Bond tmpBond=null;\r
-        for (int i = 0; i < visiblebonds.size(); i++)\r
-        {\r
-            tmpBond = (Bond) visiblebonds.elementAt(i);\r
-\r
-\r
-            xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
-                (getSize().width / 2));\r
-            ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
-                (getSize().height / 2));\r
-\r
-            xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
-                (getSize().width / 2));\r
-            yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
-                (getSize().height / 2));\r
-\r
-            xmid = (xend + xstart) / 2;\r
-            ymid = (yend + ystart) / 2;\r
-\r
-            if (depthcue && !bymolecule)\r
-            {\r
-                if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
-                    g.setColor(tmpBond.startCol.darker().darker());\r
-                    drawLine(g, xstart, ystart, xmid, ymid);\r
-\r
-                    g.setColor(tmpBond.endCol.darker().darker());\r
-                    drawLine(g, xmid, ymid, xend, yend);\r
-                } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
-                    g.setColor(tmpBond.startCol.darker());\r
-                    drawLine(g, xstart, ystart, xmid, ymid);\r
-\r
-                    g.setColor(tmpBond.endCol.darker());\r
-                    drawLine(g, xmid, ymid, xend, yend);\r
-                } else {\r
-                    g.setColor(tmpBond.startCol);\r
-                    drawLine(g, xstart, ystart, xmid, ymid);\r
-\r
-                    g.setColor(tmpBond.endCol);\r
-                    drawLine(g, xmid, ymid, xend, yend);\r
-                }\r
-\r
-            } else if (depthcue && bymolecule) {\r
-                if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
-                    g.setColor(Color.green.darker().darker());\r
-                    drawLine(g, xstart, ystart, xend, yend);\r
-                } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
-                    g.setColor(Color.green.darker());\r
-                    drawLine(g, xstart, ystart, xend, yend);\r
-                } else {\r
-                    g.setColor(Color.green);\r
-                    drawLine(g, xstart, ystart, xend, yend);\r
-                }\r
-            } else if (!depthcue && !bymolecule) {\r
-                g.setColor(tmpBond.startCol);\r
-                drawLine(g, xstart, ystart, xmid, ymid);\r
-                g.setColor(tmpBond.endCol);\r
-                drawLine(g, xmid, ymid, xend, yend);\r
-            } else {\r
-                drawLine(g, xstart, ystart, xend, yend);\r
-            }\r
-\r
-            if(highlightBond1!=null && highlightBond1==tmpBond)\r
-            {\r
-              g.setColor(Color.white);\r
-              drawLine(g, xmid, ymid, xend, yend);\r
-            }\r
-\r
-            if(highlightBond2!=null && highlightBond2==tmpBond)\r
-            {\r
-              g.setColor(Color.white);\r
-              drawLine(g, xstart, ystart, xmid, ymid);\r
-            }\r
-\r
-        }\r
-    }\r
-\r
-    public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
-        if (!wire) {\r
-            if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
-                g.drawLine(x1, y1, x2, y2);\r
-                g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
-                g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
-            } else {\r
-                g.setColor(g.getColor().brighter());\r
-                g.drawLine(x1, y1, x2, y2);\r
-                g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
-                g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
-            }\r
-        } else {\r
-            g.drawLine(x1, y1, x2, y2);\r
-        }\r
-    }\r
-\r
-    public Dimension minimumsize() {\r
-        return prefsize;\r
-    }\r
-\r
-    public Dimension preferredsize() {\r
-        return prefsize;\r
-    }\r
-\r
-    public void doKeyPressed(KeyEvent evt)\r
-    {\r
-      if (evt.getKeyCode() == KeyEvent.VK_UP)\r
-      {\r
-        scale = (float) (scale * 1.1);\r
-        redrawneeded = true;\r
-        repaint();\r
-      }\r
-      else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
-      {\r
-        scale = (float) (scale * 0.9);\r
-        redrawneeded = true;\r
-        repaint();\r
-      }\r
-    }\r
-\r
-    public void mousePressed(MouseEvent e) {\r
-      pdbAction = true;\r
-      Atom fatom = findAtom(e.getX(), e.getY());\r
-      if(fatom!=null)\r
-      {\r
-        fatom.isSelected = !fatom.isSelected;\r
-\r
-        redrawneeded = true;\r
-        repaint();\r
-        if (foundchain != -1)\r
-        {\r
-          PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
-          if (chain == mainchain)\r
-          {\r
-            if (fatom.alignmentMapping != -1)\r
-            {\r
-              if (highlightRes == null)\r
-                highlightRes = new Vector();\r
-\r
-              if (highlightRes.contains(fatom.alignmentMapping+"" + ""))\r
-                highlightRes.removeElement(fatom.alignmentMapping + "");\r
-              else\r
-                highlightRes.addElement(fatom.alignmentMapping + "");\r
-            }\r
-          }\r
-        }\r
-\r
-        }\r
-        mx = e.getX();\r
-        my = e.getY();\r
-        omx = mx;\r
-        omy = my;\r
-        dragging = false;\r
-    }\r
-\r
-    public void mouseMoved(MouseEvent e) {\r
-      pdbAction = true;\r
-      if(highlightBond1!=null)\r
-      {\r
-        highlightBond1.at2.isSelected = false;\r
-        highlightBond2.at1.isSelected = false;\r
-        highlightBond1 = null;\r
-        highlightBond2 = null;\r
-      }\r
-\r
-        Atom fatom = findAtom(e.getX(), e.getY());\r
-\r
-        PDBChain chain = null;\r
-        if(foundchain!=-1)\r
-        {\r
-          chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
-          if(chain == mainchain)\r
-          {\r
-            highlightSeqcanvas( fatom.alignmentMapping );\r
-          }\r
-        }\r
-\r
-        if (fatom != null) {\r
-            toolx = e.getX();\r
-            tooly = e.getY();\r
-\r
-            appletToolTip = chain.id+":"+ fatom.resNumber+" "+ fatom.resName;\r
-            redrawneeded = true;\r
-            repaint();\r
-        } else {\r
-            highlightSeqcanvas( -1);\r
-            appletToolTip = null;\r
-            redrawneeded = true;\r
-            repaint();\r
-        }\r
-    }\r
-\r
-\r
-    void highlightSeqcanvas(int pos)\r
-    {\r
-      SearchResults searchResults = new SearchResults();\r
-      if(highlightRes!=null)\r
-      {\r
-        for (int i = 0; i < highlightRes.size(); i++)\r
-        {\r
-          int a = Integer.parseInt(highlightRes.elementAt(\r
-              i).toString())+1;\r
-\r
-          searchResults.addResult(sequence, a, a);\r
-        }\r
-      }\r
-\r
-      if(pos!=-1)\r
-      {\r
-        searchResults.addResult(sequence, pos+1, pos+1);\r
-      }\r
-\r
-      seqcanvas.highlightSearchResults(searchResults);\r
-    }\r
-\r
-\r
-    public void mouseClicked(MouseEvent e) {\r
-    }\r
-\r
-    public void mouseEntered(MouseEvent e) {\r
-    }\r
-\r
-    public void mouseExited(MouseEvent e) {\r
-    }\r
-\r
-    public void mouseDragged(MouseEvent evt) {\r
-        int x = evt.getX();\r
-        int y = evt.getY();\r
-        mx = x;\r
-        my = y;\r
-\r
-        MCMatrix objmat = new MCMatrix(3, 3);\r
-        objmat.setIdentity();\r
-\r
-        if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
-            objmat.rotatez((float) ((mx - omx)));\r
-        } else {\r
-            objmat.rotatex((float) ((my - omy)));\r
-            objmat.rotatey((float) ((omx - mx)));\r
-        }\r
-\r
-        //Alter the bonds\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
-            Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-            for (int i = 0; i < bonds.size(); i++) {\r
-                Bond tmpBond = (Bond) bonds.elementAt(i);\r
-\r
-                //Translate the bond so the centre is 0,0,0\r
-                tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
-\r
-                //Now apply the rotation matrix\r
-                tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
-                tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
-\r
-                //Now translate back again\r
-                tmpBond.translate(centre[0], centre[1], centre[2]);\r
-            }\r
-        }\r
-\r
-        objmat = null;\r
-\r
-        omx = mx;\r
-        omy = my;\r
-\r
-        dragging = true;\r
-\r
-        redrawneeded = true;\r
-\r
-        repaint();\r
-    }\r
-\r
-    public void mouseReleased(MouseEvent evt) {\r
-        dragging = false;\r
-        return;\r
-    }\r
-\r
-    void drawLabels(Graphics g) {\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-        {\r
-            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
-\r
-            if (chain.isVisible)\r
-            {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                for (int i = 0; i < bonds.size(); i++)\r
-                {\r
-                    Bond tmpBond = (Bond) bonds.elementAt(i);\r
-\r
-                    if (tmpBond.at1.isSelected)\r
-                    {\r
-                        labelAtom(g, tmpBond, 1);\r
-                    }\r
-\r
-                    if (tmpBond.at2.isSelected)\r
-                    {\r
-\r
-                        labelAtom(g, tmpBond, 2);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    public void labelAtom(Graphics g, Bond b, int n) {\r
-        g.setFont(font);\r
-\r
-        if (n == 1) {\r
-            int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
-                (getSize().width / 2));\r
-            int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
-                (getSize().height / 2));\r
-\r
-            g.setColor(Color.red);\r
-            g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
-        }\r
-\r
-        if (n == 2) {\r
-            int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
-                (getSize().width / 2));\r
-            int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
-                (getSize().height / 2));\r
-\r
-            g.setColor(Color.red);\r
-            g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
-        }\r
-    }\r
-\r
-    int foundchain = -1;\r
-    public Atom findAtom(int x, int y) {\r
-        Atom fatom = null;\r
-\r
-        foundchain = -1;\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-        {\r
-            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
-            int truex;\r
-            Bond tmpBond=null;\r
-\r
-            if (chain.isVisible)\r
-            {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                for (int i = 0; i < bonds.size(); i++)\r
-                {\r
-                    tmpBond = (Bond) bonds.elementAt(i);\r
-\r
-                    truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
-                        (getSize().width / 2));\r
-\r
-                    if (Math.abs(truex - x) <= 2)\r
-                    {\r
-                        int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
-                            (getSize().height / 2));\r
-\r
-                        if (Math.abs(truey - y) <= 2)\r
-                        {\r
-                            fatom = tmpBond.at1;\r
-                            foundchain = ii;\r
-                            break;\r
-                        }\r
-                    }\r
-                }\r
-\r
-                // Still here? Maybe its the last bond\r
-\r
-                truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +\r
-                               (getSize().width / 2));\r
-\r
-                if (Math.abs(truex - x) <= 2)\r
-                {\r
-                  int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +\r
-                                     (getSize().height / 2));\r
-\r
-                  if (Math.abs(truey - y) <= 2)\r
-                  {\r
-                    fatom = tmpBond.at2;\r
-                    foundchain = ii;\r
-                    break;\r
-                  }\r
-                }\r
-\r
-            }\r
-\r
-            if (fatom != null) //)&& chain.ds != null)\r
-             {\r
-                chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
-            }\r
-        }\r
-\r
-        return fatom;\r
-    }\r
-\r
-    public void update(Graphics g)\r
-    {\r
-      paint(g);\r
-    }\r
-\r
-    public void highlightRes(int ii)\r
-   {\r
-     if(!seqColoursReady)\r
-       return;\r
-\r
-     if (highlightRes != null\r
-         && highlightRes.contains((ii-1) + ""))\r
-     {\r
-       return;\r
-     }\r
-\r
-     int index = -1;\r
-     Bond tmpBond;\r
-     for(index=0; index<mainchain.bonds.size(); index++)\r
-     {\r
-       tmpBond = (Bond) mainchain.bonds.elementAt(index);\r
-       if (tmpBond.at1.alignmentMapping == ii - 1)\r
-       {\r
-         if (highlightBond1 != null)\r
-           highlightBond1.at2.isSelected = false;\r
-\r
-         if (highlightBond2 != null)\r
-           highlightBond2.at1.isSelected = false;\r
-\r
-         highlightBond1 = null;\r
-         highlightBond2 = null;\r
-\r
-         if (index > 0)\r
-         {\r
-           highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
-           highlightBond1.at2.isSelected = true;\r
-         }\r
-\r
-         if (index != mainchain.bonds.size())\r
-         {\r
-           highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
-           highlightBond2.at1.isSelected = true;\r
-         }\r
-\r
-         break;\r
-       }\r
-     }\r
-\r
-     redrawneeded = true;\r
-     repaint();\r
-   }\r
-\r
-\r
-    public void setAllchainsVisible(boolean b)\r
-    {\r
-      for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-      {\r
-        PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
-        chain.isVisible = b;\r
-      }\r
-      mainchain.isVisible = true;\r
-      findCentre();\r
-      setupBonds();\r
-    }\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import jalview.analysis.AlignSeq;
+
+import jalview.datamodel.*;
+
+// JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug
+import java.awt.*;
+import java.awt.event.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+
+public class AppletPDBCanvas extends Panel implements MouseListener, MouseMotionListener
+{
+
+    MCMatrix idmat = new MCMatrix(3, 3);
+    MCMatrix objmat = new MCMatrix(3, 3);
+    boolean redrawneeded = true;
+    int omx = 0;
+    int mx = 0;
+    int omy = 0;
+    int my = 0;
+    public PDBfile pdb;
+    int bsize;
+    Image img;
+    Graphics ig;
+    Dimension prefsize;
+    float[] centre = new float[3];
+    float[] width = new float[3];
+    float maxwidth;
+    float scale;
+    String inStr;
+    String inType;
+    boolean bysequence = true;
+    boolean depthcue = true;
+    boolean wire = false;
+    boolean bymolecule = false;
+    boolean zbuffer = true;
+    boolean dragging;
+    int xstart;
+    int xend;
+    int ystart;
+    int yend;
+    int xmid;
+    int ymid;
+    Font font = new Font("Helvetica", Font.PLAIN, 10);
+    jalview.appletgui.SeqCanvas seqcanvas;
+    public Sequence sequence;
+    final StringBuffer mappingDetails = new StringBuffer();
+    String appletToolTip = null;
+    int toolx, tooly;
+    PDBChain mainchain;
+    Vector highlightRes;
+    boolean pdbAction = false;
+    Bond highlightBond1, highlightBond2;
+    boolean errorLoading = false;
+    boolean seqColoursReady = false;
+    jalview.appletgui.FeatureRenderer fr;
+
+    public AppletPDBCanvas(jalview.appletgui.SeqCanvas seqcanvas, Sequence seq)
+    {
+      this.seqcanvas = seqcanvas;
+      this.sequence = seq;
+
+      seqcanvas.setPDBCanvas(this);
+      addKeyListener(new KeyAdapter()
+      {
+
+        public void keyPressed(KeyEvent evt)
+        {
+          doKeyPressed(evt);
+        }
+      });
+    }
+
+
+  public void setPDBFile(PDBfile pdb)
+   {
+        int max = -10;
+        int maxchain = -1;
+        int pdbstart = 0;
+        int pdbend = 0;
+        int seqstart = 0;
+        int seqend = 0;
+        AlignSeq maxAlignseq = null;;
+
+        for (int i = 0; i < pdb.chains.size(); i++)
+        {
+
+          mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());
+          mappingDetails.append("\nNo of residues = " + ((PDBChain) 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");
+            as.calcScoreMatrix();
+            as.traceAlignment();
+            PrintStream ps = new PrintStream(System.out)
+           {
+              public void print(String x) {
+                   mappingDetails.append(x);
+               }
+               public void println()
+               {
+                 mappingDetails.append("\n");
+               }
+            };
+
+            as.printAlignment(ps);
+
+            if (as.maxscore > max) {
+                max = as.maxscore;
+                maxchain = i;
+
+                pdbstart = as.seq2start;
+                pdbend = as.seq2end;
+                seqstart = as.seq1start + sequence.getStart()-1;
+                seqend = as.seq1end + sequence.getEnd()-1;
+                maxAlignseq = as;
+            }
+
+            mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);
+            mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);
+        }
+
+        mainchain = (PDBChain) pdb.chains.elementAt(maxchain);
+
+        mainchain.pdbstart = pdbstart;
+        mainchain.pdbend = pdbend;
+        mainchain.seqstart = seqstart;
+        mainchain.seqend = seqend;
+        mainchain.isVisible = true;
+        mainchain.makeExactMapping(maxAlignseq, sequence);
+
+        this.pdb = pdb;
+        this.prefsize = new Dimension(getSize().width, getSize().height);
+
+        //Initialize the matrices to identity
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                if (i != j) {
+                    idmat.addElement(i, j, 0);
+                    objmat.addElement(i, j, 0);
+                } else {
+                    idmat.addElement(i, j, 1);
+                    objmat.addElement(i, j, 1);
+                }
+            }
+        }
+
+        addMouseMotionListener(this);
+        addMouseListener(this);
+
+
+        findCentre();
+        findWidth();
+
+        setupBonds();
+
+        scale = findScale();
+    }
+
+
+    Vector visiblebonds;
+    void setupBonds()
+    {
+      seqColoursReady = false;
+      // Sort the bonds by z coord
+      visiblebonds = new Vector();
+
+      for (int ii = 0; ii < pdb.chains.size(); ii++)
+      {
+        if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)
+        {
+          Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+          for (int i = 0; i < tmp.size(); i++)
+          {
+            visiblebonds.addElement(tmp.elementAt(i));
+          }
+        }
+      }
+      updateSeqColours();
+      seqColoursReady = true;
+      redrawneeded = true;
+      repaint();
+    }
+
+
+    public void findWidth() {
+        float[] max = new float[3];
+        float[] min = new float[3];
+
+        max[0] = (float) -1e30;
+        max[1] = (float) -1e30;
+        max[2] = (float) -1e30;
+
+        min[0] = (float) 1e30;
+        min[1] = (float) 1e30;
+        min[2] = (float) 1e30;
+
+        for (int ii = 0; ii < pdb.chains.size(); ii++) {
+            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                for (int i = 0; i < bonds.size(); i++) {
+                    Bond tmp = (Bond) bonds.elementAt(i);
+
+                    if (tmp.start[0] >= max[0]) {
+                        max[0] = tmp.start[0];
+                    }
+
+                    if (tmp.start[1] >= max[1]) {
+                        max[1] = tmp.start[1];
+                    }
+
+                    if (tmp.start[2] >= max[2]) {
+                        max[2] = tmp.start[2];
+                    }
+
+                    if (tmp.start[0] <= min[0]) {
+                        min[0] = tmp.start[0];
+                    }
+
+                    if (tmp.start[1] <= min[1]) {
+                        min[1] = tmp.start[1];
+                    }
+
+                    if (tmp.start[2] <= min[2]) {
+                        min[2] = tmp.start[2];
+                    }
+
+                    if (tmp.end[0] >= max[0]) {
+                        max[0] = tmp.end[0];
+                    }
+
+                    if (tmp.end[1] >= max[1]) {
+                        max[1] = tmp.end[1];
+                    }
+
+                    if (tmp.end[2] >= max[2]) {
+                        max[2] = tmp.end[2];
+                    }
+
+                    if (tmp.end[0] <= min[0]) {
+                        min[0] = tmp.end[0];
+                    }
+
+                    if (tmp.end[1] <= min[1]) {
+                        min[1] = tmp.end[1];
+                    }
+
+                    if (tmp.end[2] <= min[2]) {
+                        min[2] = tmp.end[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]);
+
+        maxwidth = width[0];
+
+        if (width[1] > width[0]) {
+            maxwidth = width[1];
+        }
+
+        if (width[2] > width[1]) {
+            maxwidth = width[2];
+        }
+
+       // System.out.println("Maxwidth = " + maxwidth);
+    }
+
+    public float findScale() {
+        int dim;
+        int width;
+        int height;
+
+        if (getSize().width != 0) {
+            width = getSize().width;
+            height = getSize().height;
+        } else {
+            width = prefsize.width;
+            height = prefsize.height;
+        }
+
+        if (width < height) {
+            dim = width;
+        } else {
+            dim = height;
+        }
+
+        return (float) (dim / (1.5d * maxwidth));
+    }
+
+    public void findCentre() {
+        float xtot = 0;
+        float ytot = 0;
+        float ztot = 0;
+
+        int bsize = 0;
+
+        //Find centre coordinate
+        for (int ii = 0; ii < pdb.chains.size(); ii++) {
+            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                bsize += bonds.size();
+
+                for (int i = 0; i < bonds.size(); i++) {
+                    xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +
+                        ((Bond) bonds.elementAt(i)).end[0];
+
+                    ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +
+                        ((Bond) bonds.elementAt(i)).end[1];
+
+                    ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +
+                        ((Bond) bonds.elementAt(i)).end[2];
+                }
+            }
+        }
+
+        centre[0] = xtot / (2 * (float) bsize);
+        centre[1] = ytot / (2 * (float) bsize);
+        centre[2] = ztot / (2 * (float) bsize);
+    }
+
+    public void paint(Graphics g)
+    {
+
+      if(errorLoading)
+      {
+        g.setColor(Color.white);
+        g.fillRect(0,0,getSize().width, getSize().height);
+        g.setColor(Color.black);
+        g.setFont(new Font("Verdana", Font.BOLD, 14));
+        g.drawString("Error loading PDB data!!", 50, getSize().height/2);
+        return;
+      }
+
+      if( !seqColoursReady )
+      {
+        g.setColor(Color.black);
+        g.setFont(new Font("Verdana", Font.BOLD, 14));
+        g.drawString("Fetching PDB data...", 50, getSize().height/2);
+        return;
+      }
+
+
+
+        //Only create the image at the beginning -
+        //this saves much memory usage
+        if ((img == null) || (prefsize.width != getSize().width) ||
+                (prefsize.height != getSize().height)) {
+
+         try{     prefsize.width = getSize().width;
+           prefsize.height = getSize().height;
+
+           scale = findScale();
+           img = createImage(prefsize.width, prefsize.height);
+           ig = img.getGraphics();
+
+           redrawneeded = true;
+         }catch(Exception ex)
+         {
+           ex.printStackTrace();
+         }
+        }
+
+
+        if (redrawneeded)
+        {
+          drawAll(ig, prefsize.width, prefsize.height);
+          redrawneeded = false;
+        }
+        if(appletToolTip!=null)
+        {
+          ig.setColor(Color.red);
+          ig.drawString(appletToolTip, toolx, tooly);
+        }
+
+        g.drawImage(img, 0, 0, this);
+
+        pdbAction = false;
+    }
+
+    public void drawAll(Graphics g, int width, int height)
+    {
+      ig.setColor(Color.black);
+      ig.fillRect(0, 0, width, height);
+      drawScene(ig);
+      drawLabels(ig);
+    }
+
+   void setColours(jalview.schemes.ColourSchemeI cs)
+   {
+     bysequence = false;
+     pdb.setColours(cs);
+     redrawneeded = true;
+     repaint();
+   }
+    public void updateSeqColours()
+    {
+      if (pdbAction)
+      {
+        return;
+      }
+
+      if(bysequence && pdb!=null)
+      {
+        for (int ii = 0; ii < pdb.chains.size(); ii++)
+        {
+          colourBySequence((PDBChain) pdb.chains.elementAt(ii));
+        }
+      }
+
+      redrawneeded=true;
+      repaint();
+    }
+
+
+    int findTrueIndex(int pos)
+    {
+      // returns the alignment position for a residue
+      int j = sequence.getStart();
+      int i = 0;
+
+      while ( (i < sequence.getLength()) && (j <= sequence.getEnd()) && (j <= pos+1))
+      {
+        if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))
+        {
+          j++;
+        }
+
+        i++;
+      }
+
+      if(i>1)
+         i--;
+
+      if ( (j == sequence.getEnd()) && (j < pos))
+      {
+        return sequence.getEnd() + 1;
+      }
+      else
+      {
+        return i;
+      }
+    }
+
+
+    // This method has been taken out of PDBChain to allow
+    // Applet and Application specific sequence renderers to be used
+    void colourBySequence(PDBChain chain)
+    {
+      boolean showFeatures = false;
+
+      if(seqcanvas.getViewport().getShowSequenceFeatures())
+        {
+          if(fr==null)
+          {
+            fr = new jalview.appletgui.FeatureRenderer(seqcanvas.getViewport());
+          }
+          fr.transferSettings( seqcanvas.getFeatureRenderer());
+          showFeatures = true;
+        }
+
+      for (int i = 0; i < chain.bonds.size(); i++)
+      {
+        Bond tmp = (Bond) chain.bonds.elementAt(i);
+        tmp.startCol = Color.lightGray;
+        tmp.endCol = Color.lightGray;
+        if(chain!=mainchain)
+          continue;
+
+        if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
+            (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))
+        {
+
+          int index = findTrueIndex(tmp.at1.alignmentMapping);
+                //sequence.findIndex(tmp.at1.alignmentMapping);
+            if (index != -1)
+            {
+              tmp.startCol = seqcanvas.getSequenceRenderer().
+                  getResidueBoxColour( sequence, index);
+
+              if(showFeatures)
+              tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);
+            }
+        }
+
+        int index =  findTrueIndex(tmp.at2.alignmentMapping);
+            //sequence.findIndex( tmp.at2.alignmentMapping );
+        if (index != -1)
+        {
+          tmp.endCol = seqcanvas.getSequenceRenderer().
+              getResidueBoxColour( sequence, index);
+
+          if(showFeatures)
+          tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);
+        }
+      }
+    }
+
+
+    Zsort zsort;
+    public void drawScene(Graphics g)
+    {
+        if (zbuffer)
+        {
+          if(zsort ==null)
+            zsort = new Zsort();
+
+          zsort.Zsort(visiblebonds);
+        }
+
+
+        Bond tmpBond=null;
+        for (int i = 0; i < visiblebonds.size(); i++)
+        {
+            tmpBond = (Bond) visiblebonds.elementAt(i);
+
+
+            xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +
+                (getSize().width / 2));
+            ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +
+                (getSize().height / 2));
+
+            xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +
+                (getSize().width / 2));
+            yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +
+                (getSize().height / 2));
+
+            xmid = (xend + xstart) / 2;
+            ymid = (yend + ystart) / 2;
+
+            if (depthcue && !bymolecule)
+            {
+                if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {
+                    g.setColor(tmpBond.startCol.darker().darker());
+                    drawLine(g, xstart, ystart, xmid, ymid);
+
+                    g.setColor(tmpBond.endCol.darker().darker());
+                    drawLine(g, xmid, ymid, xend, yend);
+                } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {
+                    g.setColor(tmpBond.startCol.darker());
+                    drawLine(g, xstart, ystart, xmid, ymid);
+
+                    g.setColor(tmpBond.endCol.darker());
+                    drawLine(g, xmid, ymid, xend, yend);
+                } else {
+                    g.setColor(tmpBond.startCol);
+                    drawLine(g, xstart, ystart, xmid, ymid);
+
+                    g.setColor(tmpBond.endCol);
+                    drawLine(g, xmid, ymid, xend, yend);
+                }
+
+            } else if (depthcue && bymolecule) {
+                if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {
+                    g.setColor(Color.green.darker().darker());
+                    drawLine(g, xstart, ystart, xend, yend);
+                } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {
+                    g.setColor(Color.green.darker());
+                    drawLine(g, xstart, ystart, xend, yend);
+                } else {
+                    g.setColor(Color.green);
+                    drawLine(g, xstart, ystart, xend, yend);
+                }
+            } else if (!depthcue && !bymolecule) {
+                g.setColor(tmpBond.startCol);
+                drawLine(g, xstart, ystart, xmid, ymid);
+                g.setColor(tmpBond.endCol);
+                drawLine(g, xmid, ymid, xend, yend);
+            } else {
+                drawLine(g, xstart, ystart, xend, yend);
+            }
+
+            if(highlightBond1!=null && highlightBond1==tmpBond)
+            {
+              g.setColor(Color.white);
+              drawLine(g, xmid, ymid, xend, yend);
+            }
+
+            if(highlightBond2!=null && highlightBond2==tmpBond)
+            {
+              g.setColor(Color.white);
+              drawLine(g, xstart, ystart, xmid, ymid);
+            }
+
+        }
+    }
+
+    public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {
+        if (!wire) {
+            if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {
+                g.drawLine(x1, y1, x2, y2);
+                g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);
+                g.drawLine(x1, y1 - 1, x2, y2 - 1);
+            } else {
+                g.setColor(g.getColor().brighter());
+                g.drawLine(x1, y1, x2, y2);
+                g.drawLine(x1 + 1, y1, x2 + 1, y2);
+                g.drawLine(x1 - 1, y1, x2 - 1, y2);
+            }
+        } else {
+            g.drawLine(x1, y1, x2, y2);
+        }
+    }
+
+    public Dimension minimumsize() {
+        return prefsize;
+    }
+
+    public Dimension preferredsize() {
+        return prefsize;
+    }
+
+    public void doKeyPressed(KeyEvent evt)
+    {
+      if (evt.getKeyCode() == KeyEvent.VK_UP)
+      {
+        scale = (float) (scale * 1.1);
+        redrawneeded = true;
+        repaint();
+      }
+      else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
+      {
+        scale = (float) (scale * 0.9);
+        redrawneeded = true;
+        repaint();
+      }
+    }
+
+    public void mousePressed(MouseEvent e) {
+      pdbAction = true;
+      Atom fatom = findAtom(e.getX(), e.getY());
+      if(fatom!=null)
+      {
+        fatom.isSelected = !fatom.isSelected;
+
+        redrawneeded = true;
+        repaint();
+        if (foundchain != -1)
+        {
+          PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);
+          if (chain == mainchain)
+          {
+            if (fatom.alignmentMapping != -1)
+            {
+              if (highlightRes == null)
+                highlightRes = new Vector();
+
+              if (highlightRes.contains(fatom.alignmentMapping+"" + ""))
+                highlightRes.removeElement(fatom.alignmentMapping + "");
+              else
+                highlightRes.addElement(fatom.alignmentMapping + "");
+            }
+          }
+        }
+
+        }
+        mx = e.getX();
+        my = e.getY();
+        omx = mx;
+        omy = my;
+        dragging = false;
+    }
+
+    public void mouseMoved(MouseEvent e) {
+      pdbAction = true;
+      if(highlightBond1!=null)
+      {
+        highlightBond1.at2.isSelected = false;
+        highlightBond2.at1.isSelected = false;
+        highlightBond1 = null;
+        highlightBond2 = null;
+      }
+
+        Atom fatom = findAtom(e.getX(), e.getY());
+
+        PDBChain chain = null;
+        if(foundchain!=-1)
+        {
+          chain = (PDBChain) pdb.chains.elementAt(foundchain);
+          if(chain == mainchain)
+          {
+            highlightSeqcanvas( fatom.alignmentMapping );
+          }
+        }
+
+        if (fatom != null) {
+            toolx = e.getX();
+            tooly = e.getY();
+
+            appletToolTip = chain.id+":"+ fatom.resNumber+" "+ fatom.resName;
+            redrawneeded = true;
+            repaint();
+        } else {
+            highlightSeqcanvas( -1);
+            appletToolTip = null;
+            redrawneeded = true;
+            repaint();
+        }
+    }
+
+
+    void highlightSeqcanvas(int pos)
+    {
+      SearchResults searchResults = new SearchResults();
+      if(highlightRes!=null)
+      {
+        for (int i = 0; i < highlightRes.size(); i++)
+        {
+          int a = Integer.parseInt(highlightRes.elementAt(
+              i).toString())+1;
+
+          searchResults.addResult(sequence, a, a);
+        }
+      }
+
+      if(pos!=-1)
+      {
+        searchResults.addResult(sequence, pos+1, pos+1);
+      }
+
+      seqcanvas.highlightSearchResults(searchResults);
+    }
+
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mouseDragged(MouseEvent evt) {
+        int x = evt.getX();
+        int y = evt.getY();
+        mx = x;
+        my = y;
+
+        MCMatrix objmat = new MCMatrix(3, 3);
+        objmat.setIdentity();
+
+        if ((evt.getModifiers() & Event.META_MASK) != 0) {
+            objmat.rotatez((float) ((mx - omx)));
+        } else {
+            objmat.rotatex((float) ((my - omy)));
+            objmat.rotatey((float) ((omx - mx)));
+        }
+
+        //Alter the bonds
+        for (int ii = 0; ii < pdb.chains.size(); ii++) {
+            Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+            for (int i = 0; i < bonds.size(); i++) {
+                Bond tmpBond = (Bond) bonds.elementAt(i);
+
+                //Translate the bond so the centre is 0,0,0
+                tmpBond.translate(-centre[0], -centre[1], -centre[2]);
+
+                //Now apply the rotation matrix
+                tmpBond.start = objmat.vectorMultiply(tmpBond.start);
+                tmpBond.end = objmat.vectorMultiply(tmpBond.end);
+
+                //Now translate back again
+                tmpBond.translate(centre[0], centre[1], centre[2]);
+            }
+        }
+
+        objmat = null;
+
+        omx = mx;
+        omy = my;
+
+        dragging = true;
+
+        redrawneeded = true;
+
+        repaint();
+    }
+
+    public void mouseReleased(MouseEvent evt) {
+        dragging = false;
+        return;
+    }
+
+    void drawLabels(Graphics g) {
+
+        for (int ii = 0; ii < pdb.chains.size(); ii++)
+        {
+            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+
+            if (chain.isVisible)
+            {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                for (int i = 0; i < bonds.size(); i++)
+                {
+                    Bond tmpBond = (Bond) bonds.elementAt(i);
+
+                    if (tmpBond.at1.isSelected)
+                    {
+                        labelAtom(g, tmpBond, 1);
+                    }
+
+                    if (tmpBond.at2.isSelected)
+                    {
+
+                        labelAtom(g, tmpBond, 2);
+                    }
+                }
+            }
+        }
+    }
+
+    public void labelAtom(Graphics g, Bond b, int n) {
+        g.setFont(font);
+
+        if (n == 1) {
+            int xstart = (int) (((b.start[0] - centre[0]) * scale) +
+                (getSize().width / 2));
+            int ystart = (int) (((b.start[1] - centre[1]) * scale) +
+                (getSize().height / 2));
+
+            g.setColor(Color.red);
+            g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);
+        }
+
+        if (n == 2) {
+            int xstart = (int) (((b.end[0] - centre[0]) * scale) +
+                (getSize().width / 2));
+            int ystart = (int) (((b.end[1] - centre[1]) * scale) +
+                (getSize().height / 2));
+
+            g.setColor(Color.red);
+            g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);
+        }
+    }
+
+    int foundchain = -1;
+    public Atom findAtom(int x, int y) {
+        Atom fatom = null;
+
+        foundchain = -1;
+
+        for (int ii = 0; ii < pdb.chains.size(); ii++)
+        {
+            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+            int truex;
+            Bond tmpBond=null;
+
+            if (chain.isVisible)
+            {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                for (int i = 0; i < bonds.size(); i++)
+                {
+                    tmpBond = (Bond) bonds.elementAt(i);
+
+                    truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +
+                        (getSize().width / 2));
+
+                    if (Math.abs(truex - x) <= 2)
+                    {
+                        int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +
+                            (getSize().height / 2));
+
+                        if (Math.abs(truey - y) <= 2)
+                        {
+                            fatom = tmpBond.at1;
+                            foundchain = ii;
+                            break;
+                        }
+                    }
+                }
+
+                // Still here? Maybe its the last bond
+
+                truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +
+                               (getSize().width / 2));
+
+                if (Math.abs(truex - x) <= 2)
+                {
+                  int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +
+                                     (getSize().height / 2));
+
+                  if (Math.abs(truey - y) <= 2)
+                  {
+                    fatom = tmpBond.at2;
+                    foundchain = ii;
+                    break;
+                  }
+                }
+
+            }
+
+            if (fatom != null) //)&& chain.ds != null)
+             {
+                chain = (PDBChain) pdb.chains.elementAt(foundchain);
+            }
+        }
+
+        return fatom;
+    }
+
+    public void update(Graphics g)
+    {
+      paint(g);
+    }
+
+    public void highlightRes(int ii)
+   {
+     if(!seqColoursReady)
+       return;
+
+     if (highlightRes != null
+         && highlightRes.contains((ii-1) + ""))
+     {
+       return;
+     }
+
+     int index = -1;
+     Bond tmpBond;
+     for(index=0; index<mainchain.bonds.size(); index++)
+     {
+       tmpBond = (Bond) mainchain.bonds.elementAt(index);
+       if (tmpBond.at1.alignmentMapping == ii - 1)
+       {
+         if (highlightBond1 != null)
+           highlightBond1.at2.isSelected = false;
+
+         if (highlightBond2 != null)
+           highlightBond2.at1.isSelected = false;
+
+         highlightBond1 = null;
+         highlightBond2 = null;
+
+         if (index > 0)
+         {
+           highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);
+           highlightBond1.at2.isSelected = true;
+         }
+
+         if (index != mainchain.bonds.size())
+         {
+           highlightBond2 = (Bond) mainchain.bonds.elementAt(index);
+           highlightBond2.at1.isSelected = true;
+         }
+
+         break;
+       }
+     }
+
+     redrawneeded = true;
+     repaint();
+   }
+
+
+    public void setAllchainsVisible(boolean b)
+    {
+      for (int ii = 0; ii < pdb.chains.size(); ii++)
+      {
+        PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+        chain.isVisible = b;
+      }
+      mainchain.isVisible = true;
+      findCentre();
+      setupBonds();
+    }
+
+}
index e80178a..351de12 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package MCview;\r
-\r
-import java.awt.*;\r
-\r
-import java.awt.event.*;\r
-import jalview.datamodel.*;\r
-import jalview.appletgui.*;\r
-import jalview.schemes.*;\r
-import java.awt.event.ActionListener;\r
-import java.awt.event.ActionEvent;\r
-\r
-\r
-public class AppletPDBViewer extends Frame implements ActionListener, ItemListener\r
-{\r
-      AppletPDBCanvas pdbcanvas;\r
-      public AppletPDBViewer(String pdbtext,String type,\r
-                       Sequence seq,\r
-                       SeqCanvas seqcanvas)\r
-      {\r
-\r
-        try\r
-        {\r
-          jbInit();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          ex.printStackTrace();\r
-        }\r
-\r
-        pdbcanvas = new AppletPDBCanvas(seqcanvas, seq);\r
-\r
-        add(pdbcanvas, BorderLayout.CENTER);\r
-\r
-        StringBuffer title = new StringBuffer(seq.getName() + ":");\r
-\r
-        jalview.bin.JalviewLite.addFrame(this,title.toString(),400, 400);\r
-\r
-        try{\r
-        PDBfile pdbfile = new PDBfile(pdbtext, type);\r
-        pdbcanvas.setPDBFile(pdbfile);\r
-        }\r
-        catch(Exception ex){\r
-          pdbcanvas.errorLoading = true;\r
-          pdbcanvas.repaint();\r
-        }\r
-      }\r
-\r
-      public void actionPerformed(ActionEvent evt)\r
-      {\r
-        if(evt.getSource()==mapping)\r
-               mapping_actionPerformed();\r
-       else if(evt.getSource()==wire)\r
-               wire_actionPerformed();\r
-       else if(evt.getSource()==depth)\r
-               depth_actionPerformed();\r
-       else if(evt.getSource()==zbuffer)\r
-               zbuffer_actionPerformed();\r
-       else if(evt.getSource()==charge)\r
-               charge_actionPerformed();\r
-\r
-       else if(evt.getSource()==chain)\r
-               chain_actionPerformed();\r
-       else if(evt.getSource()==seqButton)\r
-               seqButton_actionPerformed();\r
-       else if(evt.getSource()==zappo)\r
-                pdbcanvas.setColours(new ZappoColourScheme());\r
-       else if(evt.getSource()==taylor)\r
-               pdbcanvas.setColours(new TaylorColourScheme());\r
-      else if(evt.getSource()==hydro)\r
-               pdbcanvas.setColours(new HydrophobicColourScheme());\r
-      else if(evt.getSource()==helix)\r
-               pdbcanvas.setColours(new HelixColourScheme());\r
-       else if(evt.getSource()==strand)\r
-               pdbcanvas.setColours(new StrandColourScheme());\r
-       else if(evt.getSource()==turn)\r
-               pdbcanvas.setColours(new TurnColourScheme());\r
-       else if(evt.getSource()==buried)\r
-              pdbcanvas.setColours(new BuriedColourScheme());\r
-       else if(evt.getSource()==user)\r
-       {\r
-         pdbcanvas.bysequence = false;\r
-         new jalview.appletgui.UserDefinedColours(pdbcanvas);\r
-       }\r
-      }\r
-\r
-      public void itemStateChanged(ItemEvent evt)\r
-      {\r
-        if (evt.getSource() == allchains)\r
-          allchains_itemStateChanged();\r
-        else if (evt.getSource() == wire)\r
-          wire_actionPerformed();\r
-        else if (evt.getSource() == depth)\r
-          depth_actionPerformed();\r
-        else if (evt.getSource() == zbuffer)\r
-          zbuffer_actionPerformed();\r
-      }\r
-\r
-\r
-      private void jbInit()\r
-          throws Exception\r
-      {\r
-        setMenuBar(jMenuBar1);\r
-        fileMenu.setLabel("File");\r
-        coloursMenu.setLabel("Colours");\r
-        mapping.setLabel("View Mapping");\r
-        mapping.addActionListener(this);\r
-        wire.setLabel("Wireframe");\r
-        wire.addItemListener(this);\r
-        depth.setState(true);\r
-        depth.setLabel("Depthcue");\r
-        depth.addItemListener(this);\r
-        zbuffer.setState(true);\r
-        zbuffer.setLabel("Z Buffering");\r
-        zbuffer.addItemListener(this);\r
-        charge.setLabel("Charge & Cysteine");\r
-        charge.addActionListener(this);\r
-        hydro.setLabel("Hydrophobicity");\r
-        hydro.addActionListener(this);\r
-        chain.setLabel("By Chain");\r
-        chain.addActionListener(this);\r
-        seqButton.setLabel("By Sequence");\r
-        seqButton.addActionListener(this);\r
-    allchains.setLabel("All Chains Visible");\r
-    allchains.addItemListener(this);\r
-    viewMenu.setLabel("View");\r
-    zappo.setLabel("Zappo");\r
-    zappo.addActionListener(this);\r
-    taylor.setLabel("Taylor");\r
-    taylor.addActionListener(this);\r
-    helix.setLabel("Helix Propensity");\r
-    helix.addActionListener(this);\r
-    strand.setLabel("Strand Propensity");\r
-    strand.addActionListener(this);\r
-    turn.setLabel("Turn Propensity");\r
-    turn.addActionListener(this);\r
-    buried.setLabel("Buried Index");\r
-    buried.addActionListener(this);\r
-    user.setLabel("User Defined...");\r
-    user.addActionListener(this);\r
-    jMenuBar1.add(fileMenu);\r
-        jMenuBar1.add(coloursMenu);\r
-    jMenuBar1.add(viewMenu);\r
-    fileMenu.add(mapping);;\r
-\r
-        coloursMenu.add(seqButton);\r
-        coloursMenu.add(chain);\r
-    coloursMenu.add(charge);\r
-    coloursMenu.add(zappo);\r
-    coloursMenu.add(taylor);\r
-    coloursMenu.add(hydro);\r
-    coloursMenu.add(helix);\r
-    coloursMenu.add(strand);\r
-    coloursMenu.add(turn);\r
-    coloursMenu.add(buried);\r
-    coloursMenu.add(user);\r
-    viewMenu.add(wire);\r
-    viewMenu.add(depth);\r
-    viewMenu.add(zbuffer);\r
-    viewMenu.add(allchains);\r
-    allchains.setState(true);\r
-  }\r
-\r
-      MenuBar jMenuBar1 = new MenuBar();\r
-      Menu fileMenu = new Menu();\r
-      Menu coloursMenu = new Menu();\r
-      MenuItem mapping = new MenuItem();\r
-      CheckboxGroup bg = new CheckboxGroup();\r
-      CheckboxMenuItem wire = new CheckboxMenuItem();\r
-      CheckboxMenuItem depth = new CheckboxMenuItem();\r
-      CheckboxMenuItem zbuffer = new CheckboxMenuItem();\r
-\r
-      MenuItem charge = new MenuItem();\r
-      MenuItem hydro = new MenuItem();\r
-      MenuItem chain = new MenuItem();\r
-      MenuItem seqButton = new MenuItem();\r
-\r
-     CheckboxMenuItem allchains = new CheckboxMenuItem();\r
-  Menu viewMenu = new Menu();\r
-  MenuItem turn = new MenuItem();\r
-  MenuItem strand = new MenuItem();\r
-  MenuItem helix = new MenuItem();\r
-  MenuItem taylor = new MenuItem();\r
-  MenuItem zappo = new MenuItem();\r
-  MenuItem buried = new MenuItem();\r
-  MenuItem user = new MenuItem();\r
-\r
-  public void charge_actionPerformed()\r
-      {\r
-        pdbcanvas.bysequence = false;\r
-        pdbcanvas.pdb.setChargeColours();\r
-        pdbcanvas.redrawneeded=true;\r
-        pdbcanvas.repaint();\r
-      }\r
-\r
-      public void chain_actionPerformed()\r
-      {\r
-         pdbcanvas.bysequence = false;\r
-         pdbcanvas.pdb.setChainColours();\r
-        pdbcanvas.redrawneeded=true;\r
-        pdbcanvas.repaint();\r
-      }\r
-\r
-      public void zbuffer_actionPerformed()\r
-      {\r
-        pdbcanvas.zbuffer = ! pdbcanvas.zbuffer;\r
-        pdbcanvas.redrawneeded=true;\r
-        pdbcanvas.repaint();\r
-      }\r
-\r
-      public void depth_actionPerformed()\r
-      {\r
-      pdbcanvas.depthcue = ! pdbcanvas.depthcue;\r
-      pdbcanvas.redrawneeded=true;\r
-        pdbcanvas.repaint();\r
-      }\r
-\r
-      public void wire_actionPerformed()\r
-      {\r
-        pdbcanvas.wire = ! pdbcanvas.wire;\r
-        pdbcanvas.redrawneeded=true;\r
-        pdbcanvas.repaint();\r
-      }\r
-\r
-      public void seqButton_actionPerformed()\r
-      {\r
-        pdbcanvas.bysequence = true;\r
-        pdbcanvas.updateSeqColours();\r
-        pdbcanvas.repaint();\r
-      }\r
-\r
-\r
-      public void mapping_actionPerformed()\r
-      {\r
-        jalview.appletgui.CutAndPasteTransfer cap\r
-            = new jalview.appletgui.CutAndPasteTransfer(false, null);\r
-        Frame frame = new Frame();\r
-        frame.add(cap);\r
-        jalview.bin.JalviewLite.addFrame(frame, "PDB - Sequence Mapping", 500, 600);\r
-        cap.setText(pdbcanvas.mappingDetails.toString());\r
-      }\r
-\r
-      public void allchains_itemStateChanged()\r
-      {\r
-        pdbcanvas.setAllchainsVisible(allchains.getState());\r
-      }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package MCview;
+
+import java.awt.*;
+
+import java.awt.event.*;
+import jalview.datamodel.*;
+import jalview.appletgui.*;
+import jalview.schemes.*;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+
+public class AppletPDBViewer extends Frame implements ActionListener, ItemListener
+{
+      AppletPDBCanvas pdbcanvas;
+      public AppletPDBViewer(String pdbtext,String type,
+                       Sequence seq,
+                       SeqCanvas seqcanvas)
+      {
+
+        try
+        {
+          jbInit();
+        }
+        catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+
+        pdbcanvas = new AppletPDBCanvas(seqcanvas, seq);
+
+        add(pdbcanvas, BorderLayout.CENTER);
+
+        StringBuffer title = new StringBuffer(seq.getName() + ":");
+
+        jalview.bin.JalviewLite.addFrame(this,title.toString(),400, 400);
+
+        try{
+        PDBfile pdbfile = new PDBfile(pdbtext, type);
+        pdbcanvas.setPDBFile(pdbfile);
+        }
+        catch(Exception ex){
+          ex.printStackTrace();
+          pdbcanvas.errorLoading = true;
+          pdbcanvas.repaint();
+        }
+      }
+
+      public void actionPerformed(ActionEvent evt)
+      {
+        if(evt.getSource()==mapping)
+               mapping_actionPerformed();
+       else if(evt.getSource()==wire)
+               wire_actionPerformed();
+       else if(evt.getSource()==depth)
+               depth_actionPerformed();
+       else if(evt.getSource()==zbuffer)
+               zbuffer_actionPerformed();
+       else if(evt.getSource()==charge)
+               charge_actionPerformed();
+
+       else if(evt.getSource()==chain)
+               chain_actionPerformed();
+       else if(evt.getSource()==seqButton)
+               seqButton_actionPerformed();
+       else if(evt.getSource()==zappo)
+                pdbcanvas.setColours(new ZappoColourScheme());
+       else if(evt.getSource()==taylor)
+               pdbcanvas.setColours(new TaylorColourScheme());
+      else if(evt.getSource()==hydro)
+               pdbcanvas.setColours(new HydrophobicColourScheme());
+      else if(evt.getSource()==helix)
+               pdbcanvas.setColours(new HelixColourScheme());
+       else if(evt.getSource()==strand)
+               pdbcanvas.setColours(new StrandColourScheme());
+       else if(evt.getSource()==turn)
+               pdbcanvas.setColours(new TurnColourScheme());
+       else if(evt.getSource()==buried)
+              pdbcanvas.setColours(new BuriedColourScheme());
+       else if(evt.getSource()==user)
+       {
+         pdbcanvas.bysequence = false;
+         new jalview.appletgui.UserDefinedColours(pdbcanvas);
+       }
+      }
+
+      public void itemStateChanged(ItemEvent evt)
+      {
+        if (evt.getSource() == allchains)
+          allchains_itemStateChanged();
+        else if (evt.getSource() == wire)
+          wire_actionPerformed();
+        else if (evt.getSource() == depth)
+          depth_actionPerformed();
+        else if (evt.getSource() == zbuffer)
+          zbuffer_actionPerformed();
+      }
+
+
+      private void jbInit()
+          throws Exception
+      {
+        setMenuBar(jMenuBar1);
+        fileMenu.setLabel("File");
+        coloursMenu.setLabel("Colours");
+        mapping.setLabel("View Mapping");
+        mapping.addActionListener(this);
+        wire.setLabel("Wireframe");
+        wire.addItemListener(this);
+        depth.setState(true);
+        depth.setLabel("Depthcue");
+        depth.addItemListener(this);
+        zbuffer.setState(true);
+        zbuffer.setLabel("Z Buffering");
+        zbuffer.addItemListener(this);
+        charge.setLabel("Charge & Cysteine");
+        charge.addActionListener(this);
+        hydro.setLabel("Hydrophobicity");
+        hydro.addActionListener(this);
+        chain.setLabel("By Chain");
+        chain.addActionListener(this);
+        seqButton.setLabel("By Sequence");
+        seqButton.addActionListener(this);
+    allchains.setLabel("All Chains Visible");
+    allchains.addItemListener(this);
+    viewMenu.setLabel("View");
+    zappo.setLabel("Zappo");
+    zappo.addActionListener(this);
+    taylor.setLabel("Taylor");
+    taylor.addActionListener(this);
+    helix.setLabel("Helix Propensity");
+    helix.addActionListener(this);
+    strand.setLabel("Strand Propensity");
+    strand.addActionListener(this);
+    turn.setLabel("Turn Propensity");
+    turn.addActionListener(this);
+    buried.setLabel("Buried Index");
+    buried.addActionListener(this);
+    user.setLabel("User Defined...");
+    user.addActionListener(this);
+    jMenuBar1.add(fileMenu);
+        jMenuBar1.add(coloursMenu);
+    jMenuBar1.add(viewMenu);
+    fileMenu.add(mapping);;
+
+        coloursMenu.add(seqButton);
+        coloursMenu.add(chain);
+    coloursMenu.add(charge);
+    coloursMenu.add(zappo);
+    coloursMenu.add(taylor);
+    coloursMenu.add(hydro);
+    coloursMenu.add(helix);
+    coloursMenu.add(strand);
+    coloursMenu.add(turn);
+    coloursMenu.add(buried);
+    coloursMenu.add(user);
+    viewMenu.add(wire);
+    viewMenu.add(depth);
+    viewMenu.add(zbuffer);
+    viewMenu.add(allchains);
+    allchains.setState(true);
+  }
+
+      MenuBar jMenuBar1 = new MenuBar();
+      Menu fileMenu = new Menu();
+      Menu coloursMenu = new Menu();
+      MenuItem mapping = new MenuItem();
+      CheckboxGroup bg = new CheckboxGroup();
+      CheckboxMenuItem wire = new CheckboxMenuItem();
+      CheckboxMenuItem depth = new CheckboxMenuItem();
+      CheckboxMenuItem zbuffer = new CheckboxMenuItem();
+
+      MenuItem charge = new MenuItem();
+      MenuItem hydro = new MenuItem();
+      MenuItem chain = new MenuItem();
+      MenuItem seqButton = new MenuItem();
+
+     CheckboxMenuItem allchains = new CheckboxMenuItem();
+  Menu viewMenu = new Menu();
+  MenuItem turn = new MenuItem();
+  MenuItem strand = new MenuItem();
+  MenuItem helix = new MenuItem();
+  MenuItem taylor = new MenuItem();
+  MenuItem zappo = new MenuItem();
+  MenuItem buried = new MenuItem();
+  MenuItem user = new MenuItem();
+
+  public void charge_actionPerformed()
+      {
+        pdbcanvas.bysequence = false;
+        pdbcanvas.pdb.setChargeColours();
+        pdbcanvas.redrawneeded=true;
+        pdbcanvas.repaint();
+      }
+
+      public void chain_actionPerformed()
+      {
+         pdbcanvas.bysequence = false;
+         pdbcanvas.pdb.setChainColours();
+        pdbcanvas.redrawneeded=true;
+        pdbcanvas.repaint();
+      }
+
+      public void zbuffer_actionPerformed()
+      {
+        pdbcanvas.zbuffer = ! pdbcanvas.zbuffer;
+        pdbcanvas.redrawneeded=true;
+        pdbcanvas.repaint();
+      }
+
+      public void depth_actionPerformed()
+      {
+      pdbcanvas.depthcue = ! pdbcanvas.depthcue;
+      pdbcanvas.redrawneeded=true;
+        pdbcanvas.repaint();
+      }
+
+      public void wire_actionPerformed()
+      {
+        pdbcanvas.wire = ! pdbcanvas.wire;
+        pdbcanvas.redrawneeded=true;
+        pdbcanvas.repaint();
+      }
+
+      public void seqButton_actionPerformed()
+      {
+        pdbcanvas.bysequence = true;
+        pdbcanvas.updateSeqColours();
+        pdbcanvas.repaint();
+      }
+
+
+      public void mapping_actionPerformed()
+      {
+        jalview.appletgui.CutAndPasteTransfer cap
+            = new jalview.appletgui.CutAndPasteTransfer(false, null);
+        Frame frame = new Frame();
+        frame.add(cap);
+        jalview.bin.JalviewLite.addFrame(frame, "PDB - Sequence Mapping", 500, 600);
+        cap.setText(pdbcanvas.mappingDetails.toString());
+      }
+
+      public void allchains_itemStateChanged()
+      {
+        pdbcanvas.setAllchainsVisible(allchains.getState());
+      }
+
+}
index 51c4f01..269fbaa 100755 (executable)
@@ -1,58 +1,58 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import java.awt.*;\r
-\r
-\r
-public class Atom {\r
-    float x;\r
-    float y;\r
-    float z;\r
-    int number;\r
-    String name;\r
-    String resName;\r
-    int resNumber;\r
-    int type;\r
-    Color color;\r
-    String chain;\r
-    int alignmentMapping=-1;\r
-\r
-    public boolean isSelected = false;\r
-\r
-    public Atom(String str)\r
-    {\r
-        name =  str.substring(12,15).trim();\r
-\r
-        resName = str.substring(17,20);\r
-\r
-        chain = str.substring(21,22);\r
-\r
-        resNumber = Integer.parseInt(str.substring(22,26).trim());\r
-\r
-        this.x = (float) (new Float(str.substring(30,38).trim()).floatValue());\r
-        this.y = (float) (new Float(str.substring(38,46).trim()).floatValue());\r
-        this.z = (float) (new Float(str.substring(47,55).trim()).floatValue());\r
-\r
-    }\r
-\r
-    public void setColor(Color col) {\r
-        this.color = col;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import java.awt.*;
+
+
+public class Atom {
+    float x;
+    float y;
+    float z;
+    int number;
+    String name;
+    String resName;
+    int resNumber;
+    int type;
+    Color color = Color.lightGray;
+    String chain;
+    int alignmentMapping=-1;
+
+    public boolean isSelected = false;
+
+    public Atom(String str)
+    {
+        name =  str.substring(12,15).trim();
+
+        resName = str.substring(17,20);
+
+        chain = str.substring(21,22);
+
+        resNumber = Integer.parseInt(str.substring(22,26).trim());
+
+        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());
+
+    }
+
+  //  public void setColor(Color col) {
+  //      this.color = col;
+  //  }
+}
index 5f162b0..98edc45 100755 (executable)
@@ -1,78 +1,78 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import java.awt.*;\r
-\r
-\r
-public class Bond {\r
-    float[] start;\r
-    float[] end;\r
-    Color startCol;\r
-    Color endCol;\r
-    public Atom at1;\r
-    public Atom at2;\r
-\r
-    public Bond(float[] start, float[] end, Atom at1, Atom at2) {\r
-        this.start = start;\r
-        this.end = end;\r
-        this.startCol = at1.color;\r
-        this.endCol = at2.color;\r
-        this.at1 = at1;\r
-        this.at2 = at2;\r
-    }\r
-\r
-    public Bond(Bond bond) {\r
-        this.start = new float[3];\r
-\r
-        this.start[0] = bond.start[0];\r
-        this.start[1] = bond.start[1];\r
-        this.start[2] = bond.start[2];\r
-\r
-        this.end = new float[3];\r
-\r
-        this.end[0] = bond.end[0];\r
-        this.end[1] = bond.end[1];\r
-        this.end[2] = bond.end[2];\r
-\r
-        this.startCol = bond.startCol;\r
-        this.endCol = bond.endCol;\r
-    }\r
-\r
-    public float length() {\r
-        float len = ((end[0] - start[0]) * (end[0] - start[0])) +\r
-            ((end[1] - start[1]) * (end[1] - start[1])) +\r
-            ((end[2] - start[2]) * (end[2] - start[2]));\r
-\r
-        len = (float) (Math.sqrt(len));\r
-\r
-        return len;\r
-    }\r
-\r
-    public void translate(float x, float y, float z) {\r
-        start[0] = (start[0] + x);\r
-        end[0] = (end[0] + x);\r
-\r
-        start[1] = (start[1] + y);\r
-        end[1] = (end[1] + y);\r
-\r
-        start[2] = (start[2] + z);\r
-        end[2] = (end[2] + z);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import java.awt.*;
+
+
+public class Bond {
+    float[] start;
+    float[] end;
+    Color startCol = Color.lightGray;
+    Color endCol= Color.lightGray;
+    public Atom at1;
+    public Atom at2;
+
+    public Bond(float[] start, float[] end, Atom at1, Atom at2) {
+        this.start = start;
+        this.end = end;
+        this.startCol = at1.color;
+        this.endCol = at2.color;
+        this.at1 = at1;
+        this.at2 = at2;
+    }
+
+  /*  public Bond(Bond bond) {
+        this.start = new float[3];
+
+        this.start[0] = bond.start[0];
+        this.start[1] = bond.start[1];
+        this.start[2] = bond.start[2];
+
+        this.end = new float[3];
+
+        this.end[0] = bond.end[0];
+        this.end[1] = bond.end[1];
+        this.end[2] = bond.end[2];
+
+        this.startCol = bond.startCol;
+        this.endCol = bond.endCol;
+    }
+
+    public float length() {
+        float len = ((end[0] - start[0]) * (end[0] - start[0])) +
+            ((end[1] - start[1]) * (end[1] - start[1])) +
+            ((end[2] - start[2]) * (end[2] - start[2]));
+
+        len = (float) (Math.sqrt(len));
+
+        return len;
+    }*/
+
+    public void translate(float x, float y, float z) {
+        start[0] = (start[0] + x);
+        end[0] = (end[0] + x);
+
+        start[1] = (start[1] + y);
+        end[1] = (end[1] + y);
+
+        start[2] = (start[2] + z);
+        end[2] = (end[2] + z);
+    }
+}
index 66c3798..36aff78 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-public class MCMatrix {\r
-    float[][] matrix;\r
-    float[][] tmp;\r
-    float mycos;\r
-    float mysin;\r
-    float myconst = (float) (Math.PI / 180);\r
-\r
-    public MCMatrix(int rows, int cols) {\r
-        matrix = new float[rows][cols];\r
-        tmp = new float[rows][cols];\r
-    }\r
-\r
-    public void addElement(int i, int j, float value) {\r
-        matrix[i][j] = value;\r
-    }\r
-\r
-    public void rotatex(float degrees) {\r
-        mycos = (float) (Math.cos(degrees * myconst));\r
-        mysin = (float) (Math.sin(degrees * myconst));\r
-\r
-        tmp[0][0] = 1;\r
-        tmp[0][1] = 0;\r
-        tmp[0][2] = 0;\r
-        tmp[1][0] = 0;\r
-        tmp[1][1] = mycos;\r
-        tmp[1][2] = mysin;\r
-        tmp[2][0] = 0;\r
-        tmp[2][1] = -mysin;\r
-        tmp[2][2] = mycos;\r
-        preMultiply(tmp);\r
-    }\r
-\r
-    public void rotatez(float degrees) {\r
-        mycos = (float) (Math.cos(degrees * myconst));\r
-        mysin = (float) (Math.sin(degrees * myconst));\r
-\r
-        tmp[0][0] = mycos;\r
-        tmp[0][1] = -mysin;\r
-        tmp[0][2] = 0;\r
-        tmp[1][0] = mysin;\r
-        tmp[1][1] = mycos;\r
-        tmp[1][2] = 0;\r
-        tmp[2][0] = 0;\r
-        tmp[2][1] = 0;\r
-        tmp[2][2] = 1;\r
-\r
-        preMultiply(tmp);\r
-    }\r
-\r
-    public void rotatey(float degrees) {\r
-        mycos = (float) (Math.cos(degrees * myconst));\r
-        mysin = (float) (Math.sin(degrees * myconst));\r
-\r
-        tmp[0][0] = mycos;\r
-        tmp[0][1] = 0;\r
-        tmp[0][2] = -mysin;\r
-        tmp[1][0] = 0;\r
-        tmp[1][1] = 1;\r
-        tmp[1][2] = 0;\r
-        tmp[2][0] = mysin;\r
-        tmp[2][1] = 0;\r
-        tmp[2][2] = mycos;\r
-\r
-        preMultiply(tmp);\r
-    }\r
-\r
-    public float[] vectorMultiply(float[] vect) {\r
-        float[] temp = new float[3];\r
-\r
-        temp[0] = vect[0];\r
-        temp[1] = vect[1];\r
-        temp[2] = vect[2];\r
-\r
-        for (int i = 0; i < 3; i++) {\r
-            temp[i] = ((float) matrix[i][0] * vect[0]) +\r
-                ((float) matrix[i][1] * vect[1]) +\r
-                ((float) matrix[i][2] * vect[2]);\r
-        }\r
-\r
-        vect[0] = temp[0];\r
-        vect[1] = temp[1];\r
-        vect[2] = temp[2];\r
-\r
-        return vect;\r
-    }\r
-\r
-    public void preMultiply(float[][] mat) {\r
-        float[][] tmp = new float[3][3];\r
-\r
-        for (int i = 0; i < 3; i++) {\r
-            for (int j = 0; j < 3; j++) {\r
-                tmp[i][j] = (mat[i][0] * matrix[0][j]) +\r
-                    (mat[i][1] * matrix[1][j]) + (mat[i][2] * matrix[2][j]);\r
-            }\r
-        }\r
-\r
-        for (int i = 0; i < 3; i++) {\r
-            for (int j = 0; j < 3; j++) {\r
-                matrix[i][j] = tmp[i][j];\r
-            }\r
-        }\r
-    }\r
-\r
-    public void postMultiply(float[][] mat) {\r
-        float[][] tmp = new float[3][3];\r
-\r
-        for (int i = 0; i < 3; i++) {\r
-            for (int j = 0; j < 3; j++) {\r
-                tmp[i][j] = (matrix[i][0] * mat[0][j]) +\r
-                    (matrix[i][1] * mat[1][j]) + (matrix[i][2] * mat[2][j]);\r
-            }\r
-        }\r
-\r
-        for (int i = 0; i < 3; i++) {\r
-            for (int j = 0; j < 3; j++) {\r
-                matrix[i][j] = tmp[i][j];\r
-            }\r
-        }\r
-    }\r
-\r
-    public void setIdentity() {\r
-        matrix[0][0] = 1;\r
-        matrix[1][1] = 1;\r
-        matrix[2][2] = 1;\r
-        matrix[0][1] = 0;\r
-        matrix[0][2] = 0;\r
-        matrix[1][0] = 0;\r
-        matrix[1][2] = 0;\r
-        matrix[2][0] = 0;\r
-        matrix[2][1] = 0;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+public class MCMatrix {
+    float[][] matrix;
+    float[][] tmp;
+    float mycos;
+    float mysin;
+    float myconst = (float) (Math.PI / 180);
+
+    public MCMatrix(int rows, int cols) {
+        matrix = new float[rows][cols];
+        tmp = new float[rows][cols];
+    }
+
+    public void addElement(int i, int j, float value) {
+        matrix[i][j] = value;
+    }
+
+    public void rotatex(float degrees) {
+        mycos = (float) (Math.cos(degrees * myconst));
+        mysin = (float) (Math.sin(degrees * myconst));
+
+        tmp[0][0] = 1;
+        tmp[0][1] = 0;
+        tmp[0][2] = 0;
+        tmp[1][0] = 0;
+        tmp[1][1] = mycos;
+        tmp[1][2] = mysin;
+        tmp[2][0] = 0;
+        tmp[2][1] = -mysin;
+        tmp[2][2] = mycos;
+        preMultiply(tmp);
+    }
+
+    public void rotatez(float degrees) {
+        mycos = (float) (Math.cos(degrees * myconst));
+        mysin = (float) (Math.sin(degrees * myconst));
+
+        tmp[0][0] = mycos;
+        tmp[0][1] = -mysin;
+        tmp[0][2] = 0;
+        tmp[1][0] = mysin;
+        tmp[1][1] = mycos;
+        tmp[1][2] = 0;
+        tmp[2][0] = 0;
+        tmp[2][1] = 0;
+        tmp[2][2] = 1;
+
+        preMultiply(tmp);
+    }
+
+    public void rotatey(float degrees) {
+        mycos = (float) (Math.cos(degrees * myconst));
+        mysin = (float) (Math.sin(degrees * myconst));
+
+        tmp[0][0] = mycos;
+        tmp[0][1] = 0;
+        tmp[0][2] = -mysin;
+        tmp[1][0] = 0;
+        tmp[1][1] = 1;
+        tmp[1][2] = 0;
+        tmp[2][0] = mysin;
+        tmp[2][1] = 0;
+        tmp[2][2] = mycos;
+
+        preMultiply(tmp);
+    }
+
+    public float[] vectorMultiply(float[] vect) {
+        float[] temp = new float[3];
+
+        temp[0] = vect[0];
+        temp[1] = vect[1];
+        temp[2] = vect[2];
+
+        for (int i = 0; i < 3; i++) {
+            temp[i] = ((float) matrix[i][0] * vect[0]) +
+                ((float) matrix[i][1] * vect[1]) +
+                ((float) matrix[i][2] * vect[2]);
+        }
+
+        vect[0] = temp[0];
+        vect[1] = temp[1];
+        vect[2] = temp[2];
+
+        return vect;
+    }
+
+    public void preMultiply(float[][] mat) {
+        float[][] tmp = new float[3][3];
+
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                tmp[i][j] = (mat[i][0] * matrix[0][j]) +
+                    (mat[i][1] * matrix[1][j]) + (mat[i][2] * matrix[2][j]);
+            }
+        }
+
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                matrix[i][j] = tmp[i][j];
+            }
+        }
+    }
+
+    public void postMultiply(float[][] mat) {
+        float[][] tmp = new float[3][3];
+
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                tmp[i][j] = (matrix[i][0] * mat[0][j]) +
+                    (matrix[i][1] * mat[1][j]) + (matrix[i][2] * mat[2][j]);
+            }
+        }
+
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                matrix[i][j] = tmp[i][j];
+            }
+        }
+    }
+
+    public void setIdentity() {
+        matrix[0][0] = 1;
+        matrix[1][1] = 1;
+        matrix[2][2] = 1;
+        matrix[0][1] = 0;
+        matrix[0][2] = 0;
+        matrix[1][0] = 0;
+        matrix[1][2] = 0;
+        matrix[2][0] = 0;
+        matrix[2][1] = 0;
+    }
+}
index d702264..ca4e5be 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import jalview.analysis.AlignSeq;\r
-\r
-import jalview.datamodel.*;\r
-\r
-// JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListener\r
-{\r
-    MCMatrix idmat = new MCMatrix(3, 3);\r
-    MCMatrix objmat = new MCMatrix(3, 3);\r
-    boolean redrawneeded = true;\r
-    int omx = 0;\r
-    int mx = 0;\r
-    int omy = 0;\r
-    int my = 0;\r
-    public PDBfile pdb;\r
-    int bsize;\r
-    Image img;\r
-    Graphics ig;\r
-    Dimension prefsize;\r
-    float[] centre = new float[3];\r
-    float[] width = new float[3];\r
-    float maxwidth;\r
-    float scale;\r
-    String inStr;\r
-    String inType;\r
-    boolean bysequence = true;\r
-    boolean depthcue = true;\r
-    boolean wire = false;\r
-    boolean bymolecule = false;\r
-    boolean zbuffer = true;\r
-    boolean dragging;\r
-    int xstart;\r
-    int xend;\r
-    int ystart;\r
-    int yend;\r
-    int xmid;\r
-    int ymid;\r
-    Font font = new Font("Helvetica", Font.PLAIN, 10);\r
-    jalview.gui.SeqCanvas seqcanvas;\r
-    public Sequence sequence;\r
-    final StringBuffer mappingDetails = new StringBuffer();\r
-    PDBChain mainchain;\r
-    Vector highlightRes;\r
-    boolean pdbAction = false;\r
-    boolean seqColoursReady = false;\r
-    jalview.gui.FeatureRenderer fr;\r
-\r
-    public PDBCanvas(jalview.gui.SeqCanvas seqcanvas, Sequence seq)\r
-    {\r
-      this.seqcanvas = seqcanvas;\r
-      this.sequence = seq;\r
-      seqcanvas.setPDBCanvas(this);\r
-    }\r
-\r
-  public void setPDBFile(PDBfile pdb)\r
-   {\r
-        int max = -10;\r
-        int maxchain = -1;\r
-        int pdbstart = 0;\r
-        int pdbend = 0;\r
-        int seqstart = 0;\r
-        int seqend = 0;\r
-        AlignSeq maxAlignseq = null;\r
-\r
-        for (int i = 0; i < pdb.chains.size(); i++)\r
-        {\r
-\r
-          mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());\r
-          mappingDetails.append("\nNo of residues = " + ((PDBChain) pdb.chains.elementAt(i)).residues.size()+"\n\n");\r
-\r
-            // Now lets compare the sequences to get\r
-            // the start and end points.\r
-            // Align the sequence to the pdb\r
-            AlignSeq as = new AlignSeq(sequence,\r
-                    ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
-            as.calcScoreMatrix();\r
-            as.traceAlignment();\r
-            PrintStream  ps = new PrintStream(System.out)\r
-           {\r
-              public void print(String x) {\r
-                   mappingDetails.append(x);\r
-               }\r
-               public void println()\r
-               {\r
-                 mappingDetails.append("\n");\r
-               }\r
-            };\r
-\r
-            as.printAlignment(ps);\r
-\r
-\r
-\r
-            if (as.maxscore > max)\r
-            {\r
-                max = as.maxscore;\r
-                maxchain = i;\r
-                pdbstart = as.seq2start;\r
-                pdbend = as.seq2end;\r
-                seqstart = as.seq1start + sequence.getStart()-1;\r
-                seqend = as.seq1end + sequence.getEnd()-1;\r
-                maxAlignseq = as;\r
-            }\r
-\r
-            mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);\r
-            mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);\r
-        }\r
-\r
-        mainchain = (PDBChain) pdb.chains.elementAt(maxchain);\r
-\r
-        mainchain.pdbstart = pdbstart;\r
-        mainchain.pdbend = pdbend;\r
-        mainchain.seqstart = seqstart;\r
-        mainchain.seqend = seqend;\r
-        mainchain.isVisible = true;\r
-        mainchain.makeExactMapping(maxAlignseq, sequence);\r
-\r
-        this.pdb = pdb;\r
-        this.prefsize = new Dimension(getWidth(), getHeight());\r
-\r
-        //Initialize the matrices to identity\r
-        for (int i = 0; i < 3; i++) {\r
-            for (int j = 0; j < 3; j++) {\r
-                if (i != j) {\r
-                    idmat.addElement(i, j, 0);\r
-                    objmat.addElement(i, j, 0);\r
-                } else {\r
-                    idmat.addElement(i, j, 1);\r
-                    objmat.addElement(i, j, 1);\r
-                }\r
-            }\r
-        }\r
-\r
-        addMouseMotionListener(this);\r
-        addMouseListener(this);\r
-\r
-        addMouseWheelListener(new MouseWheelListener()\r
-        {\r
-          public void mouseWheelMoved(MouseWheelEvent e)\r
-          {\r
-            if (e.getWheelRotation() > 0)\r
-            {\r
-              scale = (float) (scale * 1.1);\r
-              redrawneeded = true;\r
-              repaint();\r
-            }\r
-\r
-            else\r
-            {\r
-              scale = (float) (scale * 0.9);\r
-              redrawneeded = true;\r
-              repaint();\r
-            }\r
-          }\r
-       });\r
-\r
-\r
-        findCentre();\r
-        findWidth();\r
-\r
-        setupBonds();\r
-\r
-        scale = findScale();\r
-\r
-        ToolTipManager.sharedInstance().registerComponent(this);\r
-        ToolTipManager.sharedInstance().setInitialDelay(0);\r
-        ToolTipManager.sharedInstance().setDismissDelay(10000);\r
-    }\r
-\r
-\r
-    Vector visiblebonds;\r
-    void setupBonds()\r
-    {\r
-      seqColoursReady = false;\r
-      // Sort the bonds by z coord\r
-      visiblebonds = new Vector();\r
-\r
-      for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-      {\r
-        if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
-        {\r
-          Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-          for (int i = 0; i < tmp.size(); i++)\r
-          {\r
-            visiblebonds.addElement(tmp.elementAt(i));\r
-          }\r
-        }\r
-      }\r
-\r
-      updateSeqColours();\r
-      seqColoursReady = true;\r
-      redrawneeded = true;\r
-      repaint();\r
-    }\r
-\r
-\r
-    public void findWidth() {\r
-        float[] max = new float[3];\r
-        float[] min = new float[3];\r
-\r
-        max[0] = (float) -1e30;\r
-        max[1] = (float) -1e30;\r
-        max[2] = (float) -1e30;\r
-\r
-        min[0] = (float) 1e30;\r
-        min[1] = (float) 1e30;\r
-        min[2] = (float) 1e30;\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
-            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                for (int i = 0; i < bonds.size(); i++) {\r
-                    Bond tmp = (Bond) bonds.elementAt(i);\r
-\r
-                    if (tmp.start[0] >= max[0]) {\r
-                        max[0] = tmp.start[0];\r
-                    }\r
-\r
-                    if (tmp.start[1] >= max[1]) {\r
-                        max[1] = tmp.start[1];\r
-                    }\r
-\r
-                    if (tmp.start[2] >= max[2]) {\r
-                        max[2] = tmp.start[2];\r
-                    }\r
-\r
-                    if (tmp.start[0] <= min[0]) {\r
-                        min[0] = tmp.start[0];\r
-                    }\r
-\r
-                    if (tmp.start[1] <= min[1]) {\r
-                        min[1] = tmp.start[1];\r
-                    }\r
-\r
-                    if (tmp.start[2] <= min[2]) {\r
-                        min[2] = tmp.start[2];\r
-                    }\r
-\r
-                    if (tmp.end[0] >= max[0]) {\r
-                        max[0] = tmp.end[0];\r
-                    }\r
-\r
-                    if (tmp.end[1] >= max[1]) {\r
-                        max[1] = tmp.end[1];\r
-                    }\r
-\r
-                    if (tmp.end[2] >= max[2]) {\r
-                        max[2] = tmp.end[2];\r
-                    }\r
-\r
-                    if (tmp.end[0] <= min[0]) {\r
-                        min[0] = tmp.end[0];\r
-                    }\r
-\r
-                    if (tmp.end[1] <= min[1]) {\r
-                        min[1] = tmp.end[1];\r
-                    }\r
-\r
-                    if (tmp.end[2] <= min[2]) {\r
-                        min[2] = tmp.end[2];\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        /*\r
-        System.out.println("xmax " + max[0] + " min " + min[0]);\r
-        System.out.println("ymax " + max[1] + " min " + min[1]);\r
-        System.out.println("zmax " + max[2] + " min " + min[2]);*/\r
-\r
-        width[0] = (float) Math.abs(max[0] - min[0]);\r
-        width[1] = (float) Math.abs(max[1] - min[1]);\r
-        width[2] = (float) Math.abs(max[2] - min[2]);\r
-\r
-        maxwidth = width[0];\r
-\r
-        if (width[1] > width[0]) {\r
-            maxwidth = width[1];\r
-        }\r
-\r
-        if (width[2] > width[1]) {\r
-            maxwidth = width[2];\r
-        }\r
-\r
-       // System.out.println("Maxwidth = " + maxwidth);\r
-    }\r
-\r
-    public float findScale() {\r
-        int dim;\r
-        int width;\r
-        int height;\r
-\r
-        if (getWidth() != 0) {\r
-            width = getWidth();\r
-            height = getHeight();\r
-        } else {\r
-            width = prefsize.width;\r
-            height = prefsize.height;\r
-        }\r
-\r
-        if (width < height) {\r
-            dim = width;\r
-        } else {\r
-            dim = height;\r
-        }\r
-\r
-        return (float) (dim / (1.5d * maxwidth));\r
-    }\r
-\r
-    public void findCentre() {\r
-        float xtot = 0;\r
-        float ytot = 0;\r
-        float ztot = 0;\r
-\r
-        int bsize = 0;\r
-\r
-        //Find centre coordinate\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
-            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                bsize += bonds.size();\r
-\r
-                for (int i = 0; i < bonds.size(); i++) {\r
-                    xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
-                        ((Bond) bonds.elementAt(i)).end[0];\r
-\r
-                    ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
-                        ((Bond) bonds.elementAt(i)).end[1];\r
-\r
-                    ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
-                        ((Bond) bonds.elementAt(i)).end[2];\r
-                }\r
-            }\r
-        }\r
-\r
-        centre[0] = xtot / (2 * (float) bsize);\r
-        centre[1] = ytot / (2 * (float) bsize);\r
-        centre[2] = ztot / (2 * (float) bsize);\r
-    }\r
-\r
-    public void paintComponent(Graphics g)\r
-    {\r
-      super.paintComponent(g);\r
-\r
-      if(!seqColoursReady)\r
-      {\r
-        g.setColor(Color.black);\r
-        g.setFont(new Font("Verdana", Font.BOLD, 14));\r
-        g.drawString("Retrieving PDB data....", 20, getHeight()/2);\r
-        return;\r
-      }\r
-\r
-\r
-        //Only create the image at the beginning -\r
-        //this saves much memory usage\r
-        if ((img == null)\r
-            || (prefsize.width != getWidth())\r
-            || (prefsize.height != getHeight()))\r
-\r
-      {\r
-            prefsize.width = getWidth();\r
-            prefsize.height = getHeight();\r
-\r
-            scale = findScale();\r
-            img = createImage(prefsize.width, prefsize.height);\r
-            ig = img.getGraphics();\r
-            Graphics2D ig2 = (Graphics2D) ig;\r
-\r
-            ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                                 RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-            redrawneeded = true;\r
-        }\r
-\r
-\r
-        if (redrawneeded)\r
-        {\r
-          drawAll(ig, prefsize.width, prefsize.height);\r
-          redrawneeded = false;\r
-        }\r
-\r
-        g.drawImage(img, 0, 0, this);\r
-\r
-        pdbAction = false;\r
-    }\r
-\r
-    public void drawAll(Graphics g, int width, int height)\r
-    {\r
-      g.setColor(Color.black);\r
-      g.fillRect(0, 0, width, height);\r
-      drawScene(g);\r
-      drawLabels(g);\r
-    }\r
-\r
-\r
-    public void updateSeqColours()\r
-    {\r
-      if(pdbAction)\r
-      {\r
-        return;\r
-      }\r
-\r
-     // System.out.println("update seq colours");\r
-      if(bysequence && pdb!=null)\r
-      {\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-        {\r
-          colourBySequence( (PDBChain) pdb.chains.elementAt(ii));\r
-        }\r
-      }\r
-\r
-      redrawneeded=true;\r
-      repaint();\r
-    }\r
-\r
-    int findTrueIndex(int pos)\r
-    {\r
-      // returns the alignment position for a residue\r
-      int j = sequence.getStart();\r
-      int i = 0;\r
-\r
-      while ( (i < sequence.getLength()) && (j <= sequence.getEnd()) && (j <= pos+1))\r
-      {\r
-        if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))\r
-        {\r
-          j++;\r
-        }\r
-\r
-        i++;\r
-      }\r
-\r
-      if(i>1)\r
-         i--;\r
-\r
-      if ( (j == sequence.getEnd()) && (j < pos))\r
-      {\r
-        return sequence.getEnd() + 1;\r
-      }\r
-      else\r
-      {\r
-        return i;\r
-      }\r
-    }\r
-\r
-    // This method has been taken out of PDBChain to allow\r
-    // Applet and Application specific sequence renderers to be used\r
-    void colourBySequence(PDBChain chain)\r
-    {\r
-     // System.out.println("colour by seq");\r
-     boolean showFeatures = false;\r
-     if(seqcanvas.getViewport().getShowSequenceFeatures())\r
-     {\r
-       showFeatures = true;\r
-       if (fr == null)\r
-         fr = new jalview.gui.FeatureRenderer(seqcanvas.getViewport());\r
-\r
-       fr.transferSettings( seqcanvas.getFeatureRenderer() );\r
-     }\r
-\r
-      for (int i = 0; i < chain.bonds.size(); i++)\r
-      {\r
-        Bond tmp = (Bond) chain.bonds.elementAt(i);\r
-        tmp.startCol = Color.lightGray;\r
-        tmp.endCol = Color.lightGray;\r
-\r
-        if(chain!=mainchain)\r
-          continue;\r
-\r
-        if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
-            (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))\r
-        {\r
-            int index = findTrueIndex(tmp.at1.alignmentMapping);\r
-                //sequence.findIndex(tmp.at1.alignmentMapping);\r
-            if (index != -1)\r
-            {\r
-              tmp.startCol = seqcanvas.getSequenceRenderer().\r
-                  getResidueBoxColour( sequence, index);\r
-              if(tmp.startCol==null)\r
-                tmp.startCol = Color.white;\r
-\r
-              if(showFeatures)\r
-                tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);\r
-            }\r
-        }\r
-\r
-        if ( (tmp.at2.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
-            (tmp.at2.resNumber <= ( (chain.pdbend + chain.offset) - 1)))\r
-        {\r
-\r
-            int index =  findTrueIndex(tmp.at2.alignmentMapping);\r
-                //sequence.findIndex( tmp.at2.alignmentMapping );\r
-            if (index != -1)\r
-            {\r
-              tmp.endCol = seqcanvas.getSequenceRenderer().\r
-                  getResidueBoxColour( sequence, index);\r
-              if(tmp.endCol==null)\r
-                tmp.endCol = Color.white;\r
-              if(showFeatures)\r
-                tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);\r
-            }\r
-        }\r
-      }\r
-    }\r
-\r
-\r
-    Zsort zsort;\r
-    public void drawScene(Graphics g)\r
-    {\r
-        if (zbuffer)\r
-        {\r
-          if(zsort==null)\r
-            zsort = new Zsort();\r
-\r
-          zsort.Zsort(visiblebonds);\r
-        }\r
-\r
-        Bond tmpBond=null;\r
-        for (int i = 0; i < visiblebonds.size(); i++)\r
-        {\r
-            tmpBond = (Bond) visiblebonds.elementAt(i);\r
-\r
-            xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
-                (getWidth() / 2));\r
-            ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
-                (getHeight() / 2));\r
-\r
-            xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
-                (getWidth() / 2));\r
-            yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
-                (getHeight() / 2));\r
-\r
-            xmid = (xend + xstart) / 2;\r
-            ymid = (yend + ystart) / 2;\r
-\r
-            if (depthcue && !bymolecule)\r
-            {\r
-                if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))\r
-                {\r
-                    g.setColor(tmpBond.startCol.darker().darker());\r
-                    drawLine(g, xstart, ystart, xmid, ymid);\r
-                    g.setColor(tmpBond.endCol.darker().darker());\r
-                    drawLine(g, xmid, ymid, xend, yend);\r
-                } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
-                    g.setColor(tmpBond.startCol.darker());\r
-                    drawLine(g, xstart, ystart, xmid, ymid);\r
-\r
-                    g.setColor(tmpBond.endCol.darker());\r
-                    drawLine(g, xmid, ymid, xend, yend);\r
-                } else {\r
-                    g.setColor(tmpBond.startCol);\r
-                    drawLine(g, xstart, ystart, xmid, ymid);\r
-\r
-                    g.setColor(tmpBond.endCol);\r
-                    drawLine(g, xmid, ymid, xend, yend);\r
-                }\r
-            } else if (depthcue && bymolecule) {\r
-                if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
-                    g.setColor(Color.green.darker().darker());\r
-                    drawLine(g, xstart, ystart, xend, yend);\r
-                } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
-                    g.setColor(Color.green.darker());\r
-                    drawLine(g, xstart, ystart, xend, yend);\r
-                } else {\r
-                    g.setColor(Color.green);\r
-                    drawLine(g, xstart, ystart, xend, yend);\r
-                }\r
-            } else if (!depthcue && !bymolecule) {\r
-                g.setColor(tmpBond.startCol);\r
-                drawLine(g, xstart, ystart, xmid, ymid);\r
-                g.setColor(tmpBond.endCol);\r
-                drawLine(g, xmid, ymid, xend, yend);\r
-            } else {\r
-                drawLine(g, xstart, ystart, xend, yend);\r
-            }\r
-\r
-            if(highlightBond1!=null && highlightBond1==tmpBond)\r
-            {\r
-              g.setColor(tmpBond.endCol.brighter().brighter().brighter().brighter());\r
-              drawLine(g, xmid, ymid, xend, yend);\r
-            }\r
-\r
-            if(highlightBond2!=null && highlightBond2==tmpBond)\r
-            {\r
-              g.setColor(tmpBond.startCol.brighter().brighter().brighter().brighter());\r
-              drawLine(g, xstart, ystart, xmid, ymid);\r
-            }\r
-\r
-        }\r
-\r
-\r
-    }\r
-\r
-    public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
-        if (!wire) {\r
-            if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
-                g.drawLine(x1, y1, x2, y2);\r
-                g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
-                g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
-            } else {\r
-                g.setColor(g.getColor().brighter());\r
-                g.drawLine(x1, y1, x2, y2);\r
-                g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
-                g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
-            }\r
-        } else {\r
-            g.drawLine(x1, y1, x2, y2);\r
-        }\r
-    }\r
-\r
-    public Dimension minimumsize() {\r
-        return prefsize;\r
-    }\r
-\r
-    public Dimension preferredsize() {\r
-        return prefsize;\r
-    }\r
-\r
-    public void keyPressed(KeyEvent evt)\r
-    {\r
-      if (evt.getKeyCode() == KeyEvent.VK_UP)\r
-      {\r
-        scale = (float) (scale * 1.1);\r
-        redrawneeded = true;\r
-        repaint();\r
-      }\r
-      else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
-      {\r
-        scale = (float) (scale * 0.9);\r
-        redrawneeded = true;\r
-        repaint();\r
-      }\r
-    }\r
-\r
-    public void mousePressed(MouseEvent e)\r
-    {\r
-        pdbAction = true;\r
-        Atom fatom = findAtom(e.getX(), e.getY());\r
-        if(fatom!=null)\r
-        {\r
-          fatom.isSelected = !fatom.isSelected;\r
-\r
-          redrawneeded = true;\r
-          repaint();\r
-          if (foundchain != -1)\r
-          {\r
-            PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
-            if (chain == mainchain)\r
-            {\r
-              if (fatom.alignmentMapping != -1)\r
-              {\r
-                if (highlightRes == null)\r
-                  highlightRes = new Vector();\r
-\r
-                if (highlightRes.contains(fatom.alignmentMapping+""))\r
-                  highlightRes.remove(fatom.alignmentMapping + "");\r
-                else\r
-                  highlightRes.add(fatom.alignmentMapping + "");\r
-              }\r
-            }\r
-          }\r
-\r
-        }\r
-        mx = e.getX();\r
-        my = e.getY();\r
-        omx = mx;\r
-        omy = my;\r
-        dragging = false;\r
-    }\r
-\r
-    public void mouseMoved(MouseEvent e)\r
-    {\r
-      pdbAction = true;\r
-      if(highlightBond1!=null)\r
-      {\r
-        highlightBond1.at2.isSelected = false;\r
-        highlightBond2.at1.isSelected = false;\r
-        highlightBond1 = null;\r
-        highlightBond2 = null;\r
-      }\r
-\r
-        Atom fatom = findAtom(e.getX(), e.getY());\r
-\r
-        PDBChain chain = null;\r
-        if(foundchain!=-1)\r
-        {\r
-          chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
-          if(chain == mainchain)\r
-          {\r
-            highlightSeqcanvas( fatom.alignmentMapping );\r
-          }\r
-        }\r
-\r
-        if (fatom != null)\r
-        {\r
-            this.setToolTipText(chain.id+":"+ fatom.resNumber+" "+ fatom.resName);\r
-        } else\r
-        {\r
-            highlightSeqcanvas( -1);\r
-            this.setToolTipText(null);\r
-        }\r
-    }\r
-\r
-\r
-    void highlightSeqcanvas(int pos)\r
-    {\r
-      SearchResults searchResults = new SearchResults();\r
-      if(highlightRes!=null)\r
-      {\r
-        for (int i = 0; i < highlightRes.size(); i++)\r
-        {\r
-          int a = Integer.parseInt(highlightRes.elementAt(\r
-              i).toString())+1;\r
-\r
-          searchResults.addResult(sequence, a, a);\r
-        }\r
-      }\r
-\r
-      if(pos!=-1)\r
-      {\r
-        searchResults.addResult(sequence, pos+1, pos+1);\r
-      }\r
-\r
-      seqcanvas.highlightSearchResults(searchResults);\r
-    }\r
-\r
-\r
-    public void mouseClicked(MouseEvent e)  { }\r
-\r
-    public void mouseEntered(MouseEvent e) {  }\r
-\r
-    public void mouseExited(MouseEvent e) { }\r
-\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-        int x = evt.getX();\r
-        int y = evt.getY();\r
-        mx = x;\r
-        my = y;\r
-\r
-\r
-        MCMatrix objmat = new MCMatrix(3, 3);\r
-        objmat.setIdentity();\r
-\r
-        if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
-            objmat.rotatez((float) ((mx - omx)));\r
-        } else {\r
-            objmat.rotatex((float) ((my - omy)));\r
-            objmat.rotatey((float) ((omx - mx)));\r
-        }\r
-\r
-        //Alter the bonds\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
-            Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-            for (int i = 0; i < bonds.size(); i++) {\r
-                Bond tmpBond = (Bond) bonds.elementAt(i);\r
-\r
-                //Translate the bond so the centre is 0,0,0\r
-                tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
-\r
-                //Now apply the rotation matrix\r
-                tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
-                tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
-\r
-                //Now translate back again\r
-                tmpBond.translate(centre[0], centre[1], centre[2]);\r
-            }\r
-        }\r
-\r
-        objmat = null;\r
-\r
-        omx = mx;\r
-        omy = my;\r
-\r
-        dragging = true;\r
-\r
-        redrawneeded = true;\r
-\r
-        repaint();\r
-    }\r
-\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-        dragging = false;\r
-        return;\r
-    }\r
-\r
-    void drawLabels(Graphics g) {\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-        {\r
-            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
-\r
-            if (chain.isVisible)\r
-            {\r
-              Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-              for (int i = 0; i < bonds.size(); i++)\r
-              {\r
-                  Bond tmpBond = (Bond) bonds.elementAt(i);\r
-\r
-                  if (tmpBond.at1.isSelected)\r
-                  {\r
-                      labelAtom(g, tmpBond, 1);\r
-                  }\r
-\r
-                  if (tmpBond.at2.isSelected)\r
-                  {\r
-\r
-                      labelAtom(g, tmpBond, 2);\r
-                  }\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    public void labelAtom(Graphics g, Bond b, int n) {\r
-        g.setFont(font);\r
-        g.setColor(Color.red);\r
-        if (n == 1)\r
-        {\r
-            int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
-                (getWidth() / 2));\r
-            int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
-                (getHeight() / 2));\r
-\r
-            g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
-        }\r
-\r
-        if (n == 2) {\r
-            int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
-                (getWidth() / 2));\r
-            int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
-                (getHeight() / 2));\r
-\r
-            g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
-        }\r
-    }\r
-\r
-    int foundchain = -1;\r
-    public Atom findAtom(int x, int y) {\r
-        Atom fatom = null;\r
-\r
-        foundchain = -1;\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-        {\r
-            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
-            int truex;\r
-            Bond tmpBond=null;\r
-\r
-            if (chain.isVisible)\r
-            {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-                for (int i = 0; i < bonds.size(); i++)\r
-                {\r
-                    tmpBond = (Bond) bonds.elementAt(i);\r
-\r
-                    truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
-                        (getWidth() / 2));\r
-\r
-                    if (Math.abs(truex - x) <= 2)\r
-                    {\r
-                        int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
-                            (getHeight() / 2));\r
-\r
-                        if (Math.abs(truey - y) <= 2)\r
-                        {\r
-                            fatom = tmpBond.at1;\r
-                            foundchain = ii;\r
-                            break;\r
-                        }\r
-                    }\r
-                }\r
-\r
-                // Still here? Maybe its the last bond\r
-\r
-                truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +\r
-                               (getWidth() / 2));\r
-\r
-                if (Math.abs(truex - x) <= 2)\r
-                {\r
-                  int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +\r
-                                     (getHeight() / 2));\r
-\r
-                  if (Math.abs(truey - y) <= 2)\r
-                  {\r
-                    fatom = tmpBond.at2;\r
-                    foundchain = ii;\r
-                    break;\r
-                  }\r
-                }\r
-\r
-            }\r
-\r
-            if (fatom != null) //)&& chain.ds != null)\r
-             {\r
-                chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
-            }\r
-        }\r
-\r
-        return fatom;\r
-    }\r
-\r
-   Bond highlightBond1, highlightBond2;\r
-   public void highlightRes(int ii)\r
-  {\r
-    if( !seqColoursReady )\r
-      return;\r
-\r
-    if (highlightRes != null\r
-        && highlightRes.contains((ii-1) + ""))\r
-    {\r
-      return;\r
-    }\r
-\r
-    int index = -1;\r
-    Bond tmpBond;\r
-    for(index=0; index<mainchain.bonds.size(); index++)\r
-    {\r
-      tmpBond = (Bond) mainchain.bonds.elementAt(index);\r
-      if (tmpBond.at1.alignmentMapping == ii - 1)\r
-      {\r
-        if (highlightBond1 != null)\r
-          highlightBond1.at2.isSelected = false;\r
-\r
-        if (highlightBond2 != null)\r
-          highlightBond2.at1.isSelected = false;\r
-\r
-        highlightBond1 = null;\r
-        highlightBond2 = null;\r
-\r
-        if (index > 0)\r
-        {\r
-          highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
-          highlightBond1.at2.isSelected = true;\r
-        }\r
-\r
-        if (index != mainchain.bonds.size())\r
-        {\r
-          highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
-          highlightBond2.at1.isSelected = true;\r
-        }\r
-\r
-        break;\r
-      }\r
-    }\r
-\r
-    redrawneeded = true;\r
-    repaint();\r
-  }\r
-\r
-    public void setAllchainsVisible(boolean b)\r
-    {\r
-      for (int ii = 0; ii < pdb.chains.size(); ii++)\r
-      {\r
-        PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
-        chain.isVisible = b;\r
-      }\r
-      mainchain.isVisible = true;\r
-      findCentre();\r
-      setupBonds();\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import jalview.analysis.AlignSeq;
+
+import jalview.datamodel.*;
+
+// JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug
+import java.awt.*;
+import java.awt.event.*;
+
+import java.io.*;
+
+import java.util.*;
+
+import javax.swing.*;
+
+
+public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListener
+{
+    MCMatrix idmat = new MCMatrix(3, 3);
+    MCMatrix objmat = new MCMatrix(3, 3);
+    boolean redrawneeded = true;
+    int omx = 0;
+    int mx = 0;
+    int omy = 0;
+    int my = 0;
+    public PDBfile pdb;
+    int bsize;
+    Image img;
+    Graphics ig;
+    Dimension prefsize;
+    float[] centre = new float[3];
+    float[] width = new float[3];
+    float maxwidth;
+    float scale;
+    String inStr;
+    String inType;
+    boolean bysequence = true;
+    boolean depthcue = true;
+    boolean wire = false;
+    boolean bymolecule = false;
+    boolean zbuffer = true;
+    boolean dragging;
+    int xstart;
+    int xend;
+    int ystart;
+    int yend;
+    int xmid;
+    int ymid;
+    Font font = new Font("Helvetica", Font.PLAIN, 10);
+    jalview.gui.SeqCanvas seqcanvas;
+    public Sequence sequence;
+    final StringBuffer mappingDetails = new StringBuffer();
+    PDBChain mainchain;
+    Vector highlightRes;
+    boolean pdbAction = false;
+    boolean seqColoursReady = false;
+    jalview.gui.FeatureRenderer fr;
+    Color backgroundColour = Color.black;
+
+    public PDBCanvas(jalview.gui.SeqCanvas seqcanvas, Sequence seq)
+    {
+      this.seqcanvas = seqcanvas;
+      this.sequence = seq;
+      seqcanvas.setPDBCanvas(this);
+    }
+
+  public void setPDBFile(PDBfile pdb)
+   {
+        int max = -10;
+        int maxchain = -1;
+        int pdbstart = 0;
+        int pdbend = 0;
+        int seqstart = 0;
+        int seqend = 0;
+        AlignSeq maxAlignseq = null;
+
+        for (int i = 0; i < pdb.chains.size(); i++)
+        {
+
+          mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());
+          mappingDetails.append("\nNo of residues = " + ((PDBChain) 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");
+            as.calcScoreMatrix();
+            as.traceAlignment();
+            PrintStream  ps = new PrintStream(System.out)
+           {
+              public void print(String x) {
+                   mappingDetails.append(x);
+               }
+               public void println()
+               {
+                 mappingDetails.append("\n");
+               }
+            };
+
+            as.printAlignment(ps);
+
+
+
+            if (as.maxscore > max)
+            {
+                max = as.maxscore;
+                maxchain = i;
+                pdbstart = as.seq2start;
+                pdbend = as.seq2end;
+                seqstart = as.seq1start + sequence.getStart()-1;
+                seqend = as.seq1end + sequence.getEnd()-1;
+                maxAlignseq = as;
+            }
+
+            mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);
+            mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);
+        }
+
+        mainchain = (PDBChain) pdb.chains.elementAt(maxchain);
+
+        mainchain.pdbstart = pdbstart;
+        mainchain.pdbend = pdbend;
+        mainchain.seqstart = seqstart;
+        mainchain.seqend = seqend;
+        mainchain.isVisible = true;
+        mainchain.makeExactMapping(maxAlignseq, sequence);
+
+        this.pdb = pdb;
+        this.prefsize = new Dimension(getWidth(), getHeight());
+
+        //Initialize the matrices to identity
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                if (i != j) {
+                    idmat.addElement(i, j, 0);
+                    objmat.addElement(i, j, 0);
+                } else {
+                    idmat.addElement(i, j, 1);
+                    objmat.addElement(i, j, 1);
+                }
+            }
+        }
+
+        addMouseMotionListener(this);
+        addMouseListener(this);
+
+        addMouseWheelListener(new MouseWheelListener()
+        {
+          public void mouseWheelMoved(MouseWheelEvent e)
+          {
+            if (e.getWheelRotation() > 0)
+            {
+              scale = (float) (scale * 1.1);
+              redrawneeded = true;
+              repaint();
+            }
+
+            else
+            {
+              scale = (float) (scale * 0.9);
+              redrawneeded = true;
+              repaint();
+            }
+          }
+       });
+
+
+        findCentre();
+        findWidth();
+
+        setupBonds();
+
+        scale = findScale();
+
+        ToolTipManager.sharedInstance().registerComponent(this);
+        ToolTipManager.sharedInstance().setInitialDelay(0);
+        ToolTipManager.sharedInstance().setDismissDelay(10000);
+    }
+
+
+    Vector visiblebonds;
+    void setupBonds()
+    {
+      seqColoursReady = false;
+      // Sort the bonds by z coord
+      visiblebonds = new Vector();
+
+      for (int ii = 0; ii < pdb.chains.size(); ii++)
+      {
+        if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)
+        {
+          Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+          for (int i = 0; i < tmp.size(); i++)
+          {
+            visiblebonds.addElement(tmp.elementAt(i));
+          }
+        }
+      }
+
+      updateSeqColours();
+      seqColoursReady = true;
+      redrawneeded = true;
+      repaint();
+    }
+
+
+    public void findWidth() {
+        float[] max = new float[3];
+        float[] min = new float[3];
+
+        max[0] = (float) -1e30;
+        max[1] = (float) -1e30;
+        max[2] = (float) -1e30;
+
+        min[0] = (float) 1e30;
+        min[1] = (float) 1e30;
+        min[2] = (float) 1e30;
+
+        for (int ii = 0; ii < pdb.chains.size(); ii++) {
+            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                for (int i = 0; i < bonds.size(); i++) {
+                    Bond tmp = (Bond) bonds.elementAt(i);
+
+                    if (tmp.start[0] >= max[0]) {
+                        max[0] = tmp.start[0];
+                    }
+
+                    if (tmp.start[1] >= max[1]) {
+                        max[1] = tmp.start[1];
+                    }
+
+                    if (tmp.start[2] >= max[2]) {
+                        max[2] = tmp.start[2];
+                    }
+
+                    if (tmp.start[0] <= min[0]) {
+                        min[0] = tmp.start[0];
+                    }
+
+                    if (tmp.start[1] <= min[1]) {
+                        min[1] = tmp.start[1];
+                    }
+
+                    if (tmp.start[2] <= min[2]) {
+                        min[2] = tmp.start[2];
+                    }
+
+                    if (tmp.end[0] >= max[0]) {
+                        max[0] = tmp.end[0];
+                    }
+
+                    if (tmp.end[1] >= max[1]) {
+                        max[1] = tmp.end[1];
+                    }
+
+                    if (tmp.end[2] >= max[2]) {
+                        max[2] = tmp.end[2];
+                    }
+
+                    if (tmp.end[0] <= min[0]) {
+                        min[0] = tmp.end[0];
+                    }
+
+                    if (tmp.end[1] <= min[1]) {
+                        min[1] = tmp.end[1];
+                    }
+
+                    if (tmp.end[2] <= min[2]) {
+                        min[2] = tmp.end[2];
+                    }
+                }
+            }
+        }
+        /*
+        System.out.println("xmax " + max[0] + " min " + min[0]);
+        System.out.println("ymax " + max[1] + " min " + min[1]);
+        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]);
+
+        maxwidth = width[0];
+
+        if (width[1] > width[0]) {
+            maxwidth = width[1];
+        }
+
+        if (width[2] > width[1]) {
+            maxwidth = width[2];
+        }
+
+       // System.out.println("Maxwidth = " + maxwidth);
+    }
+
+    public float findScale() {
+        int dim;
+        int width;
+        int height;
+
+        if (getWidth() != 0) {
+            width = getWidth();
+            height = getHeight();
+        } else {
+            width = prefsize.width;
+            height = prefsize.height;
+        }
+
+        if (width < height) {
+            dim = width;
+        } else {
+            dim = height;
+        }
+
+        return (float) (dim / (1.5d * maxwidth));
+    }
+
+    public void findCentre() {
+        float xtot = 0;
+        float ytot = 0;
+        float ztot = 0;
+
+        int bsize = 0;
+
+        //Find centre coordinate
+        for (int ii = 0; ii < pdb.chains.size(); ii++) {
+            if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                bsize += bonds.size();
+
+                for (int i = 0; i < bonds.size(); i++) {
+                    xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +
+                        ((Bond) bonds.elementAt(i)).end[0];
+
+                    ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +
+                        ((Bond) bonds.elementAt(i)).end[1];
+
+                    ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +
+                        ((Bond) bonds.elementAt(i)).end[2];
+                }
+            }
+        }
+
+        centre[0] = xtot / (2 * (float) bsize);
+        centre[1] = ytot / (2 * (float) bsize);
+        centre[2] = ztot / (2 * (float) bsize);
+    }
+
+    public void paintComponent(Graphics g)
+    {
+      super.paintComponent(g);
+
+      if(!seqColoursReady)
+      {
+        g.setColor(Color.black);
+        g.setFont(new Font("Verdana", Font.BOLD, 14));
+        g.drawString("Retrieving PDB data....", 20, getHeight()/2);
+        return;
+      }
+
+
+        //Only create the image at the beginning -
+        //this saves much memory usage
+        if ((img == null)
+            || (prefsize.width != getWidth())
+            || (prefsize.height != getHeight()))
+
+      {
+            prefsize.width = getWidth();
+            prefsize.height = getHeight();
+
+            scale = findScale();
+            img = createImage(prefsize.width, prefsize.height);
+            ig = img.getGraphics();
+            Graphics2D ig2 = (Graphics2D) ig;
+
+            ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                 RenderingHints.VALUE_ANTIALIAS_ON);
+
+            redrawneeded = true;
+        }
+
+
+        if (redrawneeded)
+        {
+          drawAll(ig, prefsize.width, prefsize.height);
+          redrawneeded = false;
+        }
+
+        g.drawImage(img, 0, 0, this);
+
+        pdbAction = false;
+    }
+
+    public void drawAll(Graphics g, int width, int height)
+    {
+      g.setColor(backgroundColour);
+      g.fillRect(0, 0, width, height);
+      drawScene(g);
+      drawLabels(g);
+    }
+
+
+    public void updateSeqColours()
+    {
+      if(pdbAction)
+      {
+        return;
+      }
+
+     // System.out.println("update seq colours");
+      if(bysequence && pdb!=null)
+      {
+        for (int ii = 0; ii < pdb.chains.size(); ii++)
+        {
+          colourBySequence( (PDBChain) pdb.chains.elementAt(ii));
+        }
+      }
+
+      redrawneeded=true;
+      repaint();
+    }
+
+    int findTrueIndex(int pos)
+    {
+      // returns the alignment position for a residue
+      int j = sequence.getStart();
+      int i = 0;
+
+      while ( (i < sequence.getLength()) && (j <= sequence.getEnd()) && (j <= pos+1))
+      {
+        if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))
+        {
+          j++;
+        }
+
+        i++;
+      }
+
+      if(i>1)
+         i--;
+
+      if ( (j == sequence.getEnd()) && (j < pos))
+      {
+        return sequence.getEnd() + 1;
+      }
+      else
+      {
+        return i;
+      }
+    }
+
+    // This method has been taken out of PDBChain to allow
+    // Applet and Application specific sequence renderers to be used
+    void colourBySequence(PDBChain chain)
+    {
+     // System.out.println("colour by seq");
+     boolean showFeatures = false;
+     if(seqcanvas.getViewport().getShowSequenceFeatures())
+     {
+       showFeatures = true;
+       if (fr == null)
+         fr = new jalview.gui.FeatureRenderer(seqcanvas.getViewport());
+
+       fr.transferSettings( seqcanvas.getFeatureRenderer() );
+     }
+
+      Bond tmp;
+      for (int i = 0; i < chain.bonds.size(); i++)
+      {
+        tmp = (Bond) chain.bonds.elementAt(i);
+
+        if(chain!=mainchain)
+          continue;
+
+        if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
+            (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))
+        {
+            int index = findTrueIndex(tmp.at1.alignmentMapping);
+                //sequence.findIndex(tmp.at1.alignmentMapping);
+            if (index != -1)
+            {
+              tmp.startCol = seqcanvas.getSequenceRenderer().
+                  getResidueBoxColour( sequence, index);
+
+              if(showFeatures)
+                tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);
+
+              if(tmp.startCol==null)
+                tmp.startCol = Color.white;
+            }
+        }
+
+        if ( (tmp.at2.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
+            (tmp.at2.resNumber <= ( (chain.pdbend + chain.offset) - 1)))
+        {
+
+            int index =  findTrueIndex(tmp.at2.alignmentMapping);
+                //sequence.findIndex( tmp.at2.alignmentMapping );
+            if (index != -1)
+            {
+              tmp.endCol = seqcanvas.getSequenceRenderer().
+                  getResidueBoxColour( sequence, index);
+
+              if(showFeatures)
+                tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);
+
+              if(tmp.endCol==null)
+                tmp.endCol = Color.white;
+            }
+        }
+      }
+    }
+
+
+    Zsort zsort;
+    public void drawScene(Graphics g)
+    {
+      if (zbuffer)
+      {
+        if (zsort == null)
+          zsort = new Zsort();
+
+        zsort.Zsort(visiblebonds);
+      }
+
+      Bond tmpBond = null;
+      for (int i = 0; i < visiblebonds.size(); i++)
+      {
+        tmpBond = (Bond) visiblebonds.elementAt(i);
+
+        xstart = (int) ( ( (tmpBond.start[0] - centre[0]) * scale) +
+                        (getWidth() / 2));
+        ystart = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +
+                        (getHeight() / 2));
+
+        xend = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +
+                      (getWidth() / 2));
+        yend = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +
+                      (getHeight() / 2));
+
+        xmid = (xend + xstart) / 2;
+        ymid = (yend + ystart) / 2;
+        if (depthcue && !bymolecule)
+        {
+          if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))
+          {
+
+            g.setColor(tmpBond.startCol.darker().darker());
+            drawLine(g, xstart, ystart, xmid, ymid);
+            g.setColor(tmpBond.endCol.darker().darker());
+            drawLine(g, xmid, ymid, xend, yend);
+
+          }
+          else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))
+          {
+            g.setColor(tmpBond.startCol.darker());
+            drawLine(g, xstart, ystart, xmid, ymid);
+
+            g.setColor(tmpBond.endCol.darker());
+            drawLine(g, xmid, ymid, xend, yend);
+          }
+          else
+          {
+            g.setColor(tmpBond.startCol);
+            drawLine(g, xstart, ystart, xmid, ymid);
+
+            g.setColor(tmpBond.endCol);
+            drawLine(g, xmid, ymid, xend, yend);
+          }
+        }
+        else if (depthcue && bymolecule)
+        {
+          if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))
+          {
+            g.setColor(Color.green.darker().darker());
+            drawLine(g, xstart, ystart, xend, yend);
+          }
+          else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))
+          {
+            g.setColor(Color.green.darker());
+            drawLine(g, xstart, ystart, xend, yend);
+          }
+          else
+          {
+            g.setColor(Color.green);
+            drawLine(g, xstart, ystart, xend, yend);
+          }
+        }
+        else if (!depthcue && !bymolecule)
+        {
+          g.setColor(tmpBond.startCol);
+          drawLine(g, xstart, ystart, xmid, ymid);
+          g.setColor(tmpBond.endCol);
+          drawLine(g, xmid, ymid, xend, yend);
+        }
+        else
+        {
+          drawLine(g, xstart, ystart, xend, yend);
+        }
+
+        if (highlightBond1 != null && highlightBond1 == tmpBond)
+        {
+          g.setColor(tmpBond.endCol.brighter().brighter().brighter().brighter());
+          drawLine(g, xmid, ymid, xend, yend);
+        }
+
+        if (highlightBond2 != null && highlightBond2 == tmpBond)
+        {
+          g.setColor(tmpBond.startCol.brighter().brighter().brighter().brighter());
+          drawLine(g, xstart, ystart, xmid, ymid);
+        }
+
+      }
+
+
+    }
+
+    public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {
+        if (!wire) {
+            if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {
+                g.drawLine(x1, y1, x2, y2);
+                g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);
+                g.drawLine(x1, y1 - 1, x2, y2 - 1);
+            } else {
+                g.setColor(g.getColor().brighter());
+                g.drawLine(x1, y1, x2, y2);
+                g.drawLine(x1 + 1, y1, x2 + 1, y2);
+                g.drawLine(x1 - 1, y1, x2 - 1, y2);
+            }
+        } else {
+            g.drawLine(x1, y1, x2, y2);
+        }
+    }
+
+    public Dimension minimumsize() {
+        return prefsize;
+    }
+
+    public Dimension preferredsize() {
+        return prefsize;
+    }
+
+    public void keyPressed(KeyEvent evt)
+    {
+      if (evt.getKeyCode() == KeyEvent.VK_UP)
+      {
+        scale = (float) (scale * 1.1);
+        redrawneeded = true;
+        repaint();
+      }
+      else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
+      {
+        scale = (float) (scale * 0.9);
+        redrawneeded = true;
+        repaint();
+      }
+    }
+
+    public void mousePressed(MouseEvent e)
+    {
+        pdbAction = true;
+        Atom fatom = findAtom(e.getX(), e.getY());
+        if(fatom!=null)
+        {
+          fatom.isSelected = !fatom.isSelected;
+
+          redrawneeded = true;
+          repaint();
+          if (foundchain != -1)
+          {
+            PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);
+            if (chain == mainchain)
+            {
+              if (fatom.alignmentMapping != -1)
+              {
+                if (highlightRes == null)
+                  highlightRes = new Vector();
+
+                if (highlightRes.contains(fatom.alignmentMapping+""))
+                  highlightRes.remove(fatom.alignmentMapping + "");
+                else
+                  highlightRes.add(fatom.alignmentMapping + "");
+              }
+            }
+          }
+
+        }
+        mx = e.getX();
+        my = e.getY();
+        omx = mx;
+        omy = my;
+        dragging = false;
+    }
+
+    public void mouseMoved(MouseEvent e)
+    {
+      pdbAction = true;
+      if(highlightBond1!=null)
+      {
+        highlightBond1.at2.isSelected = false;
+        highlightBond2.at1.isSelected = false;
+        highlightBond1 = null;
+        highlightBond2 = null;
+      }
+
+        Atom fatom = findAtom(e.getX(), e.getY());
+
+        PDBChain chain = null;
+        if(foundchain!=-1)
+        {
+          chain = (PDBChain) pdb.chains.elementAt(foundchain);
+          if(chain == mainchain)
+          {
+            highlightSeqcanvas( fatom.alignmentMapping );
+          }
+        }
+
+        if (fatom != null)
+        {
+            this.setToolTipText(chain.id+":"+ fatom.resNumber+" "+ fatom.resName);
+        } else
+        {
+            highlightSeqcanvas( -1);
+            this.setToolTipText(null);
+        }
+    }
+
+
+    void highlightSeqcanvas(int pos)
+    {
+      SearchResults searchResults = new SearchResults();
+      if(highlightRes!=null)
+      {
+        for (int i = 0; i < highlightRes.size(); i++)
+        {
+          int a = Integer.parseInt(highlightRes.elementAt(
+              i).toString())+1;
+
+          searchResults.addResult(sequence, a, a);
+        }
+      }
+
+      if(pos!=-1)
+      {
+        searchResults.addResult(sequence, pos+1, pos+1);
+      }
+
+      seqcanvas.highlightSearchResults(searchResults);
+    }
+
+
+    public void mouseClicked(MouseEvent e)  { }
+
+    public void mouseEntered(MouseEvent e) {  }
+
+    public void mouseExited(MouseEvent e) { }
+
+    public void mouseDragged(MouseEvent evt)
+    {
+        int x = evt.getX();
+        int y = evt.getY();
+        mx = x;
+        my = y;
+
+
+        MCMatrix objmat = new MCMatrix(3, 3);
+        objmat.setIdentity();
+
+        if ((evt.getModifiers() & Event.META_MASK) != 0) {
+            objmat.rotatez((float) ((mx - omx)));
+        } else {
+            objmat.rotatex((float) ((my - omy)));
+            objmat.rotatey((float) ((omx - mx)));
+        }
+
+        //Alter the bonds
+        for (int ii = 0; ii < pdb.chains.size(); ii++) {
+            Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+            for (int i = 0; i < bonds.size(); i++) {
+                Bond tmpBond = (Bond) bonds.elementAt(i);
+
+                //Translate the bond so the centre is 0,0,0
+                tmpBond.translate(-centre[0], -centre[1], -centre[2]);
+
+                //Now apply the rotation matrix
+                tmpBond.start = objmat.vectorMultiply(tmpBond.start);
+                tmpBond.end = objmat.vectorMultiply(tmpBond.end);
+
+                //Now translate back again
+                tmpBond.translate(centre[0], centre[1], centre[2]);
+            }
+        }
+
+        objmat = null;
+
+        omx = mx;
+        omy = my;
+
+        dragging = true;
+
+        redrawneeded = true;
+
+        repaint();
+    }
+
+    public void mouseReleased(MouseEvent evt)
+    {
+        dragging = false;
+        return;
+    }
+
+    void drawLabels(Graphics g) {
+
+        for (int ii = 0; ii < pdb.chains.size(); ii++)
+        {
+            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+
+            if (chain.isVisible)
+            {
+              Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+              for (int i = 0; i < bonds.size(); i++)
+              {
+                  Bond tmpBond = (Bond) bonds.elementAt(i);
+
+                  if (tmpBond.at1.isSelected)
+                  {
+                      labelAtom(g, tmpBond, 1);
+                  }
+
+                  if (tmpBond.at2.isSelected)
+                  {
+
+                      labelAtom(g, tmpBond, 2);
+                  }
+                }
+            }
+        }
+    }
+
+    public void labelAtom(Graphics g, Bond b, int n) {
+        g.setFont(font);
+        g.setColor(Color.red);
+        if (n == 1)
+        {
+            int xstart = (int) (((b.start[0] - centre[0]) * scale) +
+                (getWidth() / 2));
+            int ystart = (int) (((b.start[1] - centre[1]) * scale) +
+                (getHeight() / 2));
+
+            g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);
+        }
+
+        if (n == 2) {
+            int xstart = (int) (((b.end[0] - centre[0]) * scale) +
+                (getWidth() / 2));
+            int ystart = (int) (((b.end[1] - centre[1]) * scale) +
+                (getHeight() / 2));
+
+            g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);
+        }
+    }
+
+    int foundchain = -1;
+    public Atom findAtom(int x, int y) {
+        Atom fatom = null;
+
+        foundchain = -1;
+
+        for (int ii = 0; ii < pdb.chains.size(); ii++)
+        {
+            PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+            int truex;
+            Bond tmpBond=null;
+
+            if (chain.isVisible)
+            {
+                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+
+                for (int i = 0; i < bonds.size(); i++)
+                {
+                    tmpBond = (Bond) bonds.elementAt(i);
+
+                    truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +
+                        (getWidth() / 2));
+
+                    if (Math.abs(truex - x) <= 2)
+                    {
+                        int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +
+                            (getHeight() / 2));
+
+                        if (Math.abs(truey - y) <= 2)
+                        {
+                            fatom = tmpBond.at1;
+                            foundchain = ii;
+                            break;
+                        }
+                    }
+                }
+
+                // Still here? Maybe its the last bond
+
+                truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +
+                               (getWidth() / 2));
+
+                if (Math.abs(truex - x) <= 2)
+                {
+                  int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +
+                                     (getHeight() / 2));
+
+                  if (Math.abs(truey - y) <= 2)
+                  {
+                    fatom = tmpBond.at2;
+                    foundchain = ii;
+                    break;
+                  }
+                }
+
+            }
+
+            if (fatom != null) //)&& chain.ds != null)
+             {
+                chain = (PDBChain) pdb.chains.elementAt(foundchain);
+            }
+        }
+
+        return fatom;
+    }
+
+   Bond highlightBond1, highlightBond2;
+   public void highlightRes(int ii)
+  {
+    if( !seqColoursReady )
+      return;
+
+    if (highlightRes != null
+        && highlightRes.contains((ii-1) + ""))
+    {
+      return;
+    }
+
+    int index = -1;
+    Bond tmpBond;
+    for(index=0; index<mainchain.bonds.size(); index++)
+    {
+      tmpBond = (Bond) mainchain.bonds.elementAt(index);
+      if (tmpBond.at1.alignmentMapping == ii - 1)
+      {
+        if (highlightBond1 != null)
+          highlightBond1.at2.isSelected = false;
+
+        if (highlightBond2 != null)
+          highlightBond2.at1.isSelected = false;
+
+        highlightBond1 = null;
+        highlightBond2 = null;
+
+        if (index > 0)
+        {
+          highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);
+          highlightBond1.at2.isSelected = true;
+        }
+
+        if (index != mainchain.bonds.size())
+        {
+          highlightBond2 = (Bond) mainchain.bonds.elementAt(index);
+          highlightBond2.at1.isSelected = true;
+        }
+
+        break;
+      }
+    }
+
+    redrawneeded = true;
+    repaint();
+  }
+
+    public void setAllchainsVisible(boolean b)
+    {
+      for (int ii = 0; ii < pdb.chains.size(); ii++)
+      {
+        PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+        chain.isVisible = b;
+      }
+      mainchain.isVisible = true;
+      findCentre();
+      setupBonds();
+    }
+}
index fa4bbf9..36681a1 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.schemes.ResidueProperties;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-import jalview.analysis.AlignSeq;\r
-\r
-\r
-public class PDBChain {\r
-    public String id;\r
-    public Vector bonds = new Vector();\r
-    public Vector atoms = new Vector();\r
-    public Vector residues = new Vector();\r
-    public int offset;\r
-    public Sequence sequence;\r
-    public boolean isVisible = true;\r
-    public int pdbstart = 0;\r
-    public int pdbend = 0;\r
-    public int seqstart = 0;\r
-    public int seqend = 0;\r
-\r
-    public PDBChain(String id) {\r
-        this.id = id;\r
-    }\r
-\r
-    public String print() {\r
-        String tmp = "";\r
-\r
-        for (int i = 0; i < bonds.size(); i++) {\r
-            tmp = tmp + ((Bond) bonds.elementAt(i)).at1.resName + " " +\r
-                ((Bond) bonds.elementAt(i)).at1.resNumber + " " + offset +\r
-                "\n";\r
-        }\r
-\r
-        return tmp;\r
-    }\r
-\r
-    void makeExactMapping(AlignSeq as, Sequence s1)\r
-    {\r
-        int pdbpos =   as.getSeq2Start()-2;\r
-        int alignpos = s1.getStart() + as.getSeq1Start()-3;\r
-\r
-        for(int i=0; i<as.astr1.length(); i++)\r
-        {\r
-            if (as.astr1.charAt(i) != '-')\r
-            {\r
-              alignpos++;\r
-            }\r
-\r
-            if (as.astr2.charAt(i) != '-')\r
-            {\r
-              pdbpos++;\r
-            }\r
-\r
-            if (as.astr1.charAt(i) == as.astr2.charAt(i))\r
-            {\r
-                Residue res = (Residue) residues.elementAt(pdbpos);\r
-                Enumeration en = res.atoms.elements();\r
-                while (en.hasMoreElements())\r
-                {\r
-                  Atom atom = (Atom) en.nextElement();\r
-                  atom.alignmentMapping = alignpos;\r
-                }\r
-            }\r
-        }\r
-\r
-    }\r
-\r
-\r
-    public void makeCaBondList()\r
-    {\r
-        for (int i = 0; i < (residues.size() - 1); i++)\r
-        {\r
-            Residue tmpres = (Residue) residues.elementAt(i);\r
-            Residue tmpres2 = (Residue) residues.elementAt(i + 1);\r
-            Atom at1 = tmpres.findAtom("CA");\r
-            Atom at2 = tmpres2.findAtom("CA");\r
-\r
-            if ((at1 != null) && (at2 != null))\r
-            {\r
-                if (at1.chain.equals(at2.chain))\r
-                {\r
-                    makeBond(at1, at2);\r
-                }\r
-            }\r
-            else\r
-              System.out.println("not found "+i);\r
-        }\r
-    }\r
-\r
-    public void makeBond(Atom at1, Atom at2) {\r
-        float[] start = new float[3];\r
-        float[] end = new float[3];\r
-\r
-        start[0] = at1.x;\r
-        start[1] = at1.y;\r
-        start[2] = at1.z;\r
-\r
-        end[0] = at2.x;\r
-        end[1] = at2.y;\r
-        end[2] = at2.z;\r
-\r
-        bonds.addElement(new Bond(start, end, at1, at2));\r
-    }\r
-\r
-    public void makeResidueList() {\r
-        int count = 0;\r
-        StringBuffer seq = new StringBuffer();\r
-\r
-        int i, iSize = atoms.size()-1;\r
-        for (i = 0; i < iSize; i++)\r
-        {\r
-            Atom tmp = (Atom) atoms.elementAt(i);\r
-            int resNumber = tmp.resNumber;\r
-            int res = resNumber;\r
-\r
-            if (i == 0) {\r
-                offset = resNumber;\r
-            }\r
-\r
-            Vector resAtoms = new Vector();\r
-\r
-            resAtoms.addElement((Atom) atoms.elementAt(i));\r
-            i++;\r
-            resNumber = ((Atom) atoms.elementAt(i)).resNumber;\r
-\r
-            //Add atoms to a vector while the residue number\r
-            //remains the same\r
-            while ((resNumber == res) && (i < atoms.size())) {\r
-                resAtoms.addElement((Atom) atoms.elementAt(i));\r
-                i++;\r
-\r
-                if (i < atoms.size()) {\r
-                    resNumber = ((Atom) atoms.elementAt(i)).resNumber;\r
-                } else {\r
-                    resNumber++;\r
-                }\r
-            }\r
-\r
-            //We need this to keep in step with the outer for i = loop\r
-            i--;\r
-\r
-            //Make a new Residue object with the new atoms vector\r
-            residues.addElement(new Residue(resAtoms, resNumber - 1, count));\r
-            count++;\r
-\r
-            Residue tmpres = (Residue) residues.lastElement();\r
-            Atom tmpat = (Atom) tmpres.atoms.elementAt(0);\r
-\r
-            // Keep totting up the sequence\r
-            if (ResidueProperties.getAA3Hash().get(tmpat.resName) == null)\r
-            {\r
-                seq.append("X") ;\r
-               //  System.err.println("PDBReader:Null aa3Hash for " +\r
-               //     tmpat.resName);\r
-            } else {\r
-\r
-                seq.append(ResidueProperties.aa[((Integer) ResidueProperties.getAA3Hash()\r
-                                                                                  .get(tmpat.resName)).intValue()]);\r
-            }\r
-        }\r
-\r
-        if(id.length()<1 || id.equals(" "))\r
-           id = "_";\r
-\r
-        sequence = new Sequence(id, seq.toString(), 1, seq.length());\r
-      //  System.out.println("PDB Sequence is :\nSequence = " + seq);\r
-     //   System.out.println("No of residues = " + residues.size());\r
-    }\r
-\r
-    public void setChargeColours() {\r
-        for (int i = 0; i < bonds.size(); i++) {\r
-            try {\r
-                Bond b = (Bond) bonds.elementAt(i);\r
-\r
-                if (b.at1.resName.equalsIgnoreCase("ASP") ||\r
-                        b.at1.resName.equalsIgnoreCase("GLU")) {\r
-                    b.startCol = Color.red;\r
-                } else if (b.at1.resName.equalsIgnoreCase("LYS") ||\r
-                        b.at1.resName.equalsIgnoreCase("ARG")) {\r
-                    b.startCol = Color.blue;\r
-                } else if (b.at1.resName.equalsIgnoreCase("CYS")) {\r
-                    b.startCol = Color.yellow;\r
-                } else {\r
-                    //int atno = ((Integer) ResidueProperties.getAA3Hash().get(b.at1.resName.toUpperCase())).intValue();\r
-                    b.startCol = Color.lightGray;\r
-                }\r
-\r
-                if (b.at2.resName.equalsIgnoreCase("ASP") ||\r
-                        b.at2.resName.equalsIgnoreCase("GLU")) {\r
-                    b.endCol = Color.red;\r
-                } else if (b.at2.resName.equalsIgnoreCase("LYS") ||\r
-                        b.at2.resName.equalsIgnoreCase("ARG")) {\r
-                    b.endCol = Color.blue;\r
-                } else if (b.at2.resName.equalsIgnoreCase("CYS")) {\r
-                    b.endCol = Color.yellow;\r
-                } else {\r
-                    //int atno = ((Integer) ResidueProperties.getAA3Hash().get(b.at2.resName.toUpperCase())).intValue();\r
-                    b.endCol = Color.lightGray;\r
-                }\r
-            } catch (Exception e) {\r
-                Bond b = (Bond) bonds.elementAt(i);\r
-                b.startCol = Color.gray;\r
-                b.endCol = Color.gray;\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-    public void setChainColours(jalview.schemes.ColourSchemeI cs)\r
-    {\r
-        Bond b;\r
-        for (int i = 0; i < bonds.size(); i++) {\r
-            try {\r
-              b = (Bond) bonds.elementAt(i);\r
-\r
-              ( (Bond) bonds.elementAt(i)).startCol = cs.findColour(\r
-                  ResidueProperties.aa[ ( (Integer) ResidueProperties.aa3Hash.\r
-                                         get(b.at1.resName)).intValue()]\r
-                  );\r
-\r
-              b.endCol = cs.findColour(\r
-                  ResidueProperties.aa[ ( (Integer) ResidueProperties.aa3Hash.\r
-                                         get(b.at2.resName)).intValue()]\r
-                  );\r
-\r
-            } catch (Exception e)\r
-            {\r
-                b = (Bond) bonds.elementAt(i);\r
-                b.startCol = Color.gray;\r
-                b.endCol = Color.gray;\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-\r
-    public void setChainColours(Color col)\r
-    {\r
-        for (int i = 0; i < bonds.size(); i++)\r
-        {\r
-            Bond tmp = (Bond) bonds.elementAt(i);\r
-            tmp.startCol = col;\r
-            tmp.endCol = col;\r
-        }\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import jalview.datamodel.*;
+
+import jalview.schemes.ResidueProperties;
+
+import java.awt.*;
+
+import java.util.*;
+import jalview.analysis.AlignSeq;
+
+
+public class PDBChain {
+    public String id;
+    public Vector bonds = new Vector();
+    public Vector atoms = new Vector();
+    public Vector residues = new Vector();
+    public int offset;
+    public Sequence sequence;
+    public boolean isVisible = true;
+    public int pdbstart = 0;
+    public int pdbend = 0;
+    public int seqstart = 0;
+    public int seqend = 0;
+
+    public PDBChain(String id) {
+        this.id = id;
+    }
+
+    public String print() {
+        String tmp = "";
+
+        for (int i = 0; i < bonds.size(); i++) {
+            tmp = tmp + ((Bond) bonds.elementAt(i)).at1.resName + " " +
+                ((Bond) bonds.elementAt(i)).at1.resNumber + " " + offset +
+                "\n";
+        }
+
+        return tmp;
+    }
+
+    void makeExactMapping(AlignSeq as, Sequence s1)
+    {
+        int pdbpos =   as.getSeq2Start()-2;
+        int alignpos = s1.getStart() + as.getSeq1Start()-3;
+
+        for(int i=0; i<as.astr1.length(); i++)
+        {
+            if (as.astr1.charAt(i) != '-')
+            {
+              alignpos++;
+            }
+
+            if (as.astr2.charAt(i) != '-')
+            {
+              pdbpos++;
+            }
+
+            if (as.astr1.charAt(i) == as.astr2.charAt(i))
+            {
+                Residue res = (Residue) residues.elementAt(pdbpos);
+                Enumeration en = res.atoms.elements();
+                while (en.hasMoreElements())
+                {
+                  Atom atom = (Atom) en.nextElement();
+                  atom.alignmentMapping = alignpos;
+                }
+            }
+        }
+
+    }
+
+
+    public void makeCaBondList()
+    {
+        for (int i = 0; i < (residues.size() - 1); i++)
+        {
+            Residue tmpres = (Residue) residues.elementAt(i);
+            Residue tmpres2 = (Residue) residues.elementAt(i + 1);
+            Atom at1 = tmpres.findAtom("CA");
+            Atom at2 = tmpres2.findAtom("CA");
+
+            if ((at1 != null) && (at2 != null))
+            {
+                if (at1.chain.equals(at2.chain))
+                {
+                    makeBond(at1, at2);
+                }
+            }
+            else
+              System.out.println("not found "+i);
+        }
+    }
+
+    public void makeBond(Atom at1, Atom at2) {
+        float[] start = new float[3];
+        float[] end = new float[3];
+
+        start[0] = at1.x;
+        start[1] = at1.y;
+        start[2] = at1.z;
+
+        end[0] = at2.x;
+        end[1] = at2.y;
+        end[2] = at2.z;
+
+        bonds.addElement(new Bond(start, end, at1, at2));
+    }
+
+    public void makeResidueList() {
+        int count = 0;
+        StringBuffer seq = new StringBuffer();
+
+        int i, iSize = atoms.size()-1;
+        for (i = 0; i < iSize; i++)
+        {
+            Atom tmp = (Atom) atoms.elementAt(i);
+            int resNumber = tmp.resNumber;
+            int res = resNumber;
+
+            if (i == 0) {
+                offset = resNumber;
+            }
+
+            Vector resAtoms = new Vector();
+
+            resAtoms.addElement((Atom) atoms.elementAt(i));
+            i++;
+            resNumber = ((Atom) atoms.elementAt(i)).resNumber;
+
+            //Add atoms to a vector while the residue number
+            //remains the same
+            while ((resNumber == res) && (i < atoms.size())) {
+                resAtoms.addElement((Atom) atoms.elementAt(i));
+                i++;
+
+                if (i < atoms.size()) {
+                    resNumber = ((Atom) atoms.elementAt(i)).resNumber;
+                } else {
+                    resNumber++;
+                }
+            }
+
+            //We need this to keep in step with the outer for i = loop
+            i--;
+
+            //Make a new Residue object with the new atoms vector
+            residues.addElement(new Residue(resAtoms, resNumber - 1, count));
+            count++;
+
+            Residue tmpres = (Residue) residues.lastElement();
+            Atom tmpat = (Atom) tmpres.atoms.elementAt(0);
+
+            // Keep totting up the sequence
+            if (ResidueProperties.getAA3Hash().get(tmpat.resName) == null)
+            {
+                seq.append("X") ;
+               //  System.err.println("PDBReader:Null aa3Hash for " +
+               //     tmpat.resName);
+            } else {
+
+                seq.append(ResidueProperties.aa[((Integer) ResidueProperties.getAA3Hash()
+                                                                                  .get(tmpat.resName)).intValue()]);
+            }
+        }
+
+        if(id.length()<1 || id.equals(" "))
+           id = "_";
+
+        sequence = new Sequence(id, seq.toString(), 1, seq.length());
+      //  System.out.println("PDB Sequence is :\nSequence = " + seq);
+     //   System.out.println("No of residues = " + residues.size());
+    }
+
+    public void setChargeColours() {
+        for (int i = 0; i < bonds.size(); i++) {
+            try {
+                Bond b = (Bond) bonds.elementAt(i);
+
+                if (b.at1.resName.equalsIgnoreCase("ASP") ||
+                        b.at1.resName.equalsIgnoreCase("GLU")) {
+                    b.startCol = Color.red;
+                } else if (b.at1.resName.equalsIgnoreCase("LYS") ||
+                        b.at1.resName.equalsIgnoreCase("ARG")) {
+                    b.startCol = Color.blue;
+                } else if (b.at1.resName.equalsIgnoreCase("CYS")) {
+                    b.startCol = Color.yellow;
+                } else {
+                    //int atno = ((Integer) ResidueProperties.getAA3Hash().get(b.at1.resName.toUpperCase())).intValue();
+                    b.startCol = Color.lightGray;
+                }
+
+                if (b.at2.resName.equalsIgnoreCase("ASP") ||
+                        b.at2.resName.equalsIgnoreCase("GLU")) {
+                    b.endCol = Color.red;
+                } else if (b.at2.resName.equalsIgnoreCase("LYS") ||
+                        b.at2.resName.equalsIgnoreCase("ARG")) {
+                    b.endCol = Color.blue;
+                } else if (b.at2.resName.equalsIgnoreCase("CYS")) {
+                    b.endCol = Color.yellow;
+                } else {
+                    //int atno = ((Integer) ResidueProperties.getAA3Hash().get(b.at2.resName.toUpperCase())).intValue();
+                    b.endCol = Color.lightGray;
+                }
+            } catch (Exception e) {
+                Bond b = (Bond) bonds.elementAt(i);
+                b.startCol = Color.gray;
+                b.endCol = Color.gray;
+            }
+        }
+    }
+
+
+    public void setChainColours(jalview.schemes.ColourSchemeI cs)
+    {
+        Bond b;
+        for (int i = 0; i < bonds.size(); i++) {
+            try {
+              b = (Bond) bonds.elementAt(i);
+
+              ( (Bond) bonds.elementAt(i)).startCol = cs.findColour(
+                  ResidueProperties.aa[ ( (Integer) ResidueProperties.aa3Hash.
+                                         get(b.at1.resName)).intValue()]
+                  );
+
+              b.endCol = cs.findColour(
+                  ResidueProperties.aa[ ( (Integer) ResidueProperties.aa3Hash.
+                                         get(b.at2.resName)).intValue()]
+                  );
+
+            } catch (Exception e)
+            {
+                b = (Bond) bonds.elementAt(i);
+                b.startCol = Color.gray;
+                b.endCol = Color.gray;
+            }
+        }
+    }
+
+
+
+    public void setChainColours(Color col)
+    {
+        for (int i = 0; i < bonds.size(); i++)
+        {
+            Bond tmp = (Bond) bonds.elementAt(i);
+            tmp.startCol = col;
+            tmp.endCol = col;
+        }
+    }
+}
index f0b37df..e7924c0 100755 (executable)
@@ -1,6 +1,6 @@
 /*
  * Jalview - A Sequence Alignment Editor and Viewer
 /*
  * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,19 +26,22 @@ import jalview.gui.*;
 import jalview.io.EBIFetchClient;
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
 import jalview.io.EBIFetchClient;
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
+import java.io.*;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
 
 public class PDBViewer extends JInternalFrame implements Runnable
 {
   PDBEntry pdb;
   Sequence sequence;
   PDBCanvas pdbcanvas;
 
 public class PDBViewer extends JInternalFrame implements Runnable
 {
   PDBEntry pdb;
   Sequence sequence;
   PDBCanvas pdbcanvas;
+  String tmpPDBFile;
 
 
   public PDBViewer(PDBEntry entry,
                    Sequence seq,
                    SeqCanvas seqcanvas)
   {
 
 
   public PDBViewer(PDBEntry entry,
                    Sequence seq,
                    SeqCanvas seqcanvas)
   {
-    /*Uncomment this to modify in Jbuilder
     try
     {
       jbInit();
     try
     {
       jbInit();
@@ -46,17 +49,35 @@ public class PDBViewer extends JInternalFrame implements Runnable
     catch (Exception ex)
     {
       ex.printStackTrace();
     catch (Exception ex)
     {
       ex.printStackTrace();
-    }*/
+    }
+
 
     if (entry==null)
       return;
     pdb = entry;
     sequence = seq;
 
     if (entry==null)
       return;
     pdb = entry;
     sequence = seq;
+    pdbcanvas = new PDBCanvas(seqcanvas, sequence);
+
+    if(pdb.getFile()!=null)
+    {
+        try{
+          tmpPDBFile = pdb.getFile();
+          PDBfile pdbfile = new PDBfile(tmpPDBFile,
+                                        jalview.io.AppletFormatAdapter.FILE);
+          pdbcanvas.setPDBFile(pdbfile);
+
+        }catch(java.io.IOException ex)
+        {
+          ex.printStackTrace();
+        }
+    }
+    else
+    {
+      Thread worker = new Thread(this);
+      worker.start();
+    }
 
 
-    Thread worker = new Thread(this);
-    worker.start();
 
 
-    pdbcanvas = new PDBCanvas(seqcanvas, seq);
 
     setContentPane(pdbcanvas);
     StringBuffer title = new StringBuffer(sequence.getName() + ":" + pdb.getId());
 
     setContentPane(pdbcanvas);
     StringBuffer title = new StringBuffer(sequence.getName() + ":" + pdb.getId());
@@ -80,24 +101,18 @@ public class PDBViewer extends JInternalFrame implements Runnable
   {
     try
     {
   {
     try
     {
-      EBIFetchClient ebi = new EBIFetchClient();
-      String query = "pdb:" + pdb.getId();
-      String[] result = ebi.fetchData(query, "default","raw");
-      if (result!=null) {
-        PDBfile pdbfile = new PDBfile(result);
-        pdbcanvas.setPDBFile(pdbfile);
-      } else {
-        throw new Exception("Empty result for WSDbFetch Query: "+query);
-      }
-
-      try
-      {
-        jbInit();
-      }
-      catch (Exception ex)
-      {
-        ex.printStackTrace();
-      }
+        EBIFetchClient ebi = new EBIFetchClient();
+        String query = "pdb:" + pdb.getId();
+        tmpPDBFile = ebi.fetchDataAsFile(query, "default", "raw").getAbsolutePath();
+        if (tmpPDBFile != null)
+        {
+          PDBfile pdbfile = new PDBfile(tmpPDBFile, jalview.io.AppletFormatAdapter.FILE);
+          pdbcanvas.setPDBFile(pdbfile);
+        }
+        else
+        {
+          throw new Exception("Empty result for WSDbFetch Query: " + query);
+        }
     }
     catch (Exception ex)
     {
     }
     catch (Exception ex)
     {
@@ -272,11 +287,28 @@ public class PDBViewer extends JInternalFrame implements Runnable
       }
     });
     viewMenu.setText("View");
       }
     });
     viewMenu.setText("View");
+    background.setText("Background Colour...");
+    background.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        background_actionPerformed(e);
+      }
+    });
+    savePDB.setText("PDB File");
+    savePDB.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        savePDB_actionPerformed(e);
+      }
+    });
     jMenuBar1.add(fileMenu);
     jMenuBar1.add(coloursMenu);
     jMenuBar1.add(viewMenu);
     fileMenu.add(saveMenu);
     fileMenu.add(mapping);
     jMenuBar1.add(fileMenu);
     jMenuBar1.add(coloursMenu);
     jMenuBar1.add(viewMenu);
     fileMenu.add(saveMenu);
     fileMenu.add(mapping);
+    saveMenu.add(savePDB);
     saveMenu.add(png);
     saveMenu.add(eps);
     coloursMenu.add(seqButton);
     saveMenu.add(png);
     saveMenu.add(eps);
     coloursMenu.add(seqButton);
@@ -290,6 +322,7 @@ public class PDBViewer extends JInternalFrame implements Runnable
     coloursMenu.add(turn);
     coloursMenu.add(buried);
     coloursMenu.add(user);
     coloursMenu.add(turn);
     coloursMenu.add(buried);
     coloursMenu.add(user);
+    coloursMenu.add(background);
     ButtonGroup bg = new ButtonGroup();
     bg.add(seqButton);
     bg.add(chain);
     ButtonGroup bg = new ButtonGroup();
     bg.add(seqButton);
     bg.add(chain);
@@ -384,6 +417,8 @@ public class PDBViewer extends JInternalFrame implements Runnable
   JRadioButtonMenuItem strand = new JRadioButtonMenuItem();
   JRadioButtonMenuItem helix = new JRadioButtonMenuItem();
   JMenu viewMenu = new JMenu();
   JRadioButtonMenuItem strand = new JRadioButtonMenuItem();
   JRadioButtonMenuItem helix = new JRadioButtonMenuItem();
   JMenu viewMenu = new JMenu();
+  JMenuItem background = new JMenuItem();
+  JMenuItem savePDB = new JMenuItem();
 
   /**
    * DOCUMENT ME!
 
   /**
    * DOCUMENT ME!
@@ -572,4 +607,54 @@ public class PDBViewer extends JInternalFrame implements Runnable
       pdbcanvas.repaint();
     }
   }
       pdbcanvas.repaint();
     }
   }
+
+  public void background_actionPerformed(ActionEvent e)
+  {
+      java.awt.Color col = JColorChooser.showDialog(this, "Select Background Colour",
+                pdbcanvas.backgroundColour);
+
+      if(col!=null)
+       {
+         pdbcanvas.backgroundColour = col;
+         pdbcanvas.redrawneeded = true;
+         pdbcanvas.repaint();
+       }
+  }
+
+  public void savePDB_actionPerformed(ActionEvent e)
+  {
+    JalviewFileChooser chooser = new JalviewFileChooser(
+        jalview.bin.Cache.getProperty(
+            "LAST_DIRECTORY"));
+
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle("Save PDB File");
+    chooser.setToolTipText("Save");
+
+    int value = chooser.showSaveDialog(this);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+        try
+        {
+          BufferedReader in = new BufferedReader(new FileReader(tmpPDBFile));
+          File outFile = chooser.getSelectedFile();
+
+          PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
+          String data;
+          while ( (data = in.readLine()) != null)
+          {
+            if (
+                !( data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1)
+                )
+              out.println(data);
+          }
+          out.close();
+        }
+        catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+      }
+  }
 }
 }
index 63728ae..5824575 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import java.io.*;\r
-\r
-import java.net.*;\r
-\r
-import java.util.*;\r
-import java.awt.Color;\r
-import jalview.io.AppletFormatAdapter;\r
-\r
-\r
-public class PDBfile extends jalview.io.FileParse {\r
-    public Vector chains = new Vector();\r
-    Vector lineArray = new Vector();\r
-    public String id;\r
-\r
-    public PDBfile(String[] lines) {\r
-        for (int i = 0; i < lines.length; i++)\r
-            lineArray.addElement(lines[i]);\r
-\r
-        parse();\r
-    }\r
-\r
-    public PDBfile(String inFile, String inType) throws IOException {\r
-        super(inFile, inType);\r
-\r
-        String line;\r
-        this.lineArray = new Vector();\r
-\r
-        BufferedReader dataIn;\r
-\r
-\r
-        if (inType.equals(AppletFormatAdapter.FILE)) {\r
-            dataIn = new BufferedReader(new FileReader(inFile));\r
-        }\r
-        else if(inType.equals(AppletFormatAdapter.PASTE))\r
-        {\r
-            dataIn = new BufferedReader(new StringReader(inFile));\r
-        }\r
-        else if (inType.equalsIgnoreCase(AppletFormatAdapter.CLASSLOADER))\r
-        {\r
-          java.io.InputStream is = getClass().getResourceAsStream("/" +\r
-              inFile);\r
-\r
-          dataIn = new BufferedReader(new java.io.InputStreamReader(is));\r
-        }\r
-        else\r
-        {\r
-            URL url = new URL(inFile);\r
-            dataIn = new BufferedReader(new InputStreamReader(url.openStream()));\r
-        }\r
-\r
-        while ((line = dataIn.readLine()) != null) {\r
-            lineArray.addElement(line);\r
-        }\r
-\r
-\r
-        parse();\r
-        lineArray = null;\r
-    }\r
-\r
-    public void parse()\r
-    {\r
-        PDBChain tmpchain;\r
-        String line;\r
-        boolean modelFlag = false;\r
-        boolean terFlag = false;\r
-\r
-\r
-        for (int i = 0; i < lineArray.size(); i++)\r
-        {\r
-\r
-           line = lineArray.elementAt(i).toString();\r
-\r
-\r
-           if (line.indexOf("HEADER") == 0)\r
-           {\r
-             id = line.substring(62, 67).trim();\r
-             continue;\r
-           }\r
-\r
-           if(line.indexOf("MODEL")==0)\r
-             modelFlag = true;\r
-\r
-           if(line.indexOf("TER")==0)\r
-             terFlag = true;\r
-\r
-           if(modelFlag && line.indexOf("ENDMDL")==0)\r
-             break;\r
-\r
-           if (    line.indexOf("ATOM")==0\r
-               || (line.indexOf("HETATM")==0 && !terFlag)\r
-             )\r
-            {\r
-              terFlag = false;\r
-\r
-\r
-              //Jalview is only interested in CA bonds????\r
-              if (!line.substring(12, 15).trim().equals("CA"))\r
-              {\r
-                continue;\r
-              }\r
-\r
-              Atom tmpatom = new Atom(line);\r
-\r
-              tmpchain = findChain(tmpatom.chain);\r
-              if (tmpchain != null)\r
-              {\r
-                tmpchain.atoms.addElement(tmpatom);\r
-              }\r
-              else\r
-              {\r
-                tmpchain = new PDBChain(tmpatom.chain);\r
-                chains.addElement(tmpchain);\r
-                tmpchain.atoms.addElement(tmpatom);\r
-              }\r
-\r
-          }\r
-        }\r
-\r
-       makeResidueList();\r
-       makeCaBondList();\r
-    }\r
-\r
-    public void makeResidueList() {\r
-        for (int i = 0; i < chains.size(); i++) {\r
-            ((PDBChain) chains.elementAt(i)).makeResidueList();\r
-        }\r
-    }\r
-\r
-    public void makeCaBondList() {\r
-        for (int i = 0; i < chains.size(); i++) {\r
-            ((PDBChain) chains.elementAt(i)).makeCaBondList();\r
-        }\r
-    }\r
-\r
-    public PDBChain findChain(String id) {\r
-        for (int i = 0; i < chains.size(); i++) {\r
-            if (((PDBChain) chains.elementAt(i)).id.equals(id)) {\r
-                return (PDBChain) chains.elementAt(i);\r
-            }\r
-        }\r
-\r
-        return null;\r
-    }\r
-\r
-    public void setChargeColours() {\r
-        for (int i = 0; i < chains.size(); i++) {\r
-            ((PDBChain) chains.elementAt(i)).setChargeColours();\r
-        }\r
-    }\r
-\r
-    public void setColours(jalview.schemes.ColourSchemeI cs) {\r
-        for (int i = 0; i < chains.size(); i++) {\r
-            ((PDBChain) chains.elementAt(i)).setChainColours(cs);\r
-        }\r
-    }\r
-\r
-    public void setChainColours()\r
-    {\r
-       for (int i = 0; i < chains.size(); i++)\r
-       {\r
-            ((PDBChain) chains.elementAt(i)).setChainColours(\r
-                     Color.getHSBColor(1.0f / (float)i, .4f, 1.0f)\r
-                );\r
-        }\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import jalview.datamodel.*;
+
+import java.io.*;
+
+import java.util.*;
+import java.awt.Color;
+
+
+public class PDBfile extends jalview.io.AlignFile {
+    public Vector chains;
+    public String id;
+
+    public PDBfile(String inFile, String inType) throws IOException
+    {
+        super(inFile, inType);
+    }
+
+    public String print()
+    {
+      return null;
+    }
+
+    public void parse() throws IOException
+    {
+        chains = new Vector();
+
+        PDBChain tmpchain;
+        String line;
+        boolean modelFlag = false;
+        boolean terFlag = false;
+
+
+        int index = 0;
+        while((line = nextLine())!=null)
+        {
+           if (line.indexOf("HEADER") == 0)
+           {
+             id = line.substring(62, 67).trim();
+             continue;
+           }
+
+           if(line.indexOf("MODEL")==0)
+             modelFlag = true;
+
+           if(line.indexOf("TER")==0)
+             terFlag = true;
+
+           if(modelFlag && line.indexOf("ENDMDL")==0)
+             break;
+
+           if (    line.indexOf("ATOM")==0
+               || (line.indexOf("HETATM")==0 && !terFlag)
+             )
+            {
+              terFlag = false;
+
+
+              //Jalview is only interested in CA bonds????
+              if (!line.substring(12, 15).trim().equals("CA"))
+              {
+                continue;
+              }
+
+              Atom tmpatom = new Atom(line);
+              tmpchain = findChain(tmpatom.chain);
+              if (tmpchain != null)
+              {
+                tmpchain.atoms.addElement(tmpatom);
+              }
+              else
+              {
+                tmpchain = new PDBChain(tmpatom.chain);
+                chains.addElement(tmpchain);
+                tmpchain.atoms.addElement(tmpatom);
+              }
+          }
+          index ++;
+        }
+
+       makeResidueList();
+       makeCaBondList();
+
+       if(id==null)
+       {
+         id = inFile.getName();
+       }
+       for (int i = 0; i < chains.size(); i++)
+       {
+         SequenceI seq = ( (PDBChain) chains.elementAt(i)).
+             sequence;
+         seq.setName(id + "|" + seq.getName());
+         Sequence dataset = new Sequence(seq.
+             getName(),
+             seq.getSequence().toString(), seq.getStart(), seq.getEnd());
+
+         PDBEntry entry = new PDBEntry();
+         entry.setId(id);
+         if(inFile!=null)
+           entry.setFile(inFile.getAbsolutePath());
+
+         seq.setDatasetSequence(dataset);
+         dataset.addPDBId(entry);
+
+         getSeqs().addElement(seq);
+       }
+    }
+
+    public void makeResidueList() {
+        for (int i = 0; i < chains.size(); i++) {
+            ((PDBChain) chains.elementAt(i)).makeResidueList();
+        }
+    }
+
+    public void makeCaBondList() {
+        for (int i = 0; i < chains.size(); i++) {
+            ((PDBChain) chains.elementAt(i)).makeCaBondList();
+        }
+    }
+
+    public PDBChain findChain(String id) {
+        for (int i = 0; i < chains.size(); i++) {
+            if (((PDBChain) chains.elementAt(i)).id.equals(id)) {
+                return (PDBChain) chains.elementAt(i);
+            }
+        }
+
+        return null;
+    }
+
+    public void setChargeColours() {
+        for (int i = 0; i < chains.size(); i++) {
+            ((PDBChain) chains.elementAt(i)).setChargeColours();
+        }
+    }
+
+    public void setColours(jalview.schemes.ColourSchemeI cs) {
+        for (int i = 0; i < chains.size(); i++) {
+            ((PDBChain) chains.elementAt(i)).setChainColours(cs);
+        }
+    }
+
+    public void setChainColours()
+    {
+       for (int i = 0; i < chains.size(); i++)
+       {
+            ((PDBChain) chains.elementAt(i)).setChainColours(
+                     Color.getHSBColor(1.0f / (float)i, .4f, 1.0f)
+                );
+        }
+    }
+}
index 0f24137..39e7112 100755 (executable)
@@ -1,48 +1,48 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import java.util.*;\r
-\r
-\r
-public class Residue {\r
-    Vector atoms = new Vector();\r
-    int number;\r
-    int count;\r
-    int seqnumber;\r
-\r
-    public Residue(Vector atoms, int number, int count) {\r
-        this.atoms = atoms;\r
-        this.number = number;\r
-        this.count = count;\r
-    }\r
-\r
-    public Atom findAtom(String name)\r
-    {\r
-        for (int i = 0; i < atoms.size(); i++)\r
-        {\r
-            if (((Atom) atoms.elementAt(i)).name.equals(name))\r
-            {\r
-                return (Atom) atoms.elementAt(i);\r
-            }\r
-        }\r
-\r
-        return null;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import java.util.*;
+
+
+public class Residue {
+    Vector atoms = new Vector();
+    int number;
+    int count;
+    int seqnumber;
+
+    public Residue(Vector atoms, int number, int count) {
+        this.atoms = atoms;
+        this.number = number;
+        this.count = count;
+    }
+
+    public Atom findAtom(String name)
+    {
+        for (int i = 0; i < atoms.size(); i++)
+        {
+            if (((Atom) atoms.elementAt(i)).name.equals(name))
+            {
+                return (Atom) atoms.elementAt(i);
+            }
+        }
+
+        return null;
+    }
+}
index c54a3ff..383958d 100755 (executable)
@@ -1,63 +1,63 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package MCview;\r
-\r
-import java.util.*;\r
-\r
-\r
-public class Zsort {\r
-    public void Zsort(Vector bonds) {\r
-        sort(bonds, 0, bonds.size() - 1);\r
-    }\r
-\r
-    public void sort(Vector bonds, int p, int r) {\r
-        int q;\r
-\r
-        if (p < r) {\r
-            q = partition(bonds, p, r);\r
-            sort(bonds, p, q);\r
-            sort(bonds, q + 1, r);\r
-        }\r
-    }\r
-\r
-    private int partition(Vector bonds, int p, int r) {\r
-        float x = ((Bond) bonds.elementAt(p)).start[2];\r
-        int i = p - 1;\r
-        int j = r + 1;\r
-        Bond tmp;\r
-        while (true) {\r
-            do {\r
-                j = j - 1;\r
-            } while ((j >= 0) && (((Bond) bonds.elementAt(j)).start[2] > x));\r
-\r
-            do {\r
-                i = i + 1;\r
-            } while ((i < bonds.size()) &&\r
-                    (((Bond) bonds.elementAt(i)).start[2] < x));\r
-\r
-            if (i < j) {\r
-                tmp = (Bond) bonds.elementAt(i);\r
-                bonds.setElementAt(bonds.elementAt(j), i);\r
-                bonds.setElementAt(tmp, j);\r
-            } else {\r
-                return j;\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package MCview;
+
+import java.util.*;
+
+
+public class Zsort {
+    public void Zsort(Vector bonds) {
+        sort(bonds, 0, bonds.size() - 1);
+    }
+
+    public void sort(Vector bonds, int p, int r) {
+        int q;
+
+        if (p < r) {
+            q = partition(bonds, p, r);
+            sort(bonds, p, q);
+            sort(bonds, q + 1, r);
+        }
+    }
+
+    private int partition(Vector bonds, int p, int r) {
+        float x = ((Bond) bonds.elementAt(p)).start[2];
+        int i = p - 1;
+        int j = r + 1;
+        Bond tmp;
+        while (true) {
+            do {
+                j --;
+            } while ((j >= 0) && (((Bond) bonds.elementAt(j)).start[2] > x));
+
+            do {
+                i ++;
+            } while ((i < bonds.size()) &&
+                    (((Bond) bonds.elementAt(i)).start[2] < x));
+
+            if (i < j) {
+                tmp = (Bond) bonds.elementAt(i);
+                bonds.setElementAt(bonds.elementAt(j), i);
+                bonds.setElementAt(tmp, j);
+            } else {
+                return j;
+            }
+        }
+    }
+}
index ffbe5cb..2b9d19b 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package ext.vamsas;\r
-\r
-public interface MuscleWS extends java.rmi.Remote {\r
-    public vamsas.objects.simple.WsJobId align(\r
-        vamsas.objects.simple.SequenceSet seqSet)\r
-        throws java.rmi.RemoteException;\r
-\r
-    public vamsas.objects.simple.Alignment getalign(java.lang.String job_id)\r
-        throws java.rmi.RemoteException;\r
-\r
-    public vamsas.objects.simple.MsaResult getResult(java.lang.String job_id)\r
-        throws java.rmi.RemoteException;\r
-\r
-    public vamsas.objects.simple.WsJobId cancel(java.lang.String jobId)\r
-        throws java.rmi.RemoteException;\r
-}\r
+*/
+package ext.vamsas;
+
+public interface MuscleWS extends java.rmi.Remote {
+    public vamsas.objects.simple.WsJobId align(
+        vamsas.objects.simple.SequenceSet seqSet)
+        throws java.rmi.RemoteException;
+
+    public vamsas.objects.simple.Alignment getalign(java.lang.String job_id)
+        throws java.rmi.RemoteException;
+
+    public vamsas.objects.simple.MsaResult getResult(java.lang.String job_id)
+        throws java.rmi.RemoteException;
+
+    public vamsas.objects.simple.WsJobId cancel(java.lang.String jobId)
+        throws java.rmi.RemoteException;
+}
index ffc4abc..f4984e3 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package ext.vamsas;\r
-\r
-public interface MuscleWSService extends javax.xml.rpc.Service {\r
-    public java.lang.String getMuscleWSAddress();\r
-\r
-    public ext.vamsas.MuscleWS getMuscleWS()\r
-        throws javax.xml.rpc.ServiceException;\r
-\r
-    public ext.vamsas.MuscleWS getMuscleWS(java.net.URL portAddress)\r
-        throws javax.xml.rpc.ServiceException;\r
-}\r
+*/
+package ext.vamsas;
+
+public interface MuscleWSService extends javax.xml.rpc.Service {
+    public java.lang.String getMuscleWSAddress();
+
+    public ext.vamsas.MuscleWS getMuscleWS()
+        throws javax.xml.rpc.ServiceException;
+
+    public ext.vamsas.MuscleWS getMuscleWS(java.net.URL portAddress)
+        throws javax.xml.rpc.ServiceException;
+}
index 96ef074..565b73e 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package ext.vamsas;\r
-\r
-public class MuscleWSServiceLocator extends org.apache.axis.client.Service\r
-    implements ext.vamsas.MuscleWSService {\r
-    // Use to get a proxy class for MuscleWS\r
-    private java.lang.String MuscleWS_address = "http://anaplog.compbio.dundee.ac.uk:8080/axis/services/MuscleWS";\r
-\r
-    // The WSDD service name defaults to the port name.\r
-    private java.lang.String MuscleWSWSDDServiceName = "MuscleWS";\r
-    private java.util.HashSet ports = null;\r
-\r
-    public MuscleWSServiceLocator() {\r
-    }\r
-\r
-    public MuscleWSServiceLocator(org.apache.axis.EngineConfiguration config) {\r
-        super(config);\r
-    }\r
-\r
-    public java.lang.String getMuscleWSAddress() {\r
-        return MuscleWS_address;\r
-    }\r
-\r
-    public java.lang.String getMuscleWSWSDDServiceName() {\r
-        return MuscleWSWSDDServiceName;\r
-    }\r
-\r
-    public void setMuscleWSWSDDServiceName(java.lang.String name) {\r
-        MuscleWSWSDDServiceName = name;\r
-    }\r
-\r
-    public ext.vamsas.MuscleWS getMuscleWS()\r
-        throws javax.xml.rpc.ServiceException {\r
-        java.net.URL endpoint;\r
-\r
-        try {\r
-            endpoint = new java.net.URL(MuscleWS_address);\r
-        } catch (java.net.MalformedURLException e) {\r
-            throw new javax.xml.rpc.ServiceException(e);\r
-        }\r
-\r
-        return getMuscleWS(endpoint);\r
-    }\r
-\r
-    public ext.vamsas.MuscleWS getMuscleWS(java.net.URL portAddress)\r
-        throws javax.xml.rpc.ServiceException {\r
-        try {\r
-            ext.vamsas.MuscleWSSoapBindingStub _stub = new ext.vamsas.MuscleWSSoapBindingStub(portAddress,\r
-                    this);\r
-            _stub.setPortName(getMuscleWSWSDDServiceName());\r
-\r
-            return _stub;\r
-        } catch (org.apache.axis.AxisFault e) {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    public void setMuscleWSEndpointAddress(java.lang.String address) {\r
-        MuscleWS_address = address;\r
-    }\r
-\r
+*/
+package ext.vamsas;
+
+public class MuscleWSServiceLocator extends org.apache.axis.client.Service
+    implements ext.vamsas.MuscleWSService {
+    // Use to get a proxy class for MuscleWS
+    private java.lang.String MuscleWS_address = "http://anaplog.compbio.dundee.ac.uk:8080/axis/services/MuscleWS";
+
+    // The WSDD service name defaults to the port name.
+    private java.lang.String MuscleWSWSDDServiceName = "MuscleWS";
+    private java.util.HashSet ports = null;
+
+    public MuscleWSServiceLocator() {
+    }
+
+    public MuscleWSServiceLocator(org.apache.axis.EngineConfiguration config) {
+        super(config);
+    }
+
+    public java.lang.String getMuscleWSAddress() {
+        return MuscleWS_address;
+    }
+
+    public java.lang.String getMuscleWSWSDDServiceName() {
+        return MuscleWSWSDDServiceName;
+    }
+
+    public void setMuscleWSWSDDServiceName(java.lang.String name) {
+        MuscleWSWSDDServiceName = name;
+    }
+
+    public ext.vamsas.MuscleWS getMuscleWS()
+        throws javax.xml.rpc.ServiceException {
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(MuscleWS_address);
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        return getMuscleWS(endpoint);
+    }
+
+    public ext.vamsas.MuscleWS getMuscleWS(java.net.URL portAddress)
+        throws javax.xml.rpc.ServiceException {
+        try {
+            ext.vamsas.MuscleWSSoapBindingStub _stub = new ext.vamsas.MuscleWSSoapBindingStub(portAddress,
+                    this);
+            _stub.setPortName(getMuscleWSWSDDServiceName());
+
+            return _stub;
+        } catch (org.apache.axis.AxisFault e) {
+            return null;
+        }
+    }
+
+    public void setMuscleWSEndpointAddress(java.lang.String address) {
+        MuscleWS_address = address;
+    }
+
     /**
  * For the given interface, get the stub implementation.
  * If this service has no port for the given interface,
  * then ServiceException is thrown.
     /**
  * For the given interface, get the stub implementation.
  * If this service has no port for the given interface,
  * then ServiceException is thrown.
- */\r
-    public java.rmi.Remote getPort(Class serviceEndpointInterface)\r
-        throws javax.xml.rpc.ServiceException {\r
-        try {\r
-            if (ext.vamsas.MuscleWS.class.isAssignableFrom(\r
-                        serviceEndpointInterface)) {\r
-                ext.vamsas.MuscleWSSoapBindingStub _stub = new ext.vamsas.MuscleWSSoapBindingStub(new java.net.URL(\r
-                            MuscleWS_address), this);\r
-                _stub.setPortName(getMuscleWSWSDDServiceName());\r
-\r
-                return _stub;\r
-            }\r
-        } catch (java.lang.Throwable t) {\r
-            throw new javax.xml.rpc.ServiceException(t);\r
-        }\r
-\r
-        throw new javax.xml.rpc.ServiceException(\r
-            "There is no stub implementation for the interface:  " +\r
-            ((serviceEndpointInterface == null) ? "null"\r
-                                                : serviceEndpointInterface.getName()));\r
-    }\r
-\r
+ */
+    public java.rmi.Remote getPort(Class serviceEndpointInterface)
+        throws javax.xml.rpc.ServiceException {
+        try {
+            if (ext.vamsas.MuscleWS.class.isAssignableFrom(
+                        serviceEndpointInterface)) {
+                ext.vamsas.MuscleWSSoapBindingStub _stub = new ext.vamsas.MuscleWSSoapBindingStub(new java.net.URL(
+                            MuscleWS_address), this);
+                _stub.setPortName(getMuscleWSWSDDServiceName());
+
+                return _stub;
+            }
+        } catch (java.lang.Throwable t) {
+            throw new javax.xml.rpc.ServiceException(t);
+        }
+
+        throw new javax.xml.rpc.ServiceException(
+            "There is no stub implementation for the interface:  " +
+            ((serviceEndpointInterface == null) ? "null"
+                                                : serviceEndpointInterface.getName()));
+    }
+
     /**
  * For the given interface, get the stub implementation.
  * If this service has no port for the given interface,
  * then ServiceException is thrown.
     /**
  * For the given interface, get the stub implementation.
  * If this service has no port for the given interface,
  * then ServiceException is thrown.
- */\r
-    public java.rmi.Remote getPort(javax.xml.namespace.QName portName,\r
-        Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {\r
-        if (portName == null) {\r
-            return getPort(serviceEndpointInterface);\r
-        }\r
-\r
-        java.lang.String inputPortName = portName.getLocalPart();\r
-\r
-        if ("MuscleWS".equals(inputPortName)) {\r
-            return getMuscleWS();\r
-        } else {\r
-            java.rmi.Remote _stub = getPort(serviceEndpointInterface);\r
-            ((org.apache.axis.client.Stub) _stub).setPortName(portName);\r
-\r
-            return _stub;\r
-        }\r
-    }\r
-\r
-    public javax.xml.namespace.QName getServiceName() {\r
-        return new javax.xml.namespace.QName("vamsas", "MuscleWSService");\r
-    }\r
-\r
-    public java.util.Iterator getPorts() {\r
-        if (ports == null) {\r
-            ports = new java.util.HashSet();\r
-            ports.add(new javax.xml.namespace.QName("vamsas", "MuscleWS"));\r
-        }\r
-\r
-        return ports.iterator();\r
-    }\r
-\r
+ */
+    public java.rmi.Remote getPort(javax.xml.namespace.QName portName,
+        Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
+        if (portName == null) {
+            return getPort(serviceEndpointInterface);
+        }
+
+        java.lang.String inputPortName = portName.getLocalPart();
+
+        if ("MuscleWS".equals(inputPortName)) {
+            return getMuscleWS();
+        } else {
+            java.rmi.Remote _stub = getPort(serviceEndpointInterface);
+            ((org.apache.axis.client.Stub) _stub).setPortName(portName);
+
+            return _stub;
+        }
+    }
+
+    public javax.xml.namespace.QName getServiceName() {
+        return new javax.xml.namespace.QName("vamsas", "MuscleWSService");
+    }
+
+    public java.util.Iterator getPorts() {
+        if (ports == null) {
+            ports = new java.util.HashSet();
+            ports.add(new javax.xml.namespace.QName("vamsas", "MuscleWS"));
+        }
+
+        return ports.iterator();
+    }
+
     /**
 * Set the endpoint address for the specified port name.
     /**
 * Set the endpoint address for the specified port name.
-*/\r
-    public void setEndpointAddress(java.lang.String portName,\r
-        java.lang.String address) throws javax.xml.rpc.ServiceException {\r
-        if ("MuscleWS".equals(portName)) {\r
-            setMuscleWSEndpointAddress(address);\r
-        } else { // Unknown Port Name\r
-            throw new javax.xml.rpc.ServiceException(\r
-                " Cannot set Endpoint Address for Unknown Port" + portName);\r
-        }\r
-    }\r
-\r
+*/
+    public void setEndpointAddress(java.lang.String portName,
+        java.lang.String address) throws javax.xml.rpc.ServiceException {
+        if ("MuscleWS".equals(portName)) {
+            setMuscleWSEndpointAddress(address);
+        } else { // Unknown Port Name
+            throw new javax.xml.rpc.ServiceException(
+                " Cannot set Endpoint Address for Unknown Port" + portName);
+        }
+    }
+
     /**
 * Set the endpoint address for the specified port name.
     /**
 * Set the endpoint address for the specified port name.
-*/\r
-    public void setEndpointAddress(javax.xml.namespace.QName portName,\r
-        java.lang.String address) throws javax.xml.rpc.ServiceException {\r
-        setEndpointAddress(portName.getLocalPart(), address);\r
-    }\r
-}\r
+*/
+    public void setEndpointAddress(javax.xml.namespace.QName portName,
+        java.lang.String address) throws javax.xml.rpc.ServiceException {
+        setEndpointAddress(portName.getLocalPart(), address);
+    }
+}
index c56432d..b1f8065 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package ext.vamsas;\r
-\r
-public class MuscleWSSoapBindingStub extends org.apache.axis.client.Stub\r
-    implements ext.vamsas.MuscleWS {\r
-    static org.apache.axis.description.OperationDesc[] _operations;\r
-\r
-    static {\r
-        _operations = new org.apache.axis.description.OperationDesc[4];\r
-        _initOperationDesc1();\r
-    }\r
-\r
-    private java.util.Vector cachedSerClasses = new java.util.Vector();\r
-    private java.util.Vector cachedSerQNames = new java.util.Vector();\r
-    private java.util.Vector cachedSerFactories = new java.util.Vector();\r
-    private java.util.Vector cachedDeserFactories = new java.util.Vector();\r
-\r
-    public MuscleWSSoapBindingStub() throws org.apache.axis.AxisFault {\r
-        this(null);\r
-    }\r
-\r
-    public MuscleWSSoapBindingStub(java.net.URL endpointURL,\r
-        javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {\r
-        this(service);\r
-        super.cachedEndpoint = endpointURL;\r
-    }\r
-\r
-    public MuscleWSSoapBindingStub(javax.xml.rpc.Service service)\r
-        throws org.apache.axis.AxisFault {\r
-        if (service == null) {\r
-            super.service = new org.apache.axis.client.Service();\r
-        } else {\r
-            super.service = service;\r
-        }\r
-\r
-        java.lang.Class cls;\r
-        javax.xml.namespace.QName qName;\r
-        java.lang.Class beansf = org.apache.axis.encoding.ser.BeanSerializerFactory.class;\r
-        java.lang.Class beandf = org.apache.axis.encoding.ser.BeanDeserializerFactory.class;\r
-        //java.lang.Class enumsf = org.apache.axis.encoding.ser.EnumSerializerFactory.class;\r
-        //java.lang.Class enumdf = org.apache.axis.encoding.ser.EnumDeserializerFactory.class;\r
-        java.lang.Class arraysf = org.apache.axis.encoding.ser.ArraySerializerFactory.class;\r
-        java.lang.Class arraydf = org.apache.axis.encoding.ser.ArrayDeserializerFactory.class;\r
-        //java.lang.Class simplesf = org.apache.axis.encoding.ser.SimpleSerializerFactory.class;\r
-        // java.lang.Class simpledf = org.apache.axis.encoding.ser.SimpleDeserializerFactory.class;\r
-        //java.lang.Class simplelistsf = org.apache.axis.encoding.ser.SimpleListSerializerFactory.class;\r
-        //java.lang.Class simplelistdf = org.apache.axis.encoding.ser.SimpleListDeserializerFactory.class;\r
-        qName = new javax.xml.namespace.QName("simple.objects.vamsas",\r
-                "Sequence");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.Sequence.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-\r
-        qName = new javax.xml.namespace.QName("vamsas", "ArrayOf_tns1_Sequence");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.Sequence[].class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(arraysf);\r
-        cachedDeserFactories.add(arraydf);\r
-\r
-        qName = new javax.xml.namespace.QName("simple.objects.vamsas",\r
-                "MsaResult");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.MsaResult.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-\r
-        qName = new javax.xml.namespace.QName("simple.objects.vamsas",\r
-                "SequenceSet");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.SequenceSet.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-\r
-        qName = new javax.xml.namespace.QName("http://simple.objects.vamsas",\r
-                "Object");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.Object.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-\r
-        qName = new javax.xml.namespace.QName("simple.objects.vamsas",\r
-                "Alignment");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.Alignment.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-\r
-        qName = new javax.xml.namespace.QName("simple.objects.vamsas", "WsJobId");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.WsJobId.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-\r
-        qName = new javax.xml.namespace.QName("vamsas", "ArrayOf_xsd_string");\r
-        cachedSerQNames.add(qName);\r
-        cls = java.lang.String[].class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(arraysf);\r
-        cachedDeserFactories.add(arraydf);\r
-\r
-        qName = new javax.xml.namespace.QName("simple.objects.vamsas", "Result");\r
-        cachedSerQNames.add(qName);\r
-        cls = vamsas.objects.simple.Result.class;\r
-        cachedSerClasses.add(cls);\r
-        cachedSerFactories.add(beansf);\r
-        cachedDeserFactories.add(beandf);\r
-    }\r
-\r
-    private static void _initOperationDesc1() {\r
-        org.apache.axis.description.OperationDesc oper;\r
-        oper = new org.apache.axis.description.OperationDesc();\r
-        oper.setName("align");\r
-        oper.addParameter(new javax.xml.namespace.QName("", "seqSet"),\r
-            new javax.xml.namespace.QName("simple.objects.vamsas", "SequenceSet"),\r
-            vamsas.objects.simple.SequenceSet.class,\r
-            org.apache.axis.description.ParameterDesc.IN, false, false);\r
-        oper.setReturnType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "WsJobId"));\r
-        oper.setReturnClass(vamsas.objects.simple.WsJobId.class);\r
-        oper.setReturnQName(new javax.xml.namespace.QName("", "alignReturn"));\r
-        oper.setStyle(org.apache.axis.constants.Style.RPC);\r
-        oper.setUse(org.apache.axis.constants.Use.ENCODED);\r
-        _operations[0] = oper;\r
-\r
-        oper = new org.apache.axis.description.OperationDesc();\r
-        oper.setName("getalign");\r
-        oper.addParameter(new javax.xml.namespace.QName("", "job_id"),\r
-            new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema",\r
-                "string"), java.lang.String.class,\r
-            org.apache.axis.description.ParameterDesc.IN, false, false);\r
-        oper.setReturnType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "Alignment"));\r
-        oper.setReturnClass(vamsas.objects.simple.Alignment.class);\r
-        oper.setReturnQName(new javax.xml.namespace.QName("", "getalignReturn"));\r
-        oper.setStyle(org.apache.axis.constants.Style.RPC);\r
-        oper.setUse(org.apache.axis.constants.Use.ENCODED);\r
-        _operations[1] = oper;\r
-\r
-        oper = new org.apache.axis.description.OperationDesc();\r
-        oper.setName("getResult");\r
-        oper.addParameter(new javax.xml.namespace.QName("", "job_id"),\r
-            new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema",\r
-                "string"), java.lang.String.class,\r
-            org.apache.axis.description.ParameterDesc.IN, false, false);\r
-        oper.setReturnType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "MsaResult"));\r
-        oper.setReturnClass(vamsas.objects.simple.MsaResult.class);\r
-        oper.setReturnQName(new javax.xml.namespace.QName("", "getResultReturn"));\r
-        oper.setStyle(org.apache.axis.constants.Style.RPC);\r
-        oper.setUse(org.apache.axis.constants.Use.ENCODED);\r
-        _operations[2] = oper;\r
-\r
-        oper = new org.apache.axis.description.OperationDesc();\r
-        oper.setName("cancel");\r
-        oper.addParameter(new javax.xml.namespace.QName("", "jobId"),\r
-            new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema",\r
-                "string"), java.lang.String.class,\r
-            org.apache.axis.description.ParameterDesc.IN, false, false);\r
-        oper.setReturnType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "WsJobId"));\r
-        oper.setReturnClass(vamsas.objects.simple.WsJobId.class);\r
-        oper.setReturnQName(new javax.xml.namespace.QName("", "cancelReturn"));\r
-        oper.setStyle(org.apache.axis.constants.Style.RPC);\r
-        oper.setUse(org.apache.axis.constants.Use.ENCODED);\r
-        _operations[3] = oper;\r
-    }\r
-\r
-    protected org.apache.axis.client.Call createCall()\r
-        throws java.rmi.RemoteException {\r
-        try {\r
-            org.apache.axis.client.Call _call = (org.apache.axis.client.Call) super.service.createCall();\r
-\r
-            if (super.maintainSessionSet) {\r
-                _call.setMaintainSession(super.maintainSession);\r
-            }\r
-\r
-            if (super.cachedUsername != null) {\r
-                _call.setUsername(super.cachedUsername);\r
-            }\r
-\r
-            if (super.cachedPassword != null) {\r
-                _call.setPassword(super.cachedPassword);\r
-            }\r
-\r
-            if (super.cachedEndpoint != null) {\r
-                _call.setTargetEndpointAddress(super.cachedEndpoint);\r
-            }\r
-\r
-            if (super.cachedTimeout != null) {\r
-                _call.setTimeout(super.cachedTimeout);\r
-            }\r
-\r
-            if (super.cachedPortName != null) {\r
-                _call.setPortName(super.cachedPortName);\r
-            }\r
-\r
-            java.util.Enumeration keys = super.cachedProperties.keys();\r
-\r
-            while (keys.hasMoreElements()) {\r
-                java.lang.String key = (java.lang.String) keys.nextElement();\r
-                _call.setProperty(key, super.cachedProperties.get(key));\r
-            }\r
-\r
-            // All the type mapping information is registered\r
-            // when the first call is made.\r
-            // The type mapping information is actually registered in\r
-            // the TypeMappingRegistry of the service, which\r
-            // is the reason why registration is only needed for the first call.\r
-            synchronized (this) {\r
-                if (firstCall()) {\r
-                    // must set encoding style before registering serializers\r
-                    _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);\r
-                    _call.setEncodingStyle(org.apache.axis.Constants.URI_SOAP11_ENC);\r
-\r
-                    for (int i = 0; i < cachedSerFactories.size(); ++i) {\r
-                        java.lang.Class cls = (java.lang.Class) cachedSerClasses.get(i);\r
-                        javax.xml.namespace.QName qName = (javax.xml.namespace.QName) cachedSerQNames.get(i);\r
-                        java.lang.Class sf = (java.lang.Class) cachedSerFactories.get(i);\r
-                        java.lang.Class df = (java.lang.Class) cachedDeserFactories.get(i);\r
-                        _call.registerTypeMapping(cls, qName, sf, df, false);\r
-                    }\r
-                }\r
-            }\r
-\r
-            return _call;\r
-        } catch (java.lang.Throwable _t) {\r
-            throw new org.apache.axis.AxisFault("Failure trying to get the Call object",\r
-                _t);\r
-        }\r
-    }\r
-\r
-    public vamsas.objects.simple.WsJobId align(\r
-        vamsas.objects.simple.SequenceSet seqSet)\r
-        throws java.rmi.RemoteException {\r
-        if (super.cachedEndpoint == null) {\r
-            throw new org.apache.axis.NoEndPointException();\r
-        }\r
-\r
-        org.apache.axis.client.Call _call = createCall();\r
-        _call.setOperation(_operations[0]);\r
-        _call.setUseSOAPAction(true);\r
-        _call.setSOAPActionURI("");\r
-        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);\r
-        _call.setOperationName(new javax.xml.namespace.QName("vamsas", "align"));\r
-\r
-        setRequestHeaders(_call);\r
-        setAttachments(_call);\r
-\r
-        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { seqSet });\r
-\r
-        if (_resp instanceof java.rmi.RemoteException) {\r
-            throw (java.rmi.RemoteException) _resp;\r
-        } else {\r
-            extractAttachments(_call);\r
-\r
-            try {\r
-                return (vamsas.objects.simple.WsJobId) _resp;\r
-            } catch (java.lang.Exception _exception) {\r
-                return (vamsas.objects.simple.WsJobId) org.apache.axis.utils.JavaUtils.convert(_resp,\r
-                    vamsas.objects.simple.WsJobId.class);\r
-            }\r
-        }\r
-    }\r
-\r
-    public vamsas.objects.simple.Alignment getalign(java.lang.String job_id)\r
-        throws java.rmi.RemoteException {\r
-        if (super.cachedEndpoint == null) {\r
-            throw new org.apache.axis.NoEndPointException();\r
-        }\r
-\r
-        org.apache.axis.client.Call _call = createCall();\r
-        _call.setOperation(_operations[1]);\r
-        _call.setUseSOAPAction(true);\r
-        _call.setSOAPActionURI("");\r
-        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);\r
-        _call.setOperationName(new javax.xml.namespace.QName("vamsas",\r
-                "getalign"));\r
-\r
-        setRequestHeaders(_call);\r
-        setAttachments(_call);\r
-\r
-        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { job_id });\r
-\r
-        if (_resp instanceof java.rmi.RemoteException) {\r
-            throw (java.rmi.RemoteException) _resp;\r
-        } else {\r
-            extractAttachments(_call);\r
-\r
-            try {\r
-                return (vamsas.objects.simple.Alignment) _resp;\r
-            } catch (java.lang.Exception _exception) {\r
-                return (vamsas.objects.simple.Alignment) org.apache.axis.utils.JavaUtils.convert(_resp,\r
-                    vamsas.objects.simple.Alignment.class);\r
-            }\r
-        }\r
-    }\r
-\r
-    public vamsas.objects.simple.MsaResult getResult(java.lang.String job_id)\r
-        throws java.rmi.RemoteException {\r
-        if (super.cachedEndpoint == null) {\r
-            throw new org.apache.axis.NoEndPointException();\r
-        }\r
-\r
-        org.apache.axis.client.Call _call = createCall();\r
-        _call.setOperation(_operations[2]);\r
-        _call.setUseSOAPAction(true);\r
-        _call.setSOAPActionURI("");\r
-        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);\r
-        _call.setOperationName(new javax.xml.namespace.QName("vamsas",\r
-                "getResult"));\r
-\r
-        setRequestHeaders(_call);\r
-        setAttachments(_call);\r
-\r
-        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { job_id });\r
-\r
-        if (_resp instanceof java.rmi.RemoteException) {\r
-            throw (java.rmi.RemoteException) _resp;\r
-        } else {\r
-            extractAttachments(_call);\r
-\r
-            try {\r
-                return (vamsas.objects.simple.MsaResult) _resp;\r
-            } catch (java.lang.Exception _exception) {\r
-                return (vamsas.objects.simple.MsaResult) org.apache.axis.utils.JavaUtils.convert(_resp,\r
-                    vamsas.objects.simple.MsaResult.class);\r
-            }\r
-        }\r
-    }\r
-\r
-    public vamsas.objects.simple.WsJobId cancel(java.lang.String jobId)\r
-        throws java.rmi.RemoteException {\r
-        if (super.cachedEndpoint == null) {\r
-            throw new org.apache.axis.NoEndPointException();\r
-        }\r
-\r
-        org.apache.axis.client.Call _call = createCall();\r
-        _call.setOperation(_operations[3]);\r
-        _call.setUseSOAPAction(true);\r
-        _call.setSOAPActionURI("");\r
-        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);\r
-        _call.setOperationName(new javax.xml.namespace.QName("vamsas", "cancel"));\r
-\r
-        setRequestHeaders(_call);\r
-        setAttachments(_call);\r
-\r
-        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { jobId });\r
-\r
-        if (_resp instanceof java.rmi.RemoteException) {\r
-            throw (java.rmi.RemoteException) _resp;\r
-        } else {\r
-            extractAttachments(_call);\r
-\r
-            try {\r
-                return (vamsas.objects.simple.WsJobId) _resp;\r
-            } catch (java.lang.Exception _exception) {\r
-                return (vamsas.objects.simple.WsJobId) org.apache.axis.utils.JavaUtils.convert(_resp,\r
-                    vamsas.objects.simple.WsJobId.class);\r
-            }\r
-        }\r
-    }\r
-}\r
+*/
+package ext.vamsas;
+
+public class MuscleWSSoapBindingStub extends org.apache.axis.client.Stub
+    implements ext.vamsas.MuscleWS {
+    static org.apache.axis.description.OperationDesc[] _operations;
+
+    static {
+        _operations = new org.apache.axis.description.OperationDesc[4];
+        _initOperationDesc1();
+    }
+
+    private java.util.Vector cachedSerClasses = new java.util.Vector();
+    private java.util.Vector cachedSerQNames = new java.util.Vector();
+    private java.util.Vector cachedSerFactories = new java.util.Vector();
+    private java.util.Vector cachedDeserFactories = new java.util.Vector();
+
+    public MuscleWSSoapBindingStub() throws org.apache.axis.AxisFault {
+        this(null);
+    }
+
+    public MuscleWSSoapBindingStub(java.net.URL endpointURL,
+        javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
+        this(service);
+        super.cachedEndpoint = endpointURL;
+    }
+
+    public MuscleWSSoapBindingStub(javax.xml.rpc.Service service)
+        throws org.apache.axis.AxisFault {
+        if (service == null) {
+            super.service = new org.apache.axis.client.Service();
+        } else {
+            super.service = service;
+        }
+
+        java.lang.Class cls;
+        javax.xml.namespace.QName qName;
+        java.lang.Class beansf = org.apache.axis.encoding.ser.BeanSerializerFactory.class;
+        java.lang.Class beandf = org.apache.axis.encoding.ser.BeanDeserializerFactory.class;
+        //java.lang.Class enumsf = org.apache.axis.encoding.ser.EnumSerializerFactory.class;
+        //java.lang.Class enumdf = org.apache.axis.encoding.ser.EnumDeserializerFactory.class;
+        java.lang.Class arraysf = org.apache.axis.encoding.ser.ArraySerializerFactory.class;
+        java.lang.Class arraydf = org.apache.axis.encoding.ser.ArrayDeserializerFactory.class;
+        //java.lang.Class simplesf = org.apache.axis.encoding.ser.SimpleSerializerFactory.class;
+        // java.lang.Class simpledf = org.apache.axis.encoding.ser.SimpleDeserializerFactory.class;
+        //java.lang.Class simplelistsf = org.apache.axis.encoding.ser.SimpleListSerializerFactory.class;
+        //java.lang.Class simplelistdf = org.apache.axis.encoding.ser.SimpleListDeserializerFactory.class;
+        qName = new javax.xml.namespace.QName("simple.objects.vamsas",
+                "Sequence");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.Sequence.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+
+        qName = new javax.xml.namespace.QName("vamsas", "ArrayOf_tns1_Sequence");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.Sequence[].class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(arraysf);
+        cachedDeserFactories.add(arraydf);
+
+        qName = new javax.xml.namespace.QName("simple.objects.vamsas",
+                "MsaResult");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.MsaResult.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+
+        qName = new javax.xml.namespace.QName("simple.objects.vamsas",
+                "SequenceSet");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.SequenceSet.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+
+        qName = new javax.xml.namespace.QName("http://simple.objects.vamsas",
+                "Object");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.Object.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+
+        qName = new javax.xml.namespace.QName("simple.objects.vamsas",
+                "Alignment");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.Alignment.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+
+        qName = new javax.xml.namespace.QName("simple.objects.vamsas", "WsJobId");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.WsJobId.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+
+        qName = new javax.xml.namespace.QName("vamsas", "ArrayOf_xsd_string");
+        cachedSerQNames.add(qName);
+        cls = java.lang.String[].class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(arraysf);
+        cachedDeserFactories.add(arraydf);
+
+        qName = new javax.xml.namespace.QName("simple.objects.vamsas", "Result");
+        cachedSerQNames.add(qName);
+        cls = vamsas.objects.simple.Result.class;
+        cachedSerClasses.add(cls);
+        cachedSerFactories.add(beansf);
+        cachedDeserFactories.add(beandf);
+    }
+
+    private static void _initOperationDesc1() {
+        org.apache.axis.description.OperationDesc oper;
+        oper = new org.apache.axis.description.OperationDesc();
+        oper.setName("align");
+        oper.addParameter(new javax.xml.namespace.QName("", "seqSet"),
+            new javax.xml.namespace.QName("simple.objects.vamsas", "SequenceSet"),
+            vamsas.objects.simple.SequenceSet.class,
+            org.apache.axis.description.ParameterDesc.IN, false, false);
+        oper.setReturnType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "WsJobId"));
+        oper.setReturnClass(vamsas.objects.simple.WsJobId.class);
+        oper.setReturnQName(new javax.xml.namespace.QName("", "alignReturn"));
+        oper.setStyle(org.apache.axis.constants.Style.RPC);
+        oper.setUse(org.apache.axis.constants.Use.ENCODED);
+        _operations[0] = oper;
+
+        oper = new org.apache.axis.description.OperationDesc();
+        oper.setName("getalign");
+        oper.addParameter(new javax.xml.namespace.QName("", "job_id"),
+            new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema",
+                "string"), java.lang.String.class,
+            org.apache.axis.description.ParameterDesc.IN, false, false);
+        oper.setReturnType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "Alignment"));
+        oper.setReturnClass(vamsas.objects.simple.Alignment.class);
+        oper.setReturnQName(new javax.xml.namespace.QName("", "getalignReturn"));
+        oper.setStyle(org.apache.axis.constants.Style.RPC);
+        oper.setUse(org.apache.axis.constants.Use.ENCODED);
+        _operations[1] = oper;
+
+        oper = new org.apache.axis.description.OperationDesc();
+        oper.setName("getResult");
+        oper.addParameter(new javax.xml.namespace.QName("", "job_id"),
+            new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema",
+                "string"), java.lang.String.class,
+            org.apache.axis.description.ParameterDesc.IN, false, false);
+        oper.setReturnType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "MsaResult"));
+        oper.setReturnClass(vamsas.objects.simple.MsaResult.class);
+        oper.setReturnQName(new javax.xml.namespace.QName("", "getResultReturn"));
+        oper.setStyle(org.apache.axis.constants.Style.RPC);
+        oper.setUse(org.apache.axis.constants.Use.ENCODED);
+        _operations[2] = oper;
+
+        oper = new org.apache.axis.description.OperationDesc();
+        oper.setName("cancel");
+        oper.addParameter(new javax.xml.namespace.QName("", "jobId"),
+            new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema",
+                "string"), java.lang.String.class,
+            org.apache.axis.description.ParameterDesc.IN, false, false);
+        oper.setReturnType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "WsJobId"));
+        oper.setReturnClass(vamsas.objects.simple.WsJobId.class);
+        oper.setReturnQName(new javax.xml.namespace.QName("", "cancelReturn"));
+        oper.setStyle(org.apache.axis.constants.Style.RPC);
+        oper.setUse(org.apache.axis.constants.Use.ENCODED);
+        _operations[3] = oper;
+    }
+
+    protected org.apache.axis.client.Call createCall()
+        throws java.rmi.RemoteException {
+        try {
+            org.apache.axis.client.Call _call = (org.apache.axis.client.Call) super.service.createCall();
+
+            if (super.maintainSessionSet) {
+                _call.setMaintainSession(super.maintainSession);
+            }
+
+            if (super.cachedUsername != null) {
+                _call.setUsername(super.cachedUsername);
+            }
+
+            if (super.cachedPassword != null) {
+                _call.setPassword(super.cachedPassword);
+            }
+
+            if (super.cachedEndpoint != null) {
+                _call.setTargetEndpointAddress(super.cachedEndpoint);
+            }
+
+            if (super.cachedTimeout != null) {
+                _call.setTimeout(super.cachedTimeout);
+            }
+
+            if (super.cachedPortName != null) {
+                _call.setPortName(super.cachedPortName);
+            }
+
+            java.util.Enumeration keys = super.cachedProperties.keys();
+
+            while (keys.hasMoreElements()) {
+                java.lang.String key = (java.lang.String) keys.nextElement();
+                _call.setProperty(key, super.cachedProperties.get(key));
+            }
+
+            // All the type mapping information is registered
+            // when the first call is made.
+            // The type mapping information is actually registered in
+            // the TypeMappingRegistry of the service, which
+            // is the reason why registration is only needed for the first call.
+            synchronized (this) {
+                if (firstCall()) {
+                    // must set encoding style before registering serializers
+                    _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+                    _call.setEncodingStyle(org.apache.axis.Constants.URI_SOAP11_ENC);
+
+                    for (int i = 0; i < cachedSerFactories.size(); ++i) {
+                        java.lang.Class cls = (java.lang.Class) cachedSerClasses.get(i);
+                        javax.xml.namespace.QName qName = (javax.xml.namespace.QName) cachedSerQNames.get(i);
+                        java.lang.Class sf = (java.lang.Class) cachedSerFactories.get(i);
+                        java.lang.Class df = (java.lang.Class) cachedDeserFactories.get(i);
+                        _call.registerTypeMapping(cls, qName, sf, df, false);
+                    }
+                }
+            }
+
+            return _call;
+        } catch (java.lang.Throwable _t) {
+            throw new org.apache.axis.AxisFault("Failure trying to get the Call object",
+                _t);
+        }
+    }
+
+    public vamsas.objects.simple.WsJobId align(
+        vamsas.objects.simple.SequenceSet seqSet)
+        throws java.rmi.RemoteException {
+        if (super.cachedEndpoint == null) {
+            throw new org.apache.axis.NoEndPointException();
+        }
+
+        org.apache.axis.client.Call _call = createCall();
+        _call.setOperation(_operations[0]);
+        _call.setUseSOAPAction(true);
+        _call.setSOAPActionURI("");
+        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+        _call.setOperationName(new javax.xml.namespace.QName("vamsas", "align"));
+
+        setRequestHeaders(_call);
+        setAttachments(_call);
+
+        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { seqSet });
+
+        if (_resp instanceof java.rmi.RemoteException) {
+            throw (java.rmi.RemoteException) _resp;
+        } else {
+            extractAttachments(_call);
+
+            try {
+                return (vamsas.objects.simple.WsJobId) _resp;
+            } catch (java.lang.Exception _exception) {
+                return (vamsas.objects.simple.WsJobId) org.apache.axis.utils.JavaUtils.convert(_resp,
+                    vamsas.objects.simple.WsJobId.class);
+            }
+        }
+    }
+
+    public vamsas.objects.simple.Alignment getalign(java.lang.String job_id)
+        throws java.rmi.RemoteException {
+        if (super.cachedEndpoint == null) {
+            throw new org.apache.axis.NoEndPointException();
+        }
+
+        org.apache.axis.client.Call _call = createCall();
+        _call.setOperation(_operations[1]);
+        _call.setUseSOAPAction(true);
+        _call.setSOAPActionURI("");
+        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+        _call.setOperationName(new javax.xml.namespace.QName("vamsas",
+                "getalign"));
+
+        setRequestHeaders(_call);
+        setAttachments(_call);
+
+        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { job_id });
+
+        if (_resp instanceof java.rmi.RemoteException) {
+            throw (java.rmi.RemoteException) _resp;
+        } else {
+            extractAttachments(_call);
+
+            try {
+                return (vamsas.objects.simple.Alignment) _resp;
+            } catch (java.lang.Exception _exception) {
+                return (vamsas.objects.simple.Alignment) org.apache.axis.utils.JavaUtils.convert(_resp,
+                    vamsas.objects.simple.Alignment.class);
+            }
+        }
+    }
+
+    public vamsas.objects.simple.MsaResult getResult(java.lang.String job_id)
+        throws java.rmi.RemoteException {
+        if (super.cachedEndpoint == null) {
+            throw new org.apache.axis.NoEndPointException();
+        }
+
+        org.apache.axis.client.Call _call = createCall();
+        _call.setOperation(_operations[2]);
+        _call.setUseSOAPAction(true);
+        _call.setSOAPActionURI("");
+        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+        _call.setOperationName(new javax.xml.namespace.QName("vamsas",
+                "getResult"));
+
+        setRequestHeaders(_call);
+        setAttachments(_call);
+
+        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { job_id });
+
+        if (_resp instanceof java.rmi.RemoteException) {
+            throw (java.rmi.RemoteException) _resp;
+        } else {
+            extractAttachments(_call);
+
+            try {
+                return (vamsas.objects.simple.MsaResult) _resp;
+            } catch (java.lang.Exception _exception) {
+                return (vamsas.objects.simple.MsaResult) org.apache.axis.utils.JavaUtils.convert(_resp,
+                    vamsas.objects.simple.MsaResult.class);
+            }
+        }
+    }
+
+    public vamsas.objects.simple.WsJobId cancel(java.lang.String jobId)
+        throws java.rmi.RemoteException {
+        if (super.cachedEndpoint == null) {
+            throw new org.apache.axis.NoEndPointException();
+        }
+
+        org.apache.axis.client.Call _call = createCall();
+        _call.setOperation(_operations[3]);
+        _call.setUseSOAPAction(true);
+        _call.setSOAPActionURI("");
+        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+        _call.setOperationName(new javax.xml.namespace.QName("vamsas", "cancel"));
+
+        setRequestHeaders(_call);
+        setAttachments(_call);
+
+        java.lang.Object _resp = _call.invoke(new java.lang.Object[] { jobId });
+
+        if (_resp instanceof java.rmi.RemoteException) {
+            throw (java.rmi.RemoteException) _resp;
+        } else {
+            extractAttachments(_call);
+
+            try {
+                return (vamsas.objects.simple.WsJobId) _resp;
+            } catch (java.lang.Exception _exception) {
+                return (vamsas.objects.simple.WsJobId) org.apache.axis.utils.JavaUtils.convert(_resp,
+                    vamsas.objects.simple.WsJobId.class);
+            }
+        }
+    }
+}
index ad1fe4e..1f43788 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.analysis;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * Takes in a vector of sequences and column start and column end\r
- * and returns a vector of size (end-start+1). Each element of the\r
- * vector contains a hashtable with the keys being residues and\r
- * the values being the count of each residue in that column.\r
- * This class is used extensively in calculating alignment colourschemes\r
- * that depend on the amount of conservation in each alignment column.\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AAFrequency\r
-{\r
-    /** Takes in a vector of sequences and column start and column end\r
-    * and returns a vector of size (end-start+1). Each element of the\r
-    * vector contains a hashtable with the keys being residues and\r
-    * the values being the count of each residue in that column.\r
-    * This class is used extensively in calculating alignment colourschemes\r
-    * that depend on the amount of conservation in each alignment column. */\r
-    public static final Vector calculate(Vector sequences, int start, int end)\r
-    {\r
-      Vector result = new Vector();\r
-      Hashtable residueHash;\r
-      int count, maxCount, nongap, i, j, jSize = sequences.size();\r
-      String maxResidue, sequence, res;\r
-      float percentage;\r
-\r
-        for (i = start; i <= end; i++)\r
-        {\r
-            residueHash = new Hashtable();\r
-            maxCount = 0;\r
-            maxResidue = "-";\r
-            nongap = 0;\r
-\r
-            for (j = 0; j < jSize; j++)\r
-            {\r
-                if (sequences.elementAt(j) instanceof Sequence)\r
-                {\r
-                    sequence = ((Sequence) sequences.elementAt(j)).getSequence();\r
-\r
-                    if (sequence.length() > i)\r
-                    {\r
-                        res = String.valueOf(Character.toUpperCase(sequence.charAt(i)));\r
-\r
-                        if (jalview.util.Comparison.isGap(res.charAt(0)))\r
-                        {\r
-                            res = "-"; // we always use this for gaps in the property vectors\r
-                        }\r
-                        else\r
-                        {   nongap++;    }\r
-\r
-                        if (residueHash.containsKey(res))\r
-                        {\r
-                            count = ((Integer) residueHash.get(res)).intValue();\r
-                            count++;\r
-\r
-                            if (!jalview.util.Comparison.isGap(res.charAt(0)) &&\r
-                                    (count >= maxCount))\r
-                            {\r
-                                if (count > maxCount)\r
-                                {\r
-                                    maxResidue = res;\r
-                                }\r
-                                else if (maxResidue.indexOf(res) == -1)\r
-                                {\r
-                                    maxResidue += res;\r
-                                }\r
-\r
-                                maxCount = count;\r
-                            }\r
-\r
-                            residueHash.put(res, new Integer(count));\r
-                        }\r
-                        else\r
-                        {\r
-                            residueHash.put(res, new Integer(1));\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        if (residueHash.containsKey("-"))\r
-                        {\r
-                            count = ((Integer) residueHash.get("-")).intValue();\r
-                            count++;\r
-                            residueHash.put("-", new Integer(count));\r
-                        }\r
-                        else\r
-                        {\r
-                            residueHash.put("-", new Integer(1));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-\r
-            residueHash.put("maxCount", new Integer(maxCount));\r
-            residueHash.put("maxResidue", maxResidue);\r
-\r
-\r
-            //Size is redundant at present if we calculate percentage here\r
-            //residueHash.put("size", new Integer(jSize));\r
-            //residueHash.put("nogaps", new Integer(nongap));\r
-\r
-            percentage = ((float)maxCount*100) / (float)jSize;\r
-            residueHash.put("pid_gaps", new Float(percentage) );\r
-\r
-            percentage = ((float)maxCount*100) / (float)nongap;\r
-            residueHash.put("pid_nogaps", new Float(percentage) );\r
-            result.addElement(residueHash);\r
-        }\r
-\r
-\r
-\r
-        return result;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.analysis;
+
+import jalview.datamodel.*;
+
+import java.util.*;
+
+
+/**
+ * Takes in a vector of sequences and column start and column end
+ * and returns a vector of size (end-start+1). Each element of the
+ * vector contains a hashtable with the keys being residues and
+ * the values being the count of each residue in that column.
+ * This class is used extensively in calculating alignment colourschemes
+ * that depend on the amount of conservation in each alignment column.
+ * @author $author$
+ * @version $Revision$
+ */
+public class AAFrequency
+{
+    /** Takes in a vector of sequences and column start and column end
+    * and returns a vector of size (end-start+1). Each element of the
+    * vector contains a hashtable with the keys being residues and
+    * the values being the count of each residue in that column.
+    * This class is used extensively in calculating alignment colourschemes
+    * that depend on the amount of conservation in each alignment column. */
+    public static final Vector calculate(Vector sequences, int start, int end)
+    {
+      Vector result = new Vector();
+      Hashtable residueHash;
+      int count, maxCount, nongap, i, j, jSize = sequences.size();
+      String maxResidue, sequence, res;
+      float percentage;
+
+        for (i = start; i <= end; i++)
+        {
+            residueHash = new Hashtable();
+            maxCount = 0;
+            maxResidue = "-";
+            nongap = 0;
+
+            for (j = 0; j < jSize; j++)
+            {
+                if (sequences.elementAt(j) instanceof Sequence)
+                {
+                    sequence = ((Sequence) sequences.elementAt(j)).getSequence();
+
+                    if (sequence.length() > i)
+                    {
+                        res = String.valueOf(Character.toUpperCase(sequence.charAt(i)));
+
+                        if (jalview.util.Comparison.isGap(res.charAt(0)))
+                        {
+                            res = "-"; // we always use this for gaps in the property vectors
+                        }
+                        else
+                        {   nongap++;    }
+
+                        if (residueHash.containsKey(res))
+                        {
+                            count = ((Integer) residueHash.get(res)).intValue();
+                            count++;
+
+                            if (!jalview.util.Comparison.isGap(res.charAt(0)) &&
+                                    (count >= maxCount))
+                            {
+                                if (count > maxCount)
+                                {
+                                    maxResidue = res;
+                                }
+                                else if (maxResidue.indexOf(res) == -1)
+                                {
+                                    maxResidue += res;
+                                }
+
+                                maxCount = count;
+                            }
+
+                            residueHash.put(res, new Integer(count));
+                        }
+                        else
+                        {
+                            residueHash.put(res, new Integer(1));
+                        }
+                    }
+                    else
+                    {
+                        if (residueHash.containsKey("-"))
+                        {
+                            count = ((Integer) residueHash.get("-")).intValue();
+                            count++;
+                            residueHash.put("-", new Integer(count));
+                        }
+                        else
+                        {
+                            residueHash.put("-", new Integer(1));
+                        }
+                    }
+                }
+            }
+
+            residueHash.put("maxCount", new Integer(maxCount));
+            residueHash.put("maxResidue", maxResidue);
+
+
+            //Size is redundant at present if we calculate percentage here
+            //residueHash.put("size", new Integer(jSize));
+            //residueHash.put("nogaps", new Integer(nongap));
+
+            percentage = ((float)maxCount*100) / (float)jSize;
+            residueHash.put("pid_gaps", new Float(percentage) );
+
+            percentage = ((float)maxCount*100) / (float)nongap;
+            residueHash.put("pid_nogaps", new Float(percentage) );
+            result.addElement(residueHash);
+        }
+
+
+
+        return result;
+    }
+}
index 401ad01..f743dd2 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.analysis;\r
-\r
-import jalview.datamodel.SequenceI;\r
-\r
-import jalview.schemes.*;\r
-\r
-import jalview.util.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- *\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AlignSeq\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public static java.util.Hashtable dnaHash = new java.util.Hashtable();\r
-\r
-    static\r
-    {\r
-        dnaHash.put("C", new Integer(0));\r
-        dnaHash.put("T", new Integer(1));\r
-        dnaHash.put("A", new Integer(2));\r
-        dnaHash.put("G", new Integer(3));\r
-        dnaHash.put("-", new Integer(4));\r
-    }\r
-\r
-    static String[] dna = { "C", "T", "A", "G", "-" };\r
-    static String[] pep =\r
-    {\r
-        "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I", "L", "K", "M", "F",\r
-        "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "-"\r
-    };\r
-    int[][] score;\r
-    int[][] E;\r
-    int[][] F;\r
-    int[][] traceback;\r
-    int[] seq1;\r
-    int[] seq2;\r
-    SequenceI s1;\r
-    SequenceI s2;\r
-    String s1str;\r
-    String s2str;\r
-    int maxi;\r
-    int maxj;\r
-    int[] aseq1;\r
-    int[] aseq2;\r
-    public String astr1 = "";\r
-    public String astr2 = "";\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int seq1start;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int seq1end;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int seq2start;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int seq2end;\r
-    int count;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int maxscore;\r
-    float pid;\r
-    int prev = 0;\r
-    int gapOpen = 120;\r
-    int gapExtend = 20;\r
-    int[][] lookup = ResidueProperties.getBLOSUM62();\r
-    String[] intToStr = pep;\r
-    int defInt = 23;\r
-    StringBuffer output = new StringBuffer();\r
-    String type;\r
-    Runtime rt;\r
-\r
-\r
-    /**\r
-     * Creates a new AlignSeq object.\r
-     *\r
-     * @param s1 DOCUMENT ME!\r
-     * @param s2 DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     */\r
-    public AlignSeq(SequenceI s1, SequenceI s2, String type)\r
-    {\r
-        rt = Runtime.getRuntime();\r
-        SeqInit(s1, s2, type);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getMaxScore()\r
-    {\r
-        return maxscore;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getSeq2Start()\r
-    {\r
-        return seq2start;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getSeq2End()\r
-    {\r
-        return seq2end;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getSeq1Start()\r
-    {\r
-        return seq1start;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getSeq1End()\r
-    {\r
-        return seq1end;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getOutput()\r
-    {\r
-        return output.toString();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getAStr1()\r
-    {\r
-        return astr1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getAStr2()\r
-    {\r
-        return astr2;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int[] getASeq1()\r
-    {\r
-        return aseq1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int[] getASeq2()\r
-    {\r
-        return aseq2;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceI getS1()\r
-    {\r
-        return s1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceI getS2()\r
-    {\r
-        return s2;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s1 DOCUMENT ME!\r
-     * @param s2 DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     */\r
-    public void SeqInit(SequenceI s1, SequenceI s2, String type)\r
-    {\r
-        s1str = extractGaps(jalview.util.Comparison.GapChars, s1.getSequence());\r
-        s2str = extractGaps(jalview.util.Comparison.GapChars, s2.getSequence());\r
-\r
-        this.s1 = s1;\r
-        this.s2 = s2;\r
-\r
-        this.type = type;\r
-\r
-        if (type.equals("pep"))\r
-        {\r
-            lookup = ResidueProperties.getBLOSUM62();\r
-            intToStr = pep;\r
-            defInt = 23;\r
-        }\r
-        else if (type.equals("dna"))\r
-        {\r
-            lookup = ResidueProperties.getDNA();\r
-            intToStr = dna;\r
-            defInt = 4;\r
-        }\r
-        else\r
-        {\r
-            output.append("Wrong type = dna or pep only");\r
-            System.exit(0);\r
-        }\r
-\r
-        //System.out.println("lookuip " + rt.freeMemory() + " "+  rt.totalMemory());\r
-        seq1 = new int[s1str.length()];\r
-\r
-        //System.out.println("seq1 " + rt.freeMemory() +" "  + rt.totalMemory());\r
-        seq2 = new int[s2str.length()];\r
-\r
-        //System.out.println("seq2 " + rt.freeMemory() + " " + rt.totalMemory());\r
-        score = new int[s1str.length()][s2str.length()];\r
-\r
-        //System.out.println("score " + rt.freeMemory() + " " + rt.totalMemory());\r
-        E = new int[s1str.length()][s2str.length()];\r
-\r
-        //System.out.println("E " + rt.freeMemory() + " " + rt.totalMemory());\r
-        F = new int[s1str.length()][s2str.length()];\r
-        traceback = new int[s1str.length()][s2str.length()];\r
-\r
-        //System.out.println("F " + rt.freeMemory() + " " + rt.totalMemory());\r
-        seq1 = stringToInt(s1str, type);\r
-\r
-        //System.out.println("seq1 " + rt.freeMemory() + " " + rt.totalMemory());\r
-        seq2 = stringToInt(s2str, type);\r
-\r
-        //System.out.println("Seq2 " + rt.freeMemory() + " " + rt.totalMemory());\r
-        //   long tstart = System.currentTimeMillis();\r
-        //    calcScoreMatrix();\r
-        //long tend = System.currentTimeMillis();\r
-        //System.out.println("Time take to calculate score matrix = " + (tend-tstart) + " ms");\r
-        //   printScoreMatrix(score);\r
-        //System.out.println();\r
-        //printScoreMatrix(traceback);\r
-        //System.out.println();\r
-        //  printScoreMatrix(E);\r
-        //System.out.println();\r
-        ///printScoreMatrix(F);\r
-        //System.out.println();\r
-        // tstart = System.currentTimeMillis();\r
-        //traceAlignment();\r
-        //tend = System.currentTimeMillis();\r
-        //System.out.println("Time take to traceback alignment = " + (tend-tstart) + " ms");\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void traceAlignment()\r
-    {\r
-        // Find the maximum score along the rhs or bottom row\r
-        int max = -9999;\r
-\r
-        for (int i = 0; i < seq1.length; i++)\r
-        {\r
-            if (score[i][seq2.length - 1] > max)\r
-            {\r
-                max = score[i][seq2.length - 1];\r
-                maxi = i;\r
-                maxj = seq2.length - 1;\r
-            }\r
-        }\r
-\r
-        for (int j = 0; j < seq2.length; j++)\r
-        {\r
-            if (score[seq1.length - 1][j] > max)\r
-            {\r
-                max = score[seq1.length - 1][j];\r
-                maxi = seq1.length - 1;\r
-                maxj = j;\r
-            }\r
-        }\r
-\r
-        //  System.out.println(maxi + " " + maxj + " " + score[maxi][maxj]);\r
-        int i = maxi;\r
-        int j = maxj;\r
-        int trace;\r
-        maxscore = score[i][j] / 10;\r
-\r
-        seq1end = maxi + 1;\r
-        seq2end = maxj + 1;\r
-\r
-        aseq1 = new int[seq1.length + seq2.length];\r
-        aseq2 = new int[seq1.length + seq2.length];\r
-\r
-        count = (seq1.length + seq2.length) - 1;\r
-\r
-        while ((i > 0) && (j > 0))\r
-        {\r
-            if ((aseq1[count] != defInt) && (i >= 0))\r
-            {\r
-                aseq1[count] = seq1[i];\r
-                astr1 = intToStr[seq1[i]] + astr1;\r
-            }\r
-\r
-            if ((aseq2[count] != defInt) && (j > 0))\r
-            {\r
-                aseq2[count] = seq2[j];\r
-                astr2 = intToStr[seq2[j]] + astr2;\r
-            }\r
-\r
-            trace = findTrace(i, j);\r
-\r
-            if (trace == 0)\r
-            {\r
-                i--;\r
-                j--;\r
-            }\r
-            else if (trace == 1)\r
-            {\r
-                j--;\r
-                aseq1[count] = defInt;\r
-                astr1 = "-" + astr1.substring(1);\r
-            }\r
-            else if (trace == -1)\r
-            {\r
-                i--;\r
-                aseq2[count] = defInt;\r
-                astr2 = "-" + astr2.substring(1);\r
-            }\r
-\r
-            count--;\r
-        }\r
-\r
-        seq1start = i + 1;\r
-        seq2start = j + 1;\r
-\r
-        if (aseq1[count] != defInt)\r
-        {\r
-            aseq1[count] = seq1[i];\r
-            astr1 = intToStr[seq1[i]] + astr1;\r
-        }\r
-\r
-        if (aseq2[count] != defInt)\r
-        {\r
-            aseq2[count] = seq2[j];\r
-            astr2 = intToStr[seq2[j]] + astr2;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void printAlignment(java.io.PrintStream os)\r
-    {\r
-        // Find the biggest id length for formatting purposes\r
-        int maxid = s1.getName().length();\r
-\r
-        if (s2.getName().length() > maxid)\r
-        {\r
-            maxid = s2.getName().length();\r
-        }\r
-\r
-        int len = 72 - maxid - 1;\r
-        int nochunks = ((aseq1.length - count) / len) + 1;\r
-        pid = 0;\r
-\r
-        output.append("Score = " + score[maxi][maxj] + "\n");\r
-        output.append("Length of alignment = " + (aseq1.length - count) + "\n");\r
-        output.append("Sequence ");\r
-        output.append(new Format("%" + maxid + "s").form(s1.getName()));\r
-        output.append(" :  " + seq1start + " - " + seq1end + " (Sequence length = " +\r
-            s1str.length() + ")\n");\r
-        output .append("Sequence ");\r
-        output.append(new Format("%" + maxid + "s").form(s2.getName()));\r
-        output .append(" :  " + seq2start + " - " + seq2end + " (Sequence length = " +\r
-            s2str.length() + ")\n\n");\r
-\r
-        for (int j = 0; j < nochunks; j++)\r
-        {\r
-            // Print the first aligned sequence\r
-            output.append(new Format("%" + (maxid) + "s").form(s1.getName()) + " ");\r
-\r
-            for (int i = 0; i < len; i++)\r
-            {\r
-                if ((count + i + (j * len)) < aseq1.length)\r
-                {\r
-                    output.append(new Format("%s").form(intToStr[aseq1[count + i +\r
-                            (j * len)]]));\r
-                }\r
-            }\r
-\r
-            output.append("\n");\r
-            output.append(new Format("%" + (maxid) + "s").form(" ") + " ");\r
-\r
-            // Print out the matching chars\r
-            for (int i = 0; i < len; i++)\r
-            {\r
-                if ((count + i + (j * len)) < aseq1.length)\r
-                {\r
-                    if (intToStr[aseq1[count + i + (j * len)]].equals(\r
-                                intToStr[aseq2[count + i + (j * len)]]) &&\r
-                            !intToStr[aseq1[count + i + (j * len)]].equals("-"))\r
-                    {\r
-                        pid++;\r
-                        output.append("|");\r
-                    }\r
-                    else if (type.equals("pep"))\r
-                    {\r
-                        if (ResidueProperties.getPAM250(\r
-                                    intToStr[aseq1[count + i + (j * len)]],\r
-                                    intToStr[aseq2[count + i + (j * len)]]) > 0)\r
-                        {\r
-                            output.append(".");\r
-                        }\r
-                        else\r
-                        {\r
-                            output.append(" ");\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        output.append(" ");\r
-                    }\r
-                }\r
-            }\r
-\r
-            // Now print the second aligned sequence\r
-            output = output.append("\n");\r
-            output = output.append(new Format("%" + (maxid) + "s").form(s2.getName()) + " ");\r
-\r
-            for (int i = 0; i < len; i++)\r
-            {\r
-                if ((count + i + (j * len)) < aseq1.length)\r
-                {\r
-                    output .append(new Format("%s").form(intToStr[aseq2[count + i +\r
-                            (j * len)]]));\r
-                }\r
-            }\r
-\r
-            output = output .append("\n\n");\r
-        }\r
-\r
-        pid = pid / (float) (aseq1.length - count) * 100;\r
-        output = output.append(new Format("Percentage ID = %2.2f\n\n").form(pid));\r
-\r
-        try{\r
-          os.print(output.toString());\r
-        }catch(Exception ex){}\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param mat DOCUMENT ME!\r
-     */\r
-    public void printScoreMatrix(int[][] mat)\r
-    {\r
-        int n = seq1.length;\r
-        int m = seq2.length;\r
-\r
-        for (int i = 0; i < n; i++)\r
-        {\r
-            // Print the top sequence\r
-            if (i == 0)\r
-            {\r
-                Format.print(System.out, "%8s", s2str.substring(0, 1));\r
-\r
-                for (int jj = 1; jj < m; jj++)\r
-                {\r
-                    Format.print(System.out, "%5s", s2str.substring(jj, jj + 1));\r
-                }\r
-\r
-                System.out.println();\r
-            }\r
-\r
-            for (int j = 0; j < m; j++)\r
-            {\r
-                if (j == 0)\r
-                {\r
-                    Format.print(System.out, "%3s", s1str.substring(i, i + 1));\r
-                }\r
-\r
-                Format.print(System.out, "%3d ", mat[i][j] / 10);\r
-            }\r
-\r
-            System.out.println();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int findTrace(int i, int j)\r
-    {\r
-        int t = 0;\r
-        int max = score[i - 1][j - 1] + (lookup[seq1[i]][seq2[j]] * 10);\r
-\r
-        if (F[i][j] > max)\r
-        {\r
-            max = F[i][j];\r
-            t = -1;\r
-        }\r
-        else if (F[i][j] == max)\r
-        {\r
-            if (prev == -1)\r
-            {\r
-                max = F[i][j];\r
-                t = -1;\r
-            }\r
-        }\r
-\r
-        if (E[i][j] >= max)\r
-        {\r
-            max = E[i][j];\r
-            t = 1;\r
-        }\r
-        else if (E[i][j] == max)\r
-        {\r
-            if (prev == 1)\r
-            {\r
-                max = E[i][j];\r
-                t = 1;\r
-            }\r
-        }\r
-\r
-        prev = t;\r
-\r
-        return t;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void calcScoreMatrix()\r
-    {\r
-        int n = seq1.length;\r
-        int m = seq2.length;\r
-\r
-        // top left hand element\r
-        score[0][0] = lookup[seq1[0]][seq2[0]] * 10;\r
-        E[0][0] = -gapExtend;\r
-        F[0][0] = 0;\r
-\r
-        // Calculate the top row first\r
-        for (int j = 1; j < m; j++)\r
-        {\r
-            // What should these values be? 0 maybe\r
-            E[0][j] = max(score[0][j - 1] - gapOpen, E[0][j - 1] - gapExtend);\r
-            F[0][j] = -gapExtend;\r
-\r
-            score[0][j] = max(lookup[seq1[0]][seq2[j]] * 10, -gapOpen,\r
-                    -gapExtend);\r
-\r
-            traceback[0][j] = 1;\r
-        }\r
-\r
-        // Now do the left hand column\r
-        for (int i = 1; i < n; i++)\r
-        {\r
-            E[i][0] = -gapOpen;\r
-            F[i][0] = max(score[i - 1][0] - gapOpen, F[i - 1][0] - gapExtend);\r
-\r
-            score[i][0] = max(lookup[seq1[i]][seq2[0]] * 10, E[i][0], F[i][0]);\r
-            traceback[i][0] = -1;\r
-        }\r
-\r
-        // Now do all the other rows\r
-        for (int i = 1; i < n; i++)\r
-        {\r
-            for (int j = 1; j < m; j++)\r
-            {\r
-                E[i][j] = max(score[i][j - 1] - gapOpen, E[i][j - 1] -\r
-                        gapExtend);\r
-                F[i][j] = max(score[i - 1][j] - gapOpen, F[i - 1][j] -\r
-                        gapExtend);\r
-\r
-                score[i][j] = max(score[i - 1][j - 1] +\r
-                        (lookup[seq1[i]][seq2[j]] * 10), E[i][j], F[i][j]);\r
-                traceback[i][j] = findTrace(i, j);\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param gapChar DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static String extractGaps(String gapChar, String seq)\r
-    {\r
-        StringTokenizer str = new StringTokenizer(seq, gapChar);\r
-        StringBuffer newString = new StringBuffer();\r
-\r
-        while (str.hasMoreTokens())\r
-        {\r
-            newString.append( str.nextToken() );\r
-        }\r
-\r
-        return newString.toString();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i1 DOCUMENT ME!\r
-     * @param i2 DOCUMENT ME!\r
-     * @param i3 DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int max(int i1, int i2, int i3)\r
-    {\r
-        int max = i1;\r
-\r
-        if (i2 > i1)\r
-        {\r
-            max = i2;\r
-        }\r
-\r
-        if (i3 > max)\r
-        {\r
-            max = i3;\r
-        }\r
-\r
-        return max;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i1 DOCUMENT ME!\r
-     * @param i2 DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int max(int i1, int i2)\r
-    {\r
-        int max = i1;\r
-\r
-        if (i2 > i1)\r
-        {\r
-            max = i2;\r
-        }\r
-\r
-        return max;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int[] stringToInt(String s, String type)\r
-    {\r
-        int[] seq1 = new int[s.length()];\r
-\r
-        for (int i = 0; i < s.length(); i++)\r
-        {\r
-            String ss = s.substring(i, i + 1).toUpperCase();\r
-\r
-            try\r
-            {\r
-                if (type.equals("pep"))\r
-                {\r
-                    seq1[i] = ((Integer) ResidueProperties.aaHash.get(ss)).intValue();\r
-                }\r
-                else if (type.equals("dna"))\r
-                {\r
-                    seq1[i] = ((Integer) dnaHash.get(ss)).intValue();\r
-                }\r
-\r
-                if (seq1[i] > 23)\r
-                {\r
-                    seq1[i] = 23;\r
-                }\r
-            }\r
-            catch (Exception e)\r
-            {\r
-                if (type.equals("dna"))\r
-                {\r
-                    seq1[i] = 4;\r
-                }\r
-                else\r
-                {\r
-                    seq1[i] = 23;\r
-                }\r
-            }\r
-        }\r
-\r
-        return seq1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param mat DOCUMENT ME!\r
-     * @param n DOCUMENT ME!\r
-     * @param m DOCUMENT ME!\r
-     * @param psize DOCUMENT ME!\r
-     */\r
-    public static void displayMatrix(Graphics g, int[][] mat, int n, int m,\r
-        int psize)\r
-    {\r
-        int max = -1000;\r
-        int min = 1000;\r
-\r
-        for (int i = 0; i < n; i++)\r
-        {\r
-            for (int j = 0; j < m; j++)\r
-            {\r
-                if (mat[i][j] >= max)\r
-                {\r
-                    max = mat[i][j];\r
-                }\r
-\r
-                if (mat[i][j] <= min)\r
-                {\r
-                    min = mat[i][j];\r
-                }\r
-            }\r
-        }\r
-\r
-        System.out.println(max + " " + min);\r
-\r
-        for (int i = 0; i < n; i++)\r
-        {\r
-            for (int j = 0; j < m; j++)\r
-            {\r
-                int x = psize * i;\r
-                int y = psize * j;\r
-\r
-                //     System.out.println(mat[i][j]);\r
-                float score = (float) (mat[i][j] - min) / (float) (max - min);\r
-                g.setColor(new Color(score, 0, 0));\r
-                g.fillRect(x, y, psize, psize);\r
-\r
-                //     System.out.println(x + " " + y + " " + score);\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.analysis;
+
+import jalview.datamodel.SequenceI;
+
+import jalview.schemes.*;
+
+import jalview.util.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+
+/**
+ *
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AlignSeq
+{
+    /** DOCUMENT ME!! */
+    public static java.util.Hashtable dnaHash = new java.util.Hashtable();
+
+    static
+    {
+        dnaHash.put("C", new Integer(0));
+        dnaHash.put("T", new Integer(1));
+        dnaHash.put("A", new Integer(2));
+        dnaHash.put("G", new Integer(3));
+        dnaHash.put("-", new Integer(4));
+    }
+
+    static String[] dna = { "C", "T", "A", "G", "-" };
+    static String[] pep =
+    {
+        "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I", "L", "K", "M", "F",
+        "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "-"
+    };
+    int[][] score;
+    int[][] E;
+    int[][] F;
+    int[][] traceback;
+    int[] seq1;
+    int[] seq2;
+    SequenceI s1;
+    SequenceI s2;
+    public String s1str;
+    public String s2str;
+    int maxi;
+    int maxj;
+    int[] aseq1;
+    int[] aseq2;
+    public String astr1="";
+    public String astr2="";
+
+    /** DOCUMENT ME!! */
+    public int seq1start;
+
+    /** DOCUMENT ME!! */
+    public int seq1end;
+
+    /** DOCUMENT ME!! */
+    public int seq2start;
+
+    /** DOCUMENT ME!! */
+    public int seq2end;
+    int count;
+
+    /** DOCUMENT ME!! */
+    public int maxscore;
+    float pid;
+    int prev = 0;
+    int gapOpen = 120;
+    int gapExtend = 20;
+    int[][] lookup = ResidueProperties.getBLOSUM62();
+    String[] intToStr = pep;
+    int defInt = 23;
+    StringBuffer output = new StringBuffer();
+    String type;
+
+    /**
+     * Creates a new AlignSeq object.
+     *
+     * @param s1 DOCUMENT ME!
+     * @param s2 DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     */
+    public AlignSeq(SequenceI s1, SequenceI s2, String type)
+    {
+        SeqInit(s1, s1.getSequence(), s2,  s2.getSequence(), type);
+    }
+
+    /**
+     * Creates a new AlignSeq object.
+     *
+     * @param s1 DOCUMENT ME!
+     * @param s2 DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     */
+    public AlignSeq(SequenceI s1,
+                    String string1,
+                    SequenceI s2,
+                    String string2,
+                    String type)
+    {
+        SeqInit(s1, string1, s2,  string2,  type);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getMaxScore()
+    {
+        return maxscore;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getSeq2Start()
+    {
+        return seq2start;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getSeq2End()
+    {
+        return seq2end;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getSeq1Start()
+    {
+        return seq1start;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getSeq1End()
+    {
+        return seq1end;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getOutput()
+    {
+        return output.toString();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getAStr1()
+    {
+        return astr1;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getAStr2()
+    {
+        return astr2;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int[] getASeq1()
+    {
+        return aseq1;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int[] getASeq2()
+    {
+        return aseq2;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceI getS1()
+    {
+        return s1;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceI getS2()
+    {
+        return s2;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s1 DOCUMENT ME!
+     * @param s2 DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     */
+    public void SeqInit(SequenceI s1,
+                        String string1,
+                        SequenceI s2,
+                        String string2,
+                        String type)
+    {
+
+        s1str = extractGaps(jalview.util.Comparison.GapChars, string1);
+        s2str = extractGaps(jalview.util.Comparison.GapChars, string2);
+
+        if(s1str.length()==0 || s2str.length()==0)
+        {
+          System.out.println("ALL GAPS: " +
+                             (s1str.length()==0?s1.getName():" ")
+                             +(s2str.length()==0?s2.getName():""));
+          return;
+        }
+
+        this.s1 = s1;
+        this.s2 = s2;
+
+        this.type = type;
+
+        if (type.equals("pep"))
+        {
+            lookup = ResidueProperties.getBLOSUM62();
+            intToStr = pep;
+            defInt = 23;
+        }
+        else if (type.equals("dna"))
+        {
+            lookup = ResidueProperties.getDNA();
+            intToStr = dna;
+            defInt = 4;
+        }
+        else
+        {
+            output.append("Wrong type = dna or pep only");
+            System.exit(0);
+        }
+
+        //System.out.println("lookuip " + rt.freeMemory() + " "+  rt.totalMemory());
+        seq1 = new int[s1str.length()];
+
+        //System.out.println("seq1 " + rt.freeMemory() +" "  + rt.totalMemory());
+        seq2 = new int[s2str.length()];
+
+        //System.out.println("seq2 " + rt.freeMemory() + " " + rt.totalMemory());
+        score = new int[s1str.length()][s2str.length()];
+
+        //System.out.println("score " + rt.freeMemory() + " " + rt.totalMemory());
+        E = new int[s1str.length()][s2str.length()];
+
+        //System.out.println("E " + rt.freeMemory() + " " + rt.totalMemory());
+        F = new int[s1str.length()][s2str.length()];
+        traceback = new int[s1str.length()][s2str.length()];
+
+        //System.out.println("F " + rt.freeMemory() + " " + rt.totalMemory());
+        seq1 = stringToInt(s1str, type);
+
+        //System.out.println("seq1 " + rt.freeMemory() + " " + rt.totalMemory());
+        seq2 = stringToInt(s2str, type);
+
+        //System.out.println("Seq2 " + rt.freeMemory() + " " + rt.totalMemory());
+        //   long tstart = System.currentTimeMillis();
+        //    calcScoreMatrix();
+        //long tend = System.currentTimeMillis();
+        //System.out.println("Time take to calculate score matrix = " + (tend-tstart) + " ms");
+        //   printScoreMatrix(score);
+        //System.out.println();
+        //printScoreMatrix(traceback);
+        //System.out.println();
+        //  printScoreMatrix(E);
+        //System.out.println();
+        ///printScoreMatrix(F);
+        //System.out.println();
+        // tstart = System.currentTimeMillis();
+        //traceAlignment();
+        //tend = System.currentTimeMillis();
+        //System.out.println("Time take to traceback alignment = " + (tend-tstart) + " ms");
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void traceAlignment()
+    {
+        // Find the maximum score along the rhs or bottom row
+        int max = -9999;
+
+        for (int i = 0; i < seq1.length; i++)
+        {
+            if (score[i][seq2.length - 1] > max)
+            {
+                max = score[i][seq2.length - 1];
+                maxi = i;
+                maxj = seq2.length - 1;
+            }
+        }
+
+        for (int j = 0; j < seq2.length; j++)
+        {
+            if (score[seq1.length - 1][j] > max)
+            {
+                max = score[seq1.length - 1][j];
+                maxi = seq1.length - 1;
+                maxj = j;
+            }
+        }
+
+        //  System.out.println(maxi + " " + maxj + " " + score[maxi][maxj]);
+        int i = maxi;
+        int j = maxj;
+        int trace;
+        maxscore = score[i][j] / 10;
+
+        seq1end = maxi + 1;
+        seq2end = maxj + 1;
+
+        aseq1 = new int[seq1.length + seq2.length];
+        aseq2 = new int[seq1.length + seq2.length];
+
+        count = (seq1.length + seq2.length) - 1;
+
+        while ((i > 0) && (j > 0))
+        {
+            if ((aseq1[count] != defInt) && (i >= 0))
+            {
+                aseq1[count] = seq1[i];
+                astr1 = intToStr[seq1[i]] + astr1;
+            }
+
+            if ((aseq2[count] != defInt) && (j > 0))
+            {
+                aseq2[count] = seq2[j];
+                astr2 = intToStr[seq2[j]] + astr2;
+            }
+
+            trace = findTrace(i, j);
+
+            if (trace == 0)
+            {
+                i--;
+                j--;
+            }
+            else if (trace == 1)
+            {
+                j--;
+                aseq1[count] = defInt;
+                astr1 = "-" + astr1.substring(1);
+            }
+            else if (trace == -1)
+            {
+                i--;
+                aseq2[count] = defInt;
+                astr2 = "-" + astr2.substring(1);
+            }
+
+            count--;
+        }
+
+        seq1start = i + 1;
+        seq2start = j + 1;
+
+        if (aseq1[count] != defInt)
+        {
+            aseq1[count] = seq1[i];
+            astr1 = intToStr[seq1[i]] + astr1;
+        }
+
+        if (aseq2[count] != defInt)
+        {
+            aseq2[count] = seq2[j];
+            astr2 = intToStr[seq2[j]] + astr2;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void printAlignment(java.io.PrintStream os)
+    {
+        // Find the biggest id length for formatting purposes
+        int maxid = s1.getName().length();
+
+        if (s2.getName().length() > maxid)
+        {
+            maxid = s2.getName().length();
+        }
+
+        int len = 72 - maxid - 1;
+        int nochunks = ((aseq1.length - count) / len) + 1;
+        pid = 0;
+
+        output.append("Score = " + score[maxi][maxj] + "\n");
+        output.append("Length of alignment = " + (aseq1.length - count) + "\n");
+        output.append("Sequence ");
+        output.append(new Format("%" + maxid + "s").form(s1.getName()));
+        output.append(" :  " + s1.getStart() + " - " + s1.getEnd() + " (Sequence length = " +
+            s1str.length() + ")\n");
+        output .append("Sequence ");
+        output.append(new Format("%" + maxid + "s").form(s2.getName()));
+        output.append(" :  " + s2.getStart() + " - " + s2.getEnd() + " (Sequence length = " +
+            s2str.length() + ")\n\n");
+
+        for (int j = 0; j < nochunks; j++)
+        {
+            // Print the first aligned sequence
+            output.append(new Format("%" + (maxid) + "s").form(s1.getName()) + " ");
+
+            for (int i = 0; i < len; i++)
+            {
+                if ((count + i + (j * len)) < aseq1.length)
+                {
+                    output.append(new Format("%s").form(intToStr[aseq1[count + i +
+                            (j * len)]]));
+                }
+            }
+
+            output.append("\n");
+            output.append(new Format("%" + (maxid) + "s").form(" ") + " ");
+
+            // Print out the matching chars
+            for (int i = 0; i < len; i++)
+            {
+                if ((count + i + (j * len)) < aseq1.length)
+                {
+                    if (intToStr[aseq1[count + i + (j * len)]].equals(
+                                intToStr[aseq2[count + i + (j * len)]]) &&
+                            !intToStr[aseq1[count + i + (j * len)]].equals("-"))
+                    {
+                        pid++;
+                        output.append("|");
+                    }
+                    else if (type.equals("pep"))
+                    {
+                        if (ResidueProperties.getPAM250(
+                                    intToStr[aseq1[count + i + (j * len)]],
+                                    intToStr[aseq2[count + i + (j * len)]]) > 0)
+                        {
+                            output.append(".");
+                        }
+                        else
+                        {
+                            output.append(" ");
+                        }
+                    }
+                    else
+                    {
+                        output.append(" ");
+                    }
+                }
+            }
+
+            // Now print the second aligned sequence
+            output = output.append("\n");
+            output = output.append(new Format("%" + (maxid) + "s").form(s2.getName()) + " ");
+
+            for (int i = 0; i < len; i++)
+            {
+                if ((count + i + (j * len)) < aseq1.length)
+                {
+                    output .append(new Format("%s").form(intToStr[aseq2[count + i +
+                            (j * len)]]));
+                }
+            }
+
+            output = output .append("\n\n");
+        }
+
+        pid = pid / (float) (aseq1.length - count) * 100;
+        output = output.append(new Format("Percentage ID = %2.2f\n\n").form(pid));
+
+        try{
+          os.print(output.toString());
+        }catch(Exception ex){}
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param mat DOCUMENT ME!
+     */
+    public void printScoreMatrix(int[][] mat)
+    {
+        int n = seq1.length;
+        int m = seq2.length;
+
+        for (int i = 0; i < n; i++)
+        {
+            // Print the top sequence
+            if (i == 0)
+            {
+                Format.print(System.out, "%8s", s2str.substring(0, 1));
+
+                for (int jj = 1; jj < m; jj++)
+                {
+                    Format.print(System.out, "%5s", s2str.substring(jj, jj + 1));
+                }
+
+                System.out.println();
+            }
+
+            for (int j = 0; j < m; j++)
+            {
+                if (j == 0)
+                {
+                    Format.print(System.out, "%3s", s1str.substring(i, i + 1));
+                }
+
+                Format.print(System.out, "%3d ", mat[i][j] / 10);
+            }
+
+            System.out.println();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int findTrace(int i, int j)
+    {
+        int t = 0;
+        int max = score[i - 1][j - 1] + (lookup[seq1[i]][seq2[j]] * 10);
+
+        if (F[i][j] > max)
+        {
+            max = F[i][j];
+            t = -1;
+        }
+        else if (F[i][j] == max)
+        {
+            if (prev == -1)
+            {
+                max = F[i][j];
+                t = -1;
+            }
+        }
+
+        if (E[i][j] >= max)
+        {
+            max = E[i][j];
+            t = 1;
+        }
+        else if (E[i][j] == max)
+        {
+            if (prev == 1)
+            {
+                max = E[i][j];
+                t = 1;
+            }
+        }
+
+        prev = t;
+
+        return t;
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void calcScoreMatrix()
+    {
+        int n = seq1.length;
+        int m = seq2.length;
+
+        // top left hand element
+        score[0][0] = lookup[seq1[0]][seq2[0]] * 10;
+        E[0][0] = -gapExtend;
+        F[0][0] = 0;
+
+        // Calculate the top row first
+        for (int j = 1; j < m; j++)
+        {
+            // What should these values be? 0 maybe
+            E[0][j] = max(score[0][j - 1] - gapOpen, E[0][j - 1] - gapExtend);
+            F[0][j] = -gapExtend;
+
+            score[0][j] = max(lookup[seq1[0]][seq2[j]] * 10, -gapOpen,
+                    -gapExtend);
+
+            traceback[0][j] = 1;
+        }
+
+        // Now do the left hand column
+        for (int i = 1; i < n; i++)
+        {
+            E[i][0] = -gapOpen;
+            F[i][0] = max(score[i - 1][0] - gapOpen, F[i - 1][0] - gapExtend);
+
+            score[i][0] = max(lookup[seq1[i]][seq2[0]] * 10, E[i][0], F[i][0]);
+            traceback[i][0] = -1;
+        }
+
+        // Now do all the other rows
+        for (int i = 1; i < n; i++)
+        {
+            for (int j = 1; j < m; j++)
+            {
+                E[i][j] = max(score[i][j - 1] - gapOpen, E[i][j - 1] -
+                        gapExtend);
+                F[i][j] = max(score[i - 1][j] - gapOpen, F[i - 1][j] -
+                        gapExtend);
+
+                score[i][j] = max(score[i - 1][j - 1] +
+                        (lookup[seq1[i]][seq2[j]] * 10), E[i][j], F[i][j]);
+                traceback[i][j] = findTrace(i, j);
+            }
+        }
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param gapChar DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static String extractGaps(String gapChar, String seq)
+    {
+        StringTokenizer str = new StringTokenizer(seq, gapChar);
+        StringBuffer newString = new StringBuffer();
+
+        while (str.hasMoreTokens())
+        {
+            newString.append( str.nextToken() );
+        }
+
+        return newString.toString();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i1 DOCUMENT ME!
+     * @param i2 DOCUMENT ME!
+     * @param i3 DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int max(int i1, int i2, int i3)
+    {
+        int max = i1;
+
+        if (i2 > i1)
+        {
+            max = i2;
+        }
+
+        if (i3 > max)
+        {
+            max = i3;
+        }
+
+        return max;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i1 DOCUMENT ME!
+     * @param i2 DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int max(int i1, int i2)
+    {
+        int max = i1;
+
+        if (i2 > i1)
+        {
+            max = i2;
+        }
+
+        return max;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int[] stringToInt(String s, String type)
+    {
+        int[] seq1 = new int[s.length()];
+
+        for (int i = 0; i < s.length(); i++)
+        {
+            String ss = s.substring(i, i + 1).toUpperCase();
+
+            try
+            {
+                if (type.equals("pep"))
+                {
+                    seq1[i] = ((Integer) ResidueProperties.aaHash.get(ss)).intValue();
+                }
+                else if (type.equals("dna"))
+                {
+                    seq1[i] = ((Integer) dnaHash.get(ss)).intValue();
+                }
+
+                if (seq1[i] > 23)
+                {
+                    seq1[i] = 23;
+                }
+            }
+            catch (Exception e)
+            {
+                if (type.equals("dna"))
+                {
+                    seq1[i] = 4;
+                }
+                else
+                {
+                    seq1[i] = 23;
+                }
+            }
+        }
+
+        return seq1;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param mat DOCUMENT ME!
+     * @param n DOCUMENT ME!
+     * @param m DOCUMENT ME!
+     * @param psize DOCUMENT ME!
+     */
+    public static void displayMatrix(Graphics g, int[][] mat, int n, int m,
+        int psize)
+    {
+        int max = -1000;
+        int min = 1000;
+
+        for (int i = 0; i < n; i++)
+        {
+            for (int j = 0; j < m; j++)
+            {
+                if (mat[i][j] >= max)
+                {
+                    max = mat[i][j];
+                }
+
+                if (mat[i][j] <= min)
+                {
+                    min = mat[i][j];
+                }
+            }
+        }
+
+        System.out.println(max + " " + min);
+
+        for (int i = 0; i < n; i++)
+        {
+            for (int j = 0; j < m; j++)
+            {
+                int x = psize * i;
+                int y = psize * j;
+
+                //     System.out.println(mat[i][j]);
+                float score = (float) (mat[i][j] - min) / (float) (max - min);
+                g.setColor(new Color(score, 0, 0));
+                g.fillRect(x, y, psize, psize);
+
+                //     System.out.println(x + " " + y + " " + score);
+            }
+        }
+    }
+}
index 20101dc..507d38b 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.analysis;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.util.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/** Data structure to hold and manipulate a multiple sequence alignment\r
- */\r
-public class AlignmentSorter\r
-{\r
-    static boolean sortIdAscending = true;\r
-    static int lastGroupHash = 0;\r
-    static boolean sortGroupAscending = true;\r
-    static AlignmentOrder lastOrder = null;\r
-    static boolean sortOrderAscending = true;\r
-    static NJTree lastTree = null;\r
-    static boolean sortTreeAscending = true;\r
-\r
-    /**\r
-     * Sort by Percentage Identity\r
-     *\r
-     * @param align AlignmentI\r
-     * @param s SequenceI\r
-     */\r
-    public static void sortByPID(AlignmentI align, SequenceI s)\r
-    {\r
-        int nSeq = align.getHeight();\r
-\r
-        float[] scores = new float[nSeq];\r
-        SequenceI[] seqs = new SequenceI[nSeq];\r
-\r
-        for (int i = 0; i < nSeq; i++)\r
-        {\r
-            scores[i] = Comparison.PID(align.getSequenceAt(i), s);\r
-            seqs[i] = align.getSequenceAt(i);\r
-        }\r
-\r
-        QuickSort.sort(scores, 0, scores.length - 1, seqs);\r
-\r
-        setReverseOrder(align, seqs);\r
-    }\r
-\r
-    /**\r
-     * Reverse the order of the sort\r
-     *\r
-     * @param align DOCUMENT ME!\r
-     * @param seqs DOCUMENT ME!\r
-     */\r
-    private static void setReverseOrder(AlignmentI align, SequenceI[] seqs)\r
-    {\r
-        int nSeq = seqs.length;\r
-\r
-        int len = 0;\r
-\r
-        if ((nSeq % 2) == 0)\r
-        {\r
-            len = nSeq / 2;\r
-        }\r
-        else\r
-        {\r
-            len = (nSeq + 1) / 2;\r
-        }\r
-\r
-        // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work\r
-        for (int i = 0; i < len; i++)\r
-        {\r
-            //SequenceI tmp = seqs[i];\r
-            align.getSequences().setElementAt(seqs[nSeq - i - 1], i);\r
-            align.getSequences().setElementAt(seqs[i], nSeq - i - 1);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sets the Alignment object with the given sequences\r
-     *\r
-     * @param align Alignment object to be updated\r
-     * @param tmp sequences as a vector\r
-     */\r
-    private static void setOrder(AlignmentI align, Vector tmp)\r
-    {\r
-        setOrder(align, vectorSubsetToArray(tmp, align.getSequences()));\r
-    }\r
-\r
-    /**\r
-     * Sets the Alignment object with the given sequences\r
-     *\r
-     * @param align DOCUMENT ME!\r
-     * @param seqs sequences as an array\r
-     */\r
-    private static void setOrder(AlignmentI align, SequenceI[] seqs)\r
-    {\r
-        // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work\r
-        Vector algn = align.getSequences();\r
-\r
-        for (int i = 0; i < seqs.length; i++)\r
-        {\r
-            algn.setElementAt(seqs[i], i);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sorts by ID. Numbers are sorted before letters.\r
-     *\r
-     * @param align The alignment object to sort\r
-     */\r
-    public static void sortByID(AlignmentI align)\r
-    {\r
-        int nSeq = align.getHeight();\r
-\r
-        String[] ids = new String[nSeq];\r
-        SequenceI[] seqs = new SequenceI[nSeq];\r
-\r
-        for (int i = 0; i < nSeq; i++)\r
-        {\r
-            ids[i] = align.getSequenceAt(i).getName();\r
-            seqs[i] = align.getSequenceAt(i);\r
-        }\r
-\r
-        QuickSort.sort(ids, seqs);\r
-\r
-        if (sortIdAscending)\r
-        {\r
-            setReverseOrder(align, seqs);\r
-        }\r
-        else\r
-        {\r
-            setOrder(align, seqs);\r
-        }\r
-\r
-        sortIdAscending = !sortIdAscending;\r
-    }\r
-\r
-    /**\r
-     * Sorts the alignment by size of group.\r
-     * <br>Maintains the order of sequences in each group\r
-     * by order in given alignment object.\r
-     *\r
-     * @param align sorts the given alignment object by group\r
-     */\r
-    public static void sortByGroup(AlignmentI align)\r
-    {\r
-        //MAINTAINS ORIGNAL SEQUENCE ORDER,\r
-        //ORDERS BY GROUP SIZE\r
-        Vector groups = new Vector();\r
-\r
-        if (groups.hashCode() != lastGroupHash)\r
-        {\r
-            sortGroupAscending = true;\r
-            lastGroupHash = groups.hashCode();\r
-        }\r
-        else\r
-        {\r
-            sortGroupAscending = !sortGroupAscending;\r
-        }\r
-\r
-        //SORTS GROUPS BY SIZE\r
-        //////////////////////\r
-        for (int i = 0; i < align.getGroups().size(); i++)\r
-        {\r
-            SequenceGroup sg = (SequenceGroup) align.getGroups().elementAt(i);\r
-\r
-            for (int j = 0; j < groups.size(); j++)\r
-            {\r
-                SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j);\r
-\r
-                if (sg.getSize() > sg2.getSize())\r
-                {\r
-                    groups.insertElementAt(sg, j);\r
-\r
-                    break;\r
-                }\r
-            }\r
-\r
-            if (!groups.contains(sg))\r
-            {\r
-                groups.addElement(sg);\r
-            }\r
-        }\r
-\r
-        //NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER\r
-        ///////////////////////////////////////////////\r
-        Vector seqs = new Vector();\r
-\r
-        for (int i = 0; i < groups.size(); i++)\r
-        {\r
-            SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-            SequenceI[] orderedseqs = sg.getSequencesInOrder(align);\r
-\r
-            for (int j = 0; j < orderedseqs.length; j++)\r
-            {\r
-                seqs.addElement(orderedseqs[j]);\r
-            }\r
-        }\r
-\r
-        if (sortGroupAscending)\r
-        {\r
-            setOrder(align, seqs);\r
-        }\r
-        else\r
-        {\r
-            setReverseOrder(align,\r
-                vectorSubsetToArray(seqs, align.getSequences()));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Converts Vector to array.\r
-     * java 1.18 does not have Vector.toArray()\r
-     *\r
-     * @param tmp Vector of SequenceI objects\r
-     *\r
-     * @return array of Sequence[]\r
-     */\r
-    private static SequenceI[] vectorToArray(Vector tmp)\r
-    {\r
-        SequenceI[] seqs = new SequenceI[tmp.size()];\r
-\r
-        for (int i = 0; i < tmp.size(); i++)\r
-        {\r
-            seqs[i] = (SequenceI) tmp.elementAt(i);\r
-        }\r
-\r
-        return seqs;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param tmp DOCUMENT ME!\r
-     * @param mask DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private static SequenceI[] vectorSubsetToArray(Vector tmp, Vector mask)\r
-    {\r
-        Vector seqs = new Vector();\r
-        int i;\r
-        boolean[] tmask = new boolean[mask.size()];\r
-\r
-        for (i = 0; i < mask.size(); i++)\r
-            tmask[i] = true;\r
-\r
-        for (i = 0; i < tmp.size(); i++)\r
-        {\r
-            Object sq = tmp.elementAt(i);\r
-\r
-            if (mask.contains(sq) && tmask[mask.indexOf(sq)])\r
-            {\r
-                tmask[mask.indexOf(sq)] = false;\r
-                seqs.addElement(sq);\r
-            }\r
-        }\r
-\r
-        for (i = 0; i < tmask.length; i++)\r
-            if (tmask[i])\r
-            {\r
-                seqs.addElement(mask.elementAt(i));\r
-            }\r
-\r
-        return vectorToArray(seqs);\r
-    }\r
-\r
-    /**\r
-     * Sorts by a given AlignmentOrder object\r
-     *\r
-     * @param align Alignment to order\r
-     * @param order specified order for alignment\r
-     */\r
-    public static void sortBy(AlignmentI align, AlignmentOrder order)\r
-    {\r
-        // Get an ordered vector of sequences which may also be present in align\r
-        Vector tmp = order.getOrder();\r
-\r
-        if (lastOrder == order)\r
-        {\r
-            sortOrderAscending = !sortOrderAscending;\r
-        }\r
-        else\r
-        {\r
-            sortOrderAscending = true;\r
-        }\r
-\r
-        if (sortOrderAscending)\r
-        {\r
-            setOrder(align, tmp);\r
-        }\r
-        else\r
-        {\r
-            setReverseOrder(align,\r
-                vectorSubsetToArray(tmp, align.getSequences()));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param align alignment to order\r
-     * @param tree tree which has\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private static Vector getOrderByTree(AlignmentI align, NJTree tree)\r
-    {\r
-        int nSeq = align.getHeight();\r
-\r
-        Vector tmp = new Vector();\r
-\r
-        tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());\r
-\r
-        if (tmp.size() != nSeq)\r
-        {\r
-            // TODO: JBPNote - decide if this is always an error\r
-            // (eg. not when a tree is associated to another alignment which has more\r
-            //  sequences)\r
-            if (tmp.size() < nSeq)\r
-            {\r
-                addStrays(align, tmp);\r
-            }\r
-\r
-            if (tmp.size() != nSeq)\r
-            {\r
-                System.err.println("ERROR: tmp.size()=" + tmp.size() +\r
-                    " != nseq=" + nSeq + " in getOrderByTree");\r
-            }\r
-        }\r
-\r
-        return tmp;\r
-    }\r
-\r
-    /**\r
-     * Sorts the alignment by a given tree\r
-     *\r
-     * @param align alignment to order\r
-     * @param tree tree which has\r
-     */\r
-    public static void sortByTree(AlignmentI align, NJTree tree)\r
-    {\r
-        Vector tmp = getOrderByTree(align, tree);\r
-\r
-        // tmp should properly permute align with tree.\r
-        if (lastTree != tree)\r
-        {\r
-            sortTreeAscending = true;\r
-            lastTree = tree;\r
-        }\r
-        else\r
-        {\r
-            sortTreeAscending = !sortTreeAscending;\r
-        }\r
-\r
-        if (sortTreeAscending)\r
-        {\r
-            setOrder(align, tmp);\r
-        }\r
-        else\r
-        {\r
-            setReverseOrder(align,\r
-                vectorSubsetToArray(tmp, align.getSequences()));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param align DOCUMENT ME!\r
-     * @param seqs DOCUMENT ME!\r
-     */\r
-    private static void addStrays(AlignmentI align, Vector seqs)\r
-    {\r
-        int nSeq = align.getHeight();\r
-\r
-        for (int i = 0; i < nSeq; i++)\r
-        {\r
-            if (!seqs.contains(align.getSequenceAt(i)))\r
-            {\r
-                seqs.addElement(align.getSequenceAt(i));\r
-            }\r
-        }\r
-\r
-        if (nSeq != seqs.size())\r
-        {\r
-            System.err.println(\r
-                "ERROR: Size still not right even after addStrays");\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param tmp DOCUMENT ME!\r
-     * @param seqset DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private static Vector _sortByTree(SequenceNode node, Vector tmp,\r
-        Vector seqset)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return tmp;\r
-        }\r
-\r
-        SequenceNode left = (SequenceNode) node.left();\r
-        SequenceNode right = (SequenceNode) node.right();\r
-\r
-        if ((left == null) && (right == null))\r
-        {\r
-            if (!node.isPlaceholder() && (node.element() != null))\r
-            {\r
-                if (node.element() instanceof SequenceI)\r
-                {\r
-                    if (!tmp.contains(node.element()))\r
-                    {\r
-                        tmp.addElement((SequenceI) node.element());\r
-                    }\r
-                }\r
-            }\r
-\r
-            return tmp;\r
-        }\r
-        else\r
-        {\r
-            _sortByTree(left, tmp, seqset);\r
-            _sortByTree(right, tmp, seqset);\r
-        }\r
-\r
-        return tmp;\r
-    }\r
-\r
-    // Ordering Objects\r
-    // Alignment.sortBy(OrderObj) - sequence of sequence pointer refs in appropriate order\r
-    //\r
-\r
-    /**\r
-     * recover the order of sequences given by the safe numbering scheme introducd\r
-     * SeqsetUtils.uniquify.\r
-     */\r
-    public static void recoverOrder(SequenceI[] alignment)\r
-    {\r
-        float[] ids = new float[alignment.length];\r
-\r
-        for (int i = 0; i < alignment.length; i++)\r
-            ids[i] = (new Float(alignment[i].getName().substring(8))).floatValue();\r
-\r
-        jalview.util.QuickSort.sort(ids, alignment);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.analysis;
+
+import jalview.datamodel.*;
+
+import jalview.util.*;
+
+import java.util.*;
+
+
+/** Data structure to hold and manipulate a multiple sequence alignment
+ */
+public class AlignmentSorter
+{
+    static boolean sortIdAscending = true;
+    static int lastGroupHash = 0;
+    static boolean sortGroupAscending = true;
+    static AlignmentOrder lastOrder = null;
+    static boolean sortOrderAscending = true;
+    static NJTree lastTree = null;
+    static boolean sortTreeAscending = true;
+
+    /**
+     * Sort by Percentage Identity
+     *
+     * @param align AlignmentI
+     * @param s SequenceI
+     */
+    public static void sortByPID(AlignmentI align, SequenceI s)
+    {
+        int nSeq = align.getHeight();
+
+        float[] scores = new float[nSeq];
+        SequenceI[] seqs = new SequenceI[nSeq];
+
+        for (int i = 0; i < nSeq; i++)
+        {
+            scores[i] = Comparison.PID(align.getSequenceAt(i).getSequence(),
+                                       s.getSequence());
+            seqs[i] = align.getSequenceAt(i);
+        }
+
+        QuickSort.sort(scores, 0, scores.length - 1, seqs);
+
+        setReverseOrder(align, seqs);
+    }
+
+    /**
+     * Reverse the order of the sort
+     *
+     * @param align DOCUMENT ME!
+     * @param seqs DOCUMENT ME!
+     */
+    private static void setReverseOrder(AlignmentI align, SequenceI[] seqs)
+    {
+        int nSeq = seqs.length;
+
+        int len = 0;
+
+        if ((nSeq % 2) == 0)
+        {
+            len = nSeq / 2;
+        }
+        else
+        {
+            len = (nSeq + 1) / 2;
+        }
+
+        // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
+        for (int i = 0; i < len; i++)
+        {
+            //SequenceI tmp = seqs[i];
+            align.getSequences().setElementAt(seqs[nSeq - i - 1], i);
+            align.getSequences().setElementAt(seqs[i], nSeq - i - 1);
+        }
+    }
+
+    /**
+     * Sets the Alignment object with the given sequences
+     *
+     * @param align Alignment object to be updated
+     * @param tmp sequences as a vector
+     */
+    private static void setOrder(AlignmentI align, Vector tmp)
+    {
+        setOrder(align, vectorSubsetToArray(tmp, align.getSequences()));
+    }
+
+    /**
+     * Sets the Alignment object with the given sequences
+     *
+     * @param align DOCUMENT ME!
+     * @param seqs sequences as an array
+     */
+    private static void setOrder(AlignmentI align, SequenceI[] seqs)
+    {
+        // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
+        Vector algn = align.getSequences();
+
+        for (int i = 0; i < seqs.length; i++)
+        {
+            algn.setElementAt(seqs[i], i);
+        }
+    }
+
+    /**
+     * Sorts by ID. Numbers are sorted before letters.
+     *
+     * @param align The alignment object to sort
+     */
+    public static void sortByID(AlignmentI align)
+    {
+        int nSeq = align.getHeight();
+
+        String[] ids = new String[nSeq];
+        SequenceI[] seqs = new SequenceI[nSeq];
+
+        for (int i = 0; i < nSeq; i++)
+        {
+            ids[i] = align.getSequenceAt(i).getName();
+            seqs[i] = align.getSequenceAt(i);
+        }
+
+        QuickSort.sort(ids, seqs);
+
+        if (sortIdAscending)
+        {
+            setReverseOrder(align, seqs);
+        }
+        else
+        {
+            setOrder(align, seqs);
+        }
+
+        sortIdAscending = !sortIdAscending;
+    }
+
+    /**
+     * Sorts the alignment by size of group.
+     * <br>Maintains the order of sequences in each group
+     * by order in given alignment object.
+     *
+     * @param align sorts the given alignment object by group
+     */
+    public static void sortByGroup(AlignmentI align)
+    {
+        //MAINTAINS ORIGNAL SEQUENCE ORDER,
+        //ORDERS BY GROUP SIZE
+        Vector groups = new Vector();
+
+        if (groups.hashCode() != lastGroupHash)
+        {
+            sortGroupAscending = true;
+            lastGroupHash = groups.hashCode();
+        }
+        else
+        {
+            sortGroupAscending = !sortGroupAscending;
+        }
+
+        //SORTS GROUPS BY SIZE
+        //////////////////////
+        for (int i = 0; i < align.getGroups().size(); i++)
+        {
+            SequenceGroup sg = (SequenceGroup) align.getGroups().elementAt(i);
+
+            for (int j = 0; j < groups.size(); j++)
+            {
+                SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j);
+
+                if (sg.getSize(false) > sg2.getSize(false))
+                {
+                    groups.insertElementAt(sg, j);
+
+                    break;
+                }
+            }
+
+            if (!groups.contains(sg))
+            {
+                groups.addElement(sg);
+            }
+        }
+
+        //NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER
+        ///////////////////////////////////////////////
+        Vector seqs = new Vector();
+
+        for (int i = 0; i < groups.size(); i++)
+        {
+            SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+            SequenceI[] orderedseqs = sg.getSequencesInOrder(align);
+
+            for (int j = 0; j < orderedseqs.length; j++)
+            {
+                seqs.addElement(orderedseqs[j]);
+            }
+        }
+
+        if (sortGroupAscending)
+        {
+            setOrder(align, seqs);
+        }
+        else
+        {
+            setReverseOrder(align,
+                vectorSubsetToArray(seqs, align.getSequences()));
+        }
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param tmp DOCUMENT ME!
+     * @param mask DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private static SequenceI[] vectorSubsetToArray(Vector tmp, Vector mask)
+    {
+        Vector seqs = new Vector();
+        int i;
+        boolean[] tmask = new boolean[mask.size()];
+
+        for (i = 0; i < mask.size(); i++)
+            tmask[i] = true;
+
+        for (i = 0; i < tmp.size(); i++)
+        {
+            Object sq = tmp.elementAt(i);
+
+            if (mask.contains(sq) && tmask[mask.indexOf(sq)])
+            {
+                tmask[mask.indexOf(sq)] = false;
+                seqs.addElement(sq);
+            }
+        }
+
+        for (i = 0; i < tmask.length; i++)
+            if (tmask[i])
+            {
+                seqs.addElement(mask.elementAt(i));
+            }
+
+        return vectorToArray(seqs);
+    }
+
+    /**
+     * Sorts by a given AlignmentOrder object
+     *
+     * @param align Alignment to order
+     * @param order specified order for alignment
+     */
+    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();
+
+        if (lastOrder == order)
+        {
+            sortOrderAscending = !sortOrderAscending;
+        }
+        else
+        {
+            sortOrderAscending = true;
+        }
+
+        if (sortOrderAscending)
+        {
+            setOrder(align, tmp);
+        }
+        else
+        {
+            setReverseOrder(align,
+                vectorSubsetToArray(tmp, align.getSequences()));
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param align alignment to order
+     * @param tree tree which has
+     *
+     * @return DOCUMENT ME!
+     */
+    private static Vector getOrderByTree(AlignmentI align, NJTree tree)
+    {
+        int nSeq = align.getHeight();
+
+        Vector tmp = new Vector();
+
+        tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());
+
+        if (tmp.size() != nSeq)
+        {
+            // TODO: JBPNote - decide if this is always an error
+            // (eg. not when a tree is associated to another alignment which has more
+            //  sequences)
+            if (tmp.size() < nSeq)
+            {
+                addStrays(align, tmp);
+            }
+
+            if (tmp.size() != nSeq)
+            {
+                System.err.println("ERROR: tmp.size()=" + tmp.size() +
+                    " != nseq=" + nSeq + " in getOrderByTree");
+            }
+        }
+
+        return tmp;
+    }
+
+    /**
+     * Sorts the alignment by a given tree
+     *
+     * @param align alignment to order
+     * @param tree tree which has
+     */
+    public static void sortByTree(AlignmentI align, NJTree tree)
+    {
+        Vector tmp = getOrderByTree(align, tree);
+
+        // tmp should properly permute align with tree.
+        if (lastTree != tree)
+        {
+            sortTreeAscending = true;
+            lastTree = tree;
+        }
+        else
+        {
+            sortTreeAscending = !sortTreeAscending;
+        }
+
+        if (sortTreeAscending)
+        {
+            setOrder(align, tmp);
+        }
+        else
+        {
+            setReverseOrder(align,
+                vectorSubsetToArray(tmp, align.getSequences()));
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param align DOCUMENT ME!
+     * @param seqs DOCUMENT ME!
+     */
+    private static void addStrays(AlignmentI align, Vector seqs)
+    {
+        int nSeq = align.getHeight();
+
+        for (int i = 0; i < nSeq; i++)
+        {
+            if (!seqs.contains(align.getSequenceAt(i)))
+            {
+                seqs.addElement(align.getSequenceAt(i));
+            }
+        }
+
+        if (nSeq != seqs.size())
+        {
+            System.err.println(
+                "ERROR: Size still not right even after addStrays");
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param tmp DOCUMENT ME!
+     * @param seqset DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private static Vector _sortByTree(SequenceNode node, Vector tmp,
+        Vector seqset)
+    {
+        if (node == null)
+        {
+            return tmp;
+        }
+
+        SequenceNode left = (SequenceNode) node.left();
+        SequenceNode right = (SequenceNode) node.right();
+
+        if ((left == null) && (right == null))
+        {
+            if (!node.isPlaceholder() && (node.element() != null))
+            {
+                if (node.element() instanceof SequenceI)
+                {
+                    if (!tmp.contains(node.element()))
+                    {
+                        tmp.addElement((SequenceI) node.element());
+                    }
+                }
+            }
+
+            return tmp;
+        }
+        else
+        {
+            _sortByTree(left, tmp, seqset);
+            _sortByTree(right, tmp, seqset);
+        }
+
+        return tmp;
+    }
+
+    // Ordering Objects
+    // Alignment.sortBy(OrderObj) - sequence of sequence pointer refs in appropriate order
+    //
+
+    /**
+     * recover the order of sequences given by the safe numbering scheme introducd
+     * SeqsetUtils.uniquify.
+     */
+    public static void recoverOrder(SequenceI[] alignment)
+    {
+        float[] ids = new float[alignment.length];
+
+        for (int i = 0; i < alignment.length; i++)
+            ids[i] = (new Float(alignment[i].getName().substring(8))).floatValue();
+
+        jalview.util.QuickSort.sort(ids, alignment);
+    }
+}
index b9b68ce..7d831e8 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.analysis;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * Calculates conservation values for a given set of sequences\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Conservation\r
-{\r
-    Vector sequences;\r
-    int start;\r
-    int end;\r
-    Vector seqNums; // vector of int vectors where first is sequence checksum\r
-    int maxLength = 0; //  used by quality calcs\r
-    boolean seqNumsChanged = false; // updated after any change via calcSeqNum;\r
-    Vector total = new Vector();\r
-\r
-    /** Stores calculated quality values */\r
-    public Vector quality;\r
-\r
-    /** Stores maximum and minimum values of quality values  */\r
-    public Double[] qualityRange = new Double[2];\r
-    String consString = "";\r
-    Sequence consSequence;\r
-    Hashtable propHash;\r
-    int threshold;\r
-    String name = "";\r
-    int[][] cons2;\r
-\r
-    /**\r
-     * Creates a new Conservation object.\r
-     *\r
-     * @param name Name of conservation\r
-     * @param propHash DOCUMENT ME!\r
-     * @param threshold to count the residues in residueHash(). commonly used value is 3\r
-     * @param sequences sequences to be used in calculation\r
-     * @param start start residue position\r
-     * @param end end residue position\r
-     */\r
-    public Conservation(String name, Hashtable propHash, int threshold,\r
-        Vector sequences, int start, int end)\r
-    {\r
-        this.name = name;\r
-        this.propHash = propHash;\r
-        this.threshold = threshold;\r
-        this.sequences = sequences;\r
-        this.start = start;\r
-        this.end = end;\r
-        seqNums = new Vector(sequences.size());\r
-        calcSeqNums();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    private void calcSeqNums()\r
-    {\r
-      int i=0, iSize=sequences.size();\r
-        for (i=0; i < iSize; i++)\r
-        {\r
-            calcSeqNum(i);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    private void calcSeqNum(int i)\r
-    {\r
-        String sq = null; // for dumb jbuilder not-inited exception warning\r
-        int[] sqnum = null;\r
-\r
-        if ((i > -1) && (i < sequences.size()))\r
-        {\r
-            sq = ((SequenceI) sequences.elementAt(i)).getSequence();\r
-\r
-            if (seqNums.size() <= i)\r
-            {\r
-                seqNums.addElement(new int[sq.length() + 1]);\r
-            }\r
-\r
-            if (sq.hashCode() != ((int[]) seqNums.elementAt(i))[0])\r
-            {\r
-                int j;\r
-                int len;\r
-                seqNumsChanged = true;\r
-                sq = ((SequenceI) sequences.elementAt(i)).getSequence();\r
-                len = sq.length();\r
-\r
-                if (maxLength < len)\r
-                {\r
-                    maxLength = len;\r
-                }\r
-\r
-                sqnum = new int[len + 1]; // better to always make a new array - sequence can change its length\r
-                sqnum[0] = sq.hashCode();\r
-\r
-                for (j = 1; j <= len; j++)\r
-                {\r
-                    sqnum[j] = ((Integer) jalview.schemes.ResidueProperties.aaHash.get(String.valueOf(\r
-                                sq.charAt(j - 1)))).intValue(); // yuk - JBPNote - case taken care of in aaHash\r
-                }\r
-\r
-                seqNums.setElementAt(sqnum, i);\r
-            }\r
-        }\r
-        else\r
-        {\r
-            // JBPNote INFO level debug\r
-            System.err.println(\r
-                "ERROR: calcSeqNum called with out of range sequence index for Alignment\n");\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Calculates the conservation values for given set of sequences\r
-     */\r
-    public void calculate()\r
-    {\r
-      Hashtable resultHash, residueHash, ht;\r
-      int count, thresh, j, jSize = sequences.size();\r
-      String sequence, res, type;\r
-      Enumeration enumeration, enumeration2;\r
-\r
-      for (int i = start; i <= end; i++)\r
-        {\r
-            resultHash = new Hashtable();\r
-            residueHash = new Hashtable();\r
-\r
-            for (j = 0; j < jSize; j++)\r
-            {\r
-                // JBPNote - have to make sure elements of the sequences vector\r
-                //  are tested like this everywhere...\r
-                if (sequences.elementAt(j) instanceof Sequence)\r
-                {\r
-                    sequence = ((Sequence) sequences.elementAt(j)).getSequence();\r
-\r
-                    if (sequence.length() > i)\r
-                    {\r
-                        res = String.valueOf(Character.toUpperCase(sequence.charAt(i)));\r
-\r
-                        if (residueHash.containsKey(res))\r
-                        {\r
-                            count = ((Integer) residueHash.get(res)).intValue();\r
-                            count++;\r
-                            residueHash.put(res, new Integer(count));\r
-                        }\r
-                        else\r
-                        {\r
-                            residueHash.put(res, new Integer(1));\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        if (residueHash.containsKey("-"))\r
-                        {\r
-                            count = ((Integer) residueHash.get("-")).intValue();\r
-                            count++;\r
-                            residueHash.put("-", new Integer(count));\r
-                        }\r
-                        else\r
-                        {\r
-                            residueHash.put("-", new Integer(1));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-\r
-            //What is the count threshold to count the residues in residueHash()\r
-            thresh = (threshold * (sequences.size())) / 100;\r
-\r
-            //loop over all the found residues\r
-            enumeration = residueHash.keys();\r
-\r
-            while (enumeration.hasMoreElements())\r
-            {\r
-                res = (String) enumeration.nextElement();\r
-\r
-                if (((Integer) residueHash.get(res)).intValue() > thresh)\r
-                {\r
-                    //Now loop over the properties\r
-                    enumeration2 = propHash.keys();\r
-\r
-                    while (enumeration2.hasMoreElements())\r
-                    {\r
-                        type = (String) enumeration2.nextElement();\r
-                        ht = (Hashtable) propHash.get(type);\r
-\r
-                        //Have we ticked this before?\r
-                        if (!resultHash.containsKey(type))\r
-                        {\r
-                            if (ht.containsKey(res))\r
-                            {\r
-                                resultHash.put(type, ht.get(res));\r
-                            }\r
-                            else\r
-                            {\r
-                                resultHash.put(type, ht.get("-"));\r
-                            }\r
-                        }\r
-                        else if (((Integer) resultHash.get(type)).equals(\r
-                                    (Integer) ht.get(res)) == false)\r
-                        {\r
-                            resultHash.put(type, new Integer(-1));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-\r
-            total.addElement(resultHash);\r
-        }\r
-    }\r
-\r
-\r
-    /***\r
-     * countConsNGaps\r
-     * returns gap count in int[0], and conserved residue count in int[1]\r
-     */\r
-    public int[] countConsNGaps(int j)\r
-    {\r
-        int count = 0;\r
-        int cons = 0;\r
-        int nres = 0;\r
-        int[] r = new int[2];\r
-        char f = '$';\r
-        int i, iSize = sequences.size();\r
-        char c;\r
-\r
-        for (i = 0; i < iSize; i++)\r
-        {\r
-            if (j >= ((Sequence) sequences.elementAt(i)).getLength())\r
-            {\r
-                count++;\r
-                continue;\r
-            }\r
-\r
-            c = ((Sequence) sequences.elementAt(i)).getCharAt(j); // gaps do not have upper/lower case\r
-\r
-            if (jalview.util.Comparison.isGap((c)))\r
-            {\r
-                count++;\r
-            }\r
-            else\r
-            {\r
-                nres++;\r
-\r
-                if (nres == 1)\r
-                {\r
-                    f = c;\r
-                    cons++;\r
-                }\r
-                else if (f == c)\r
-                {\r
-                    cons++;\r
-                }\r
-            }\r
-        }\r
-\r
-        r[0] = (nres == cons) ? 1 : 0;\r
-        r[1] = count;\r
-\r
-        return r;\r
-    }\r
-\r
-    /**\r
-     * Calculates the conservation sequence\r
-     *\r
-     * @param consflag if true, poitiveve conservation; false calculates negative conservation\r
-     * @param percentageGaps commonly used value is 25\r
-     */\r
-    public void verdict(boolean consflag, float percentageGaps)\r
-    {\r
-        StringBuffer consString = new StringBuffer();\r
-        String type;\r
-        Integer result;\r
-        int[] gapcons;\r
-        int totGaps, count;\r
-        float pgaps;\r
-        Hashtable resultHash ;\r
-        Enumeration enumeration;\r
-\r
-\r
-        for (int i = start; i <= end; i++)\r
-        {\r
-            gapcons = countConsNGaps(i);\r
-            totGaps = gapcons[1];\r
-            pgaps = ((float) totGaps * 100) / (float) sequences.size();\r
-\r
-            if (percentageGaps > pgaps)\r
-            {\r
-                resultHash = (Hashtable) total.elementAt(i - start);\r
-\r
-                //Now find the verdict\r
-                count = 0;\r
-                enumeration = resultHash.keys();\r
-\r
-                while (enumeration.hasMoreElements())\r
-                {\r
-                   type = (String) enumeration.nextElement();\r
-                   result = (Integer) resultHash.get(type);\r
-\r
-                    //Do we want to count +ve conservation or +ve and -ve cons.?\r
-                    if (consflag)\r
-                    {\r
-                        if (result.intValue() == 1)\r
-                        {\r
-                            count++;\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        if (result.intValue() != -1)\r
-                        {\r
-                            count++;\r
-                        }\r
-                    }\r
-                }\r
-\r
-                if (count < 10)\r
-                {\r
-                    consString.append(count); // Conserved props!=Identity\r
-                }\r
-                else\r
-                {\r
-                    consString.append((gapcons[0] == 1) ? "*" : "+");\r
-                }\r
-            }\r
-            else\r
-            {\r
-                consString.append("-");\r
-            }\r
-        }\r
-\r
-        consSequence = new Sequence(name, consString.toString(), start, end);\r
-    }\r
-\r
-    /**\r
-     *\r
-     *\r
-     * @return Conservation sequence\r
-     */\r
-    public Sequence getConsSequence()\r
-    {\r
-        return consSequence;\r
-    }\r
-\r
-    // From Alignment.java in jalview118\r
-    public void findQuality()\r
-    {\r
-        findQuality(0, maxLength - 1);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    private void percentIdentity2()\r
-    {\r
-        calcSeqNums(); // updates maxLength, too.\r
-\r
-        if ((cons2 == null) || seqNumsChanged)\r
-        {\r
-            cons2 = new int[maxLength][24];\r
-\r
-            // Initialize the array\r
-            for (int j = 0; j < 24; j++)\r
-            {\r
-                for (int i = 0; i < maxLength; i++)\r
-                {\r
-                    cons2[i][j] = 0;\r
-                }\r
-            }\r
-\r
-            int[] sqnum;\r
-            int j = 0;\r
-\r
-            while (j < sequences.size())\r
-            {\r
-                sqnum = (int[]) seqNums.elementAt(j);\r
-\r
-                for (int i = 1; i < sqnum.length; i++)\r
-                {\r
-                    cons2[i - 1][sqnum[i]]++;\r
-                }\r
-\r
-                for (int i = sqnum.length - 1; i < maxLength; i++)\r
-                {\r
-                    cons2[i][23]++; // gap count\r
-                }\r
-\r
-                j++;\r
-            }\r
-\r
-            // unnecessary ?\r
-\r
-            /* for (int i=start; i <= end; i++) {\r
-                 int max = -1000;\r
-            int maxi = -1;\r
-            int maxj = -1;\r
-\r
-            for (int j=0;j<24;j++) {\r
-              if (cons2[i][j] > max) {\r
-              max = cons2[i][j];\r
-              maxi = i;\r
-              maxj = j;\r
-            }\r
-\r
-            }\r
-            } */\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Calculates the quality of the set of sequences\r
-     *\r
-     * @param start Start residue\r
-     * @param end End residue\r
-     */\r
-    public void findQuality(int start, int end)\r
-    {\r
-        quality = new Vector();\r
-\r
-        double max = -10000;\r
-        int[][] BLOSUM62 = jalview.schemes.ResidueProperties.getBLOSUM62();\r
-\r
-        //Loop over columns // JBPNote Profiling info\r
-        //    long ts = System.currentTimeMillis();\r
-        //long te = System.currentTimeMillis();\r
-        percentIdentity2();\r
-\r
-        int size = seqNums.size();\r
-        int[] lengths = new int[size];\r
-        double tot, bigtot, sr, tmp;\r
-        double [] x, xx;\r
-        int l, j, i, ii, seqNum;\r
-\r
-        for (l = 0; l < size; l++)\r
-            lengths[l] = ((int[]) seqNums.elementAt(l)).length - 1;\r
-\r
-\r
-        for (j = start; j <= end; j++)\r
-        {\r
-            bigtot = 0;\r
-\r
-            // First Xr = depends on column only\r
-            x = new double[24];\r
-\r
-            for (ii = 0; ii < 24; ii++)\r
-            {\r
-                x[ii] = 0;\r
-\r
-                try\r
-                {\r
-                    for (int i2 = 0; i2 < 24; i2++)\r
-                    {\r
-                        x[ii] += (((double) cons2[j][i2] * BLOSUM62[ii][i2]) +\r
-                        4);\r
-                    }\r
-                }\r
-                catch (Exception e)\r
-                {\r
-                    System.err.println("Exception during quality calculation.");\r
-                    e.printStackTrace();\r
-                }\r
-\r
-                //System.out.println("X " + ii + " " + x[ii]);\r
-                x[ii] /= (size);\r
-\r
-                //System.out.println("X " + ii + " " + x[ii]);\r
-            }\r
-\r
-            // Now calculate D for each position and sum\r
-            for (int k = 0; k < size; k++)\r
-            {\r
-                tot = 0;\r
-                xx = new double[24];\r
-                seqNum = (j < lengths[k])\r
-                    ? ((int[]) seqNums.elementAt(k))[j + 1] : 23; // Sequence, or gap at the end\r
-\r
-                // This is a loop over r\r
-                for (i = 0; i < 23; i++)\r
-                {\r
-                    sr = 0;\r
-\r
-                    try\r
-                    {\r
-                        sr = (double) BLOSUM62[i][seqNum] + 4;\r
-                    }\r
-                    catch (Exception e)\r
-                    {\r
-                        System.out.println("Exception in sr: " + e);\r
-                        e.printStackTrace();\r
-                    }\r
-\r
-                    //Calculate X with another loop over residues\r
-                    //  System.out.println("Xi " + i + " " + x[i] + " " + sr);\r
-                    xx[i] = x[i] - sr;\r
-\r
-                    tot += (xx[i] * xx[i]);\r
-                }\r
-\r
-                bigtot += Math.sqrt(tot);\r
-            }\r
-\r
-            // This is the quality for one column\r
-            if (max < bigtot)\r
-            {\r
-                max = bigtot;\r
-            }\r
-\r
-            //      bigtot  = bigtot * (size-cons2[j][23])/size;\r
-            quality.addElement(new Double(bigtot));\r
-\r
-\r
-            // Need to normalize by gaps\r
-        }\r
-\r
-        double newmax = -10000;\r
-\r
-        for (j = start; j <= end; j++)\r
-        {\r
-            tmp = ((Double) quality.elementAt(j)).doubleValue();\r
-            tmp = ((max - tmp) * (size - cons2[j][23])) / size;\r
-\r
-            //     System.out.println(tmp+ " " + j);\r
-            quality.setElementAt(new Double(tmp), j);\r
-\r
-            if (tmp > newmax)\r
-            {\r
-                newmax = tmp;\r
-            }\r
-        }\r
-\r
-        //    System.out.println("Quality " + s);\r
-        qualityRange[0] = new Double(0);\r
-        qualityRange[1] = new Double(newmax);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.analysis;
+
+import jalview.datamodel.*;
+
+import java.util.*;
+
+
+/**
+ * Calculates conservation values for a given set of sequences
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Conservation
+{
+    Vector sequences;
+    int start;
+    int end;
+    Vector seqNums; // vector of int vectors where first is sequence checksum
+    int maxLength = 0; //  used by quality calcs
+    boolean seqNumsChanged = false; // updated after any change via calcSeqNum;
+    Vector total = new Vector();
+
+    /** Stores calculated quality values */
+    public Vector quality;
+
+    /** Stores maximum and minimum values of quality values  */
+    public Double[] qualityRange = new Double[2];
+    String consString = "";
+    Sequence consSequence;
+    Hashtable propHash;
+    int threshold;
+    String name = "";
+    int[][] cons2;
+
+    /**
+     * Creates a new Conservation object.
+     *
+     * @param name Name of conservation
+     * @param propHash DOCUMENT ME!
+     * @param threshold to count the residues in residueHash(). commonly used value is 3
+     * @param sequences sequences to be used in calculation
+     * @param start start residue position
+     * @param end end residue position
+     */
+    public Conservation(String name, Hashtable propHash, int threshold,
+        Vector sequences, int start, int end)
+    {
+        this.name = name;
+        this.propHash = propHash;
+        this.threshold = threshold;
+        this.sequences = sequences;
+        this.start = start;
+        this.end = end;
+        seqNums = new Vector(sequences.size());
+        calcSeqNums();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    private void calcSeqNums()
+    {
+      int i=0, iSize=sequences.size();
+        for (i=0; i < iSize; i++)
+        {
+            calcSeqNum(i);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    private void calcSeqNum(int i)
+    {
+        String sq = null; // for dumb jbuilder not-inited exception warning
+        int[] sqnum = null;
+
+        if ((i > -1) && (i < sequences.size()))
+        {
+            sq = ((SequenceI) sequences.elementAt(i)).getSequence();
+
+            if (seqNums.size() <= i)
+            {
+                seqNums.addElement(new int[sq.length() + 1]);
+            }
+
+            if (sq.hashCode() != ((int[]) seqNums.elementAt(i))[0])
+            {
+                int j;
+                int len;
+                seqNumsChanged = true;
+                sq = ((SequenceI) sequences.elementAt(i)).getSequence();
+                len = sq.length();
+
+                if (maxLength < len)
+                {
+                    maxLength = len;
+                }
+
+                sqnum = new int[len + 1]; // better to always make a new array - sequence can change its length
+                sqnum[0] = sq.hashCode();
+
+                for (j = 1; j <= len; j++)
+                {
+                    sqnum[j] = ((Integer) jalview.schemes.ResidueProperties.aaHash.get(String.valueOf(
+                                sq.charAt(j - 1)))).intValue(); // yuk - JBPNote - case taken care of in aaHash
+                }
+
+                seqNums.setElementAt(sqnum, i);
+            }
+        }
+        else
+        {
+            // JBPNote INFO level debug
+            System.err.println(
+                "ERROR: calcSeqNum called with out of range sequence index for Alignment\n");
+        }
+    }
+
+    /**
+     * Calculates the conservation values for given set of sequences
+     */
+    public void calculate()
+    {
+      Hashtable resultHash, residueHash, ht;
+      int count, thresh, j, jSize = sequences.size();
+      String type, res=null;
+      SequenceI sequence;
+      char c;
+      Enumeration enumeration, enumeration2;
+
+      for (int i = start; i <= end; i++)
+        {
+            resultHash = new Hashtable();
+            residueHash = new Hashtable();
+
+            for (j = 0; j < jSize; j++)
+            {
+                // JBPNote - have to make sure elements of the sequences vector
+                //  are tested like this everywhere...
+                    sequence = (Sequence) sequences.elementAt(j);
+
+                    if (sequence.getLength() > i)
+                    {
+                        c = sequence.getCharAt(i);
+
+                        // No need to check if its a '-'
+                        if(c == '.' || c==' ')
+                          c = '-';
+
+                        if ('a' <= c && c <= 'z')
+                        {
+                          // TO UPPERCASE !!!
+                          //Faster than toUpperCase
+                          c -= ('a' - 'A') ;
+                        }
+
+                        res = String.valueOf( c );
+
+
+                        if (residueHash.containsKey(res))
+                        {
+                            count = ((Integer) residueHash.get(res)).intValue();
+                            count++;
+                            residueHash.put(res, new Integer(count));
+                        }
+                        else
+                        {
+                            residueHash.put(res, new Integer(1));
+                        }
+                    }
+                    else
+                    {
+                        if (residueHash.containsKey("-"))
+                        {
+                            count = ((Integer) residueHash.get("-")).intValue();
+                            count++;
+                            residueHash.put("-", new Integer(count));
+                        }
+                        else
+                        {
+                            residueHash.put("-", new Integer(1));
+                        }
+                    }
+            }
+
+            //What is the count threshold to count the residues in residueHash()
+            thresh = (threshold * (sequences.size())) / 100;
+
+            //loop over all the found residues
+            enumeration = residueHash.keys();
+
+            while (enumeration.hasMoreElements())
+            {
+                res = (String) enumeration.nextElement();
+
+                if (((Integer) residueHash.get(res)).intValue() > thresh)
+                {
+                    //Now loop over the properties
+                    enumeration2 = propHash.keys();
+
+                    while (enumeration2.hasMoreElements())
+                    {
+                        type = (String) enumeration2.nextElement();
+                        ht = (Hashtable) propHash.get(type);
+
+                        //Have we ticked this before?
+                        if (!resultHash.containsKey(type))
+                        {
+                            if (ht.containsKey(res))
+                            {
+                                resultHash.put(type, ht.get(res));
+                            }
+                            else
+                            {
+                                resultHash.put(type, ht.get("-"));
+                            }
+                        }
+                        else if (((Integer) resultHash.get(type)).equals(
+                                    (Integer) ht.get(res)) == false)
+                        {
+                            resultHash.put(type, new Integer(-1));
+                        }
+                    }
+                }
+            }
+
+            total.addElement(resultHash);
+        }
+    }
+
+
+    /***
+     * countConsNGaps
+     * returns gap count in int[0], and conserved residue count in int[1]
+     */
+    public int[] countConsNGaps(int j)
+    {
+        int count = 0;
+        int cons = 0;
+        int nres = 0;
+        int[] r = new int[2];
+        char f = '$';
+        int i, iSize = sequences.size();
+        char c;
+
+        for (i = 0; i < iSize; i++)
+        {
+            if (j >= ((Sequence) sequences.elementAt(i)).getLength())
+            {
+                count++;
+                continue;
+            }
+
+            c = ((Sequence) sequences.elementAt(i)).getCharAt(j); // gaps do not have upper/lower case
+
+            if (jalview.util.Comparison.isGap((c)))
+            {
+                count++;
+            }
+            else
+            {
+                nres++;
+
+                if (nres == 1)
+                {
+                    f = c;
+                    cons++;
+                }
+                else if (f == c)
+                {
+                    cons++;
+                }
+            }
+        }
+
+        r[0] = (nres == cons) ? 1 : 0;
+        r[1] = count;
+
+        return r;
+    }
+
+    /**
+     * Calculates the conservation sequence
+     *
+     * @param consflag if true, poitiveve conservation; false calculates negative conservation
+     * @param percentageGaps commonly used value is 25
+     */
+    public void verdict(boolean consflag, float percentageGaps)
+    {
+        StringBuffer consString = new StringBuffer();
+        String type;
+        Integer result;
+        int[] gapcons;
+        int totGaps, count;
+        float pgaps;
+        Hashtable resultHash ;
+        Enumeration enumeration;
+
+
+        for (int i = start; i <= end; i++)
+        {
+            gapcons = countConsNGaps(i);
+            totGaps = gapcons[1];
+            pgaps = ((float) totGaps * 100) / (float) sequences.size();
+
+            if (percentageGaps > pgaps)
+            {
+                resultHash = (Hashtable) total.elementAt(i - start);
+
+                //Now find the verdict
+                count = 0;
+                enumeration = resultHash.keys();
+
+                while (enumeration.hasMoreElements())
+                {
+                   type = (String) enumeration.nextElement();
+                   result = (Integer) resultHash.get(type);
+
+                    //Do we want to count +ve conservation or +ve and -ve cons.?
+                    if (consflag)
+                    {
+                        if (result.intValue() == 1)
+                        {
+                            count++;
+                        }
+                    }
+                    else
+                    {
+                        if (result.intValue() != -1)
+                        {
+                            count++;
+                        }
+                    }
+                }
+
+                if (count < 10)
+                {
+                    consString.append(count); // Conserved props!=Identity
+                }
+                else
+                {
+                    consString.append((gapcons[0] == 1) ? "*" : "+");
+                }
+            }
+            else
+            {
+                consString.append("-");
+            }
+        }
+
+        consSequence = new Sequence(name, consString.toString(), start, end);
+    }
+
+    /**
+     *
+     *
+     * @return Conservation sequence
+     */
+    public Sequence getConsSequence()
+    {
+        return consSequence;
+    }
+
+    // From Alignment.java in jalview118
+    public void findQuality()
+    {
+        findQuality(0, maxLength - 1);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    private void percentIdentity2()
+    {
+        calcSeqNums(); // updates maxLength, too.
+
+        if ((cons2 == null) || seqNumsChanged)
+        {
+            cons2 = new int[maxLength][24];
+
+            // Initialize the array
+            for (int j = 0; j < 24; j++)
+            {
+                for (int i = 0; i < maxLength; i++)
+                {
+                    cons2[i][j] = 0;
+                }
+            }
+
+            int[] sqnum;
+            int j = 0;
+
+            while (j < sequences.size())
+            {
+                sqnum = (int[]) seqNums.elementAt(j);
+
+                for (int i = 1; i < sqnum.length; i++)
+                {
+                    cons2[i - 1][sqnum[i]]++;
+                }
+
+                for (int i = sqnum.length - 1; i < maxLength; i++)
+                {
+                    cons2[i][23]++; // gap count
+                }
+
+                j++;
+            }
+
+            // unnecessary ?
+
+            /* for (int i=start; i <= end; i++) {
+                 int max = -1000;
+            int maxi = -1;
+            int maxj = -1;
+
+            for (int j=0;j<24;j++) {
+              if (cons2[i][j] > max) {
+              max = cons2[i][j];
+              maxi = i;
+              maxj = j;
+            }
+
+            }
+            } */
+        }
+    }
+
+    /**
+     * Calculates the quality of the set of sequences
+     *
+     * @param start Start residue
+     * @param end End residue
+     */
+    public void findQuality(int start, int end)
+    {
+        quality = new Vector();
+
+        double max = -10000;
+        int[][] BLOSUM62 = jalview.schemes.ResidueProperties.getBLOSUM62();
+
+        //Loop over columns // JBPNote Profiling info
+        //    long ts = System.currentTimeMillis();
+        //long te = System.currentTimeMillis();
+        percentIdentity2();
+
+        int size = seqNums.size();
+        int[] lengths = new int[size];
+        double tot, bigtot, sr, tmp;
+        double [] x, xx;
+        int l, j, i, ii, seqNum;
+
+        for (l = 0; l < size; l++)
+            lengths[l] = ((int[]) seqNums.elementAt(l)).length - 1;
+
+
+        for (j = start; j <= end; j++)
+        {
+            bigtot = 0;
+
+            // First Xr = depends on column only
+            x = new double[24];
+
+            for (ii = 0; ii < 24; ii++)
+            {
+                x[ii] = 0;
+
+                try
+                {
+                    for (int i2 = 0; i2 < 24; i2++)
+                    {
+                        x[ii] += (((double) cons2[j][i2] * BLOSUM62[ii][i2]) +
+                        4);
+                    }
+                }
+                catch (Exception e)
+                {
+                    System.err.println("Exception during quality calculation.");
+                    e.printStackTrace();
+                }
+
+                //System.out.println("X " + ii + " " + x[ii]);
+                x[ii] /= (size);
+
+                //System.out.println("X " + ii + " " + x[ii]);
+            }
+
+            // Now calculate D for each position and sum
+            for (int k = 0; k < size; k++)
+            {
+                tot = 0;
+                xx = new double[24];
+                seqNum = (j < lengths[k])
+                    ? ((int[]) seqNums.elementAt(k))[j + 1] : 23; // Sequence, or gap at the end
+
+                // This is a loop over r
+                for (i = 0; i < 23; i++)
+                {
+                    sr = 0;
+
+                    try
+                    {
+                        sr = (double) BLOSUM62[i][seqNum] + 4;
+                    }
+                    catch (Exception e)
+                    {
+                        System.out.println("Exception in sr: " + e);
+                        e.printStackTrace();
+                    }
+
+                    //Calculate X with another loop over residues
+                    //  System.out.println("Xi " + i + " " + x[i] + " " + sr);
+                    xx[i] = x[i] - sr;
+
+                    tot += (xx[i] * xx[i]);
+                }
+
+                bigtot += Math.sqrt(tot);
+            }
+
+            // This is the quality for one column
+            if (max < bigtot)
+            {
+                max = bigtot;
+            }
+
+            //      bigtot  = bigtot * (size-cons2[j][23])/size;
+            quality.addElement(new Double(bigtot));
+
+
+            // Need to normalize by gaps
+        }
+
+        double newmax = -10000;
+
+        for (j = start; j <= end; j++)
+        {
+            tmp = ((Double) quality.elementAt(j)).doubleValue();
+            tmp = ((max - tmp) * (size - cons2[j][23])) / size;
+
+            //     System.out.println(tmp+ " " + j);
+            quality.setElementAt(new Double(tmp), j);
+
+            if (tmp > newmax)
+            {
+                newmax = tmp;
+            }
+        }
+
+        //    System.out.println("Quality " + s);
+        qualityRange[0] = new Double(0);
+        qualityRange[1] = new Double(newmax);
+    }
+}
index 40dfc9b..e029771 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.analysis;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.io.NewickFile;\r
-\r
-import jalview.schemes.ResidueProperties;\r
-\r
-import jalview.util.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class NJTree\r
-{\r
-    Vector cluster;\r
-    SequenceI[] sequence;\r
-    int[] done;\r
-    int noseqs;\r
-    int noClus;\r
-    float[][] distance;\r
-    int mini;\r
-    int minj;\r
-    float ri;\r
-    float rj;\r
-    Vector groups = new Vector();\r
-    SequenceNode maxdist;\r
-    SequenceNode top;\r
-    float maxDistValue;\r
-    float maxheight;\r
-    int ycount;\r
-    Vector node;\r
-    String type;\r
-    String pwtype;\r
-    Object found = null;\r
-    Object leaves = null;\r
-    int start;\r
-    int end;\r
-    boolean hasDistances = true; // normal case for jalview trees\r
-       boolean hasBootstrap = false; // normal case for jalview trees\r
-\r
-    private boolean hasRootDistance = true;\r
-\r
-    /**\r
-     * Creates a new NJTree object.\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     */\r
-    public NJTree(SequenceNode node)\r
-    {\r
-        top = node;\r
-        maxheight = findHeight(top);\r
-    }\r
-\r
-    /**\r
-     * Creates a new NJTree object.\r
-     *\r
-     * @param seqs DOCUMENT ME!\r
-     * @param treefile DOCUMENT ME!\r
-     */\r
-    public NJTree(SequenceI[] seqs, NewickFile treefile)\r
-    {\r
-        top = treefile.getTree();\r
-\r
-        hasDistances = treefile.HasDistances();\r
-        hasBootstrap = treefile.HasBootstrap();\r
-        hasRootDistance = treefile.HasRootDistance();\r
-\r
-        maxheight = findHeight(top);\r
-\r
-        SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs);\r
-\r
-        Vector leaves = new Vector();\r
-        findLeaves(top, leaves);\r
-\r
-        int i = 0;\r
-        int namesleft = seqs.length;\r
-\r
-        SequenceNode j;\r
-        SequenceI nam;\r
-        String realnam;\r
-\r
-        while (i < leaves.size())\r
-        {\r
-            j = (SequenceNode) leaves.elementAt(i++);\r
-            realnam = j.getName();\r
-            nam = null;\r
-\r
-            if (namesleft > -1)\r
-            {\r
-                nam = algnIds.findIdMatch(realnam);\r
-            }\r
-\r
-            if (nam != null)\r
-            {\r
-                j.setElement(nam);\r
-                namesleft--;\r
-            }\r
-            else\r
-            {\r
-                j.setElement(new Sequence(realnam, "THISISAPLACEHLDER"));\r
-                j.setPlaceholder(true);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Creates a new NJTree object.\r
-     *\r
-     * @param sequence DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public NJTree(SequenceI[] sequence, int start, int end)\r
-    {\r
-        this(sequence, "NJ", "BL", start, end);\r
-    }\r
-\r
-    /**\r
-     * Creates a new NJTree object.\r
-     *\r
-     * @param sequence DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     * @param pwtype DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public NJTree(SequenceI[] sequence, String type, String pwtype, int start,\r
-        int end)\r
-    {\r
-        this.sequence = sequence;\r
-        this.node = new Vector();\r
-        this.type = type;\r
-        this.pwtype = pwtype;\r
-        this.start = start;\r
-        this.end = end;\r
-\r
-        if (!(type.equals("NJ")))\r
-        {\r
-            type = "AV";\r
-        }\r
-\r
-        if (!(pwtype.equals("PID")))\r
-        {\r
-            type = "BL";\r
-        }\r
-\r
-        int i = 0;\r
-\r
-        done = new int[sequence.length];\r
-\r
-        while ((i < sequence.length) && (sequence[i] != null))\r
-        {\r
-            done[i] = 0;\r
-            i++;\r
-        }\r
-\r
-        noseqs = i++;\r
-\r
-        distance = findDistances();\r
-\r
-        makeLeaves();\r
-\r
-        noClus = cluster.size();\r
-\r
-        cluster();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String toString()\r
-    {\r
-        jalview.io.NewickFile fout = new jalview.io.NewickFile(getTopNode());\r
-\r
-        return fout.print(false, true); // distances only\r
-    }\r
-\r
-    /**\r
-     *\r
-     * used when the alignment associated to a tree has changed.\r
-     *\r
-     * @param alignment Vector\r
-     */\r
-    public void UpdatePlaceHolders(Vector alignment)\r
-    {\r
-        Vector leaves = new Vector();\r
-        findLeaves(top, leaves);\r
-\r
-        int sz = leaves.size();\r
-        SequenceIdMatcher seqmatcher = null;\r
-        int i = 0;\r
-\r
-        while (i < sz)\r
-        {\r
-            SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);\r
-\r
-            if (alignment.contains(leaf.element()))\r
-            {\r
-                leaf.setPlaceholder(false);\r
-            }\r
-            else\r
-            {\r
-                if (seqmatcher == null)\r
-                {\r
-                    // Only create this the first time we need it\r
-                    SequenceI[] seqs = new SequenceI[alignment.size()];\r
-\r
-                    for (int j = 0; j < seqs.length; j++)\r
-                        seqs[j] = (SequenceI) alignment.elementAt(j);\r
-\r
-                    seqmatcher = new SequenceIdMatcher(seqs);\r
-                }\r
-\r
-                SequenceI nam = seqmatcher.findIdMatch(leaf.getName());\r
-\r
-                if (nam != null)\r
-                {\r
-                    leaf.setPlaceholder(false);\r
-                    leaf.setElement(nam);\r
-                }\r
-                else\r
-                {\r
-                    leaf.setPlaceholder(true);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void cluster()\r
-    {\r
-        while (noClus > 2)\r
-        {\r
-            if (type.equals("NJ"))\r
-            {\r
-                findMinNJDistance();\r
-            }\r
-            else\r
-            {\r
-                findMinDistance();\r
-            }\r
-\r
-            Cluster c = joinClusters(mini, minj);\r
-\r
-            done[minj] = 1;\r
-\r
-            cluster.setElementAt(null, minj);\r
-            cluster.setElementAt(c, mini);\r
-\r
-            noClus--;\r
-        }\r
-\r
-        boolean onefound = false;\r
-\r
-        int one = -1;\r
-        int two = -1;\r
-\r
-        for (int i = 0; i < noseqs; i++)\r
-        {\r
-            if (done[i] != 1)\r
-            {\r
-                if (onefound == false)\r
-                {\r
-                    two = i;\r
-                    onefound = true;\r
-                }\r
-                else\r
-                {\r
-                    one = i;\r
-                }\r
-            }\r
-        }\r
-\r
-        joinClusters(one, two);\r
-        top = (SequenceNode) (node.elementAt(one));\r
-\r
-        reCount(top);\r
-        findHeight(top);\r
-        findMaxDist(top);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Cluster joinClusters(int i, int j)\r
-    {\r
-        float dist = distance[i][j];\r
-\r
-        int noi = ((Cluster) cluster.elementAt(i)).value.length;\r
-        int noj = ((Cluster) cluster.elementAt(j)).value.length;\r
-\r
-        int[] value = new int[noi + noj];\r
-\r
-        for (int ii = 0; ii < noi; ii++)\r
-        {\r
-            value[ii] = ((Cluster) cluster.elementAt(i)).value[ii];\r
-        }\r
-\r
-        for (int ii = noi; ii < (noi + noj); ii++)\r
-        {\r
-            value[ii] = ((Cluster) cluster.elementAt(j)).value[ii - noi];\r
-        }\r
-\r
-        Cluster c = new Cluster(value);\r
-\r
-        ri = findr(i, j);\r
-        rj = findr(j, i);\r
-\r
-        if (type.equals("NJ"))\r
-        {\r
-            findClusterNJDistance(i, j);\r
-        }\r
-        else\r
-        {\r
-            findClusterDistance(i, j);\r
-        }\r
-\r
-        SequenceNode sn = new SequenceNode();\r
-\r
-        sn.setLeft((SequenceNode) (node.elementAt(i)));\r
-        sn.setRight((SequenceNode) (node.elementAt(j)));\r
-\r
-        SequenceNode tmpi = (SequenceNode) (node.elementAt(i));\r
-        SequenceNode tmpj = (SequenceNode) (node.elementAt(j));\r
-\r
-        if (type.equals("NJ"))\r
-        {\r
-            findNewNJDistances(tmpi, tmpj, dist);\r
-        }\r
-        else\r
-        {\r
-            findNewDistances(tmpi, tmpj, dist);\r
-        }\r
-\r
-        tmpi.setParent(sn);\r
-        tmpj.setParent(sn);\r
-\r
-        node.setElementAt(sn, i);\r
-\r
-        return c;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param tmpi DOCUMENT ME!\r
-     * @param tmpj DOCUMENT ME!\r
-     * @param dist DOCUMENT ME!\r
-     */\r
-    public void findNewNJDistances(SequenceNode tmpi, SequenceNode tmpj,\r
-        float dist)\r
-    {\r
-\r
-        tmpi.dist = ((dist + ri) - rj) / 2;\r
-        tmpj.dist = (dist - tmpi.dist);\r
-\r
-        if (tmpi.dist < 0)\r
-        {\r
-            tmpi.dist = 0;\r
-        }\r
-\r
-        if (tmpj.dist < 0)\r
-        {\r
-            tmpj.dist = 0;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param tmpi DOCUMENT ME!\r
-     * @param tmpj DOCUMENT ME!\r
-     * @param dist DOCUMENT ME!\r
-     */\r
-    public void findNewDistances(SequenceNode tmpi, SequenceNode tmpj,\r
-        float dist)\r
-    {\r
-        float ih = 0;\r
-        float jh = 0;\r
-\r
-        SequenceNode sni = tmpi;\r
-        SequenceNode snj = tmpj;\r
-\r
-        while (sni != null)\r
-        {\r
-            ih = ih + sni.dist;\r
-            sni = (SequenceNode) sni.left();\r
-        }\r
-\r
-        while (snj != null)\r
-        {\r
-            jh = jh + snj.dist;\r
-            snj = (SequenceNode) snj.left();\r
-        }\r
-\r
-        tmpi.dist = ((dist / 2) - ih);\r
-        tmpj.dist = ((dist / 2) - jh);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     */\r
-    public void findClusterDistance(int i, int j)\r
-    {\r
-        int noi = ((Cluster) cluster.elementAt(i)).value.length;\r
-        int noj = ((Cluster) cluster.elementAt(j)).value.length;\r
-\r
-        // New distances from cluster to others\r
-        float[] newdist = new float[noseqs];\r
-\r
-        for (int l = 0; l < noseqs; l++)\r
-        {\r
-            if ((l != i) && (l != j))\r
-            {\r
-                newdist[l] = ((distance[i][l] * noi) + (distance[j][l] * noj)) / (noi +\r
-                    noj);\r
-            }\r
-            else\r
-            {\r
-                newdist[l] = 0;\r
-            }\r
-        }\r
-\r
-        for (int ii = 0; ii < noseqs; ii++)\r
-        {\r
-            distance[i][ii] = newdist[ii];\r
-            distance[ii][i] = newdist[ii];\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     */\r
-    public void findClusterNJDistance(int i, int j)\r
-    {\r
-\r
-        // New distances from cluster to others\r
-        float[] newdist = new float[noseqs];\r
-\r
-        for (int l = 0; l < noseqs; l++)\r
-        {\r
-            if ((l != i) && (l != j))\r
-            {\r
-                newdist[l] = ((distance[i][l] + distance[j][l]) -\r
-                    distance[i][j]) / 2;\r
-            }\r
-            else\r
-            {\r
-                newdist[l] = 0;\r
-            }\r
-        }\r
-\r
-        for (int ii = 0; ii < noseqs; ii++)\r
-        {\r
-            distance[i][ii] = newdist[ii];\r
-            distance[ii][i] = newdist[ii];\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float findr(int i, int j)\r
-    {\r
-        float tmp = 1;\r
-\r
-        for (int k = 0; k < noseqs; k++)\r
-        {\r
-            if ((k != i) && (k != j) && (done[k] != 1))\r
-            {\r
-                tmp = tmp + distance[i][k];\r
-            }\r
-        }\r
-\r
-        if (noClus > 2)\r
-        {\r
-            tmp = tmp / (noClus - 2);\r
-        }\r
-\r
-        return tmp;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float findMinNJDistance()\r
-    {\r
-        float min = 100000;\r
-\r
-        for (int i = 0; i < (noseqs - 1); i++)\r
-        {\r
-            for (int j = i + 1; j < noseqs; j++)\r
-            {\r
-                if ((done[i] != 1) && (done[j] != 1))\r
-                {\r
-                    float tmp = distance[i][j] - (findr(i, j) + findr(j, i));\r
-\r
-                    if (tmp < min)\r
-                    {\r
-                        mini = i;\r
-                        minj = j;\r
-\r
-                        min = tmp;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        return min;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float findMinDistance()\r
-    {\r
-        float min = 100000;\r
-\r
-        for (int i = 0; i < (noseqs - 1); i++)\r
-        {\r
-            for (int j = i + 1; j < noseqs; j++)\r
-            {\r
-                if ((done[i] != 1) && (done[j] != 1))\r
-                {\r
-                    if (distance[i][j] < min)\r
-                    {\r
-                        mini = i;\r
-                        minj = j;\r
-\r
-                        min = distance[i][j];\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        return min;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float[][] findDistances()\r
-    {\r
-        float[][] distance = new float[noseqs][noseqs];\r
-\r
-        if (pwtype.equals("PID"))\r
-        {\r
-            for (int i = 0; i < (noseqs - 1); i++)\r
-            {\r
-                for (int j = i; j < noseqs; j++)\r
-                {\r
-                    if (j == i)\r
-                    {\r
-                        distance[i][i] = 0;\r
-                    }\r
-                    else\r
-                    {\r
-                        distance[i][j] = 100 -\r
-                            Comparison.PID(sequence[i], sequence[j], start, end);\r
-                        distance[j][i] = distance[i][j];\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        else if (pwtype.equals("BL"))\r
-        {\r
-            int maxscore = 0;\r
-\r
-            for (int i = 0; i < (noseqs - 1); i++)\r
-            {\r
-                for (int j = i; j < noseqs; j++)\r
-                {\r
-                    int score = 0;\r
-\r
-                    for (int k = start; k < end; k++)\r
-                    {\r
-                        try\r
-                        {\r
-                            score += ResidueProperties.getBLOSUM62(sequence[i].getSequence(\r
-                                    k, k + 1), sequence[j].getSequence(k, k +\r
-                                    1));\r
-                        }\r
-                        catch (Exception ex)\r
-                        {\r
-                            System.err.println("err creating BLOSUM62 tree");\r
-                            ex.printStackTrace();\r
-                        }\r
-                    }\r
-\r
-                    distance[i][j] = (float) score;\r
-\r
-                    if (score > maxscore)\r
-                    {\r
-                        maxscore = score;\r
-                    }\r
-                }\r
-            }\r
-\r
-            for (int i = 0; i < (noseqs - 1); i++)\r
-            {\r
-                for (int j = i; j < noseqs; j++)\r
-                {\r
-                    distance[i][j] = (float) maxscore - distance[i][j];\r
-                    distance[j][i] = distance[i][j];\r
-                }\r
-            }\r
-        }\r
-        else if (pwtype.equals("SW"))\r
-        {\r
-            float max = -1;\r
-\r
-            for (int i = 0; i < (noseqs - 1); i++)\r
-            {\r
-                for (int j = i; j < noseqs; j++)\r
-                {\r
-                    AlignSeq as = new AlignSeq(sequence[i], sequence[j], "pep");\r
-                    as.calcScoreMatrix();\r
-                    as.traceAlignment();\r
-                    as.printAlignment(System.out);\r
-                    distance[i][j] = (float) as.maxscore;\r
-\r
-                    if (max < distance[i][j])\r
-                    {\r
-                        max = distance[i][j];\r
-                    }\r
-                }\r
-            }\r
-\r
-            for (int i = 0; i < (noseqs - 1); i++)\r
-            {\r
-                for (int j = i; j < noseqs; j++)\r
-                {\r
-                    distance[i][j] = max - distance[i][j];\r
-                    distance[j][i] = distance[i][j];\r
-                }\r
-            }\r
-        }\r
-\r
-        return distance;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void makeLeaves()\r
-    {\r
-        cluster = new Vector();\r
-\r
-        for (int i = 0; i < noseqs; i++)\r
-        {\r
-            SequenceNode sn = new SequenceNode();\r
-\r
-            sn.setElement(sequence[i]);\r
-            sn.setName(sequence[i].getName());\r
-            node.addElement(sn);\r
-\r
-            int[] value = new int[1];\r
-            value[0] = i;\r
-\r
-            Cluster c = new Cluster(value);\r
-            cluster.addElement(c);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param leaves DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector findLeaves(SequenceNode node, Vector leaves)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return leaves;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            leaves.addElement(node);\r
-\r
-            return leaves;\r
-        }\r
-        else\r
-        {\r
-            findLeaves((SequenceNode) node.left(), leaves);\r
-            findLeaves((SequenceNode) node.right(), leaves);\r
-        }\r
-\r
-        return leaves;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param count DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Object findLeaf(SequenceNode node, int count)\r
-    {\r
-        found = _findLeaf(node, count);\r
-\r
-        return found;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param count DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Object _findLeaf(SequenceNode node, int count)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return null;\r
-        }\r
-\r
-        if (node.ycount == count)\r
-        {\r
-            found = node.element();\r
-\r
-            return found;\r
-        }\r
-        else\r
-        {\r
-            _findLeaf((SequenceNode) node.left(), count);\r
-            _findLeaf((SequenceNode) node.right(), count);\r
-        }\r
-\r
-        return found;\r
-    }\r
-\r
-    /**\r
-     * printNode is mainly for debugging purposes.\r
-     *\r
-     * @param node SequenceNode\r
-     */\r
-    public void printNode(SequenceNode node)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            System.out.println("Leaf = " +\r
-                ((SequenceI) node.element()).getName());\r
-            System.out.println("Dist " + ((SequenceNode) node).dist);\r
-            System.out.println("Boot " + node.getBootstrap());\r
-        }\r
-        else\r
-        {\r
-            System.out.println("Dist " + ((SequenceNode) node).dist);\r
-            printNode((SequenceNode) node.left());\r
-            printNode((SequenceNode) node.right());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     */\r
-    public void findMaxDist(SequenceNode node)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            float dist = ((SequenceNode) node).dist;\r
-\r
-            if (dist > maxDistValue)\r
-            {\r
-                maxdist = (SequenceNode) node;\r
-                maxDistValue = dist;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            findMaxDist((SequenceNode) node.left());\r
-            findMaxDist((SequenceNode) node.right());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getGroups()\r
-    {\r
-        return groups;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float getMaxHeight()\r
-    {\r
-        return maxheight;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param threshold DOCUMENT ME!\r
-     */\r
-    public void groupNodes(SequenceNode node, float threshold)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.height / maxheight) > threshold)\r
-        {\r
-            groups.addElement(node);\r
-        }\r
-        else\r
-        {\r
-            groupNodes((SequenceNode) node.left(), threshold);\r
-            groupNodes((SequenceNode) node.right(), threshold);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float findHeight(SequenceNode node)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return maxheight;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            node.height = ((SequenceNode) node.parent()).height + node.dist;\r
-\r
-            if (node.height > maxheight)\r
-            {\r
-                return node.height;\r
-            }\r
-            else\r
-            {\r
-                return maxheight;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            if (node.parent() != null)\r
-            {\r
-                node.height = ((SequenceNode) node.parent()).height +\r
-                    node.dist;\r
-            }\r
-            else\r
-            {\r
-                maxheight = 0;\r
-                node.height = (float) 0.0;\r
-            }\r
-\r
-            maxheight = findHeight((SequenceNode) (node.left()));\r
-            maxheight = findHeight((SequenceNode) (node.right()));\r
-        }\r
-\r
-        return maxheight;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceNode reRoot()\r
-    {\r
-        if (maxdist != null)\r
-        {\r
-            ycount = 0;\r
-\r
-            float tmpdist = maxdist.dist;\r
-\r
-            // New top\r
-            SequenceNode sn = new SequenceNode();\r
-            sn.setParent(null);\r
-\r
-            // New right hand of top\r
-            SequenceNode snr = (SequenceNode) maxdist.parent();\r
-            changeDirection(snr, maxdist);\r
-            System.out.println("Printing reversed tree");\r
-            printN(snr);\r
-            snr.dist = tmpdist / 2;\r
-            maxdist.dist = tmpdist / 2;\r
-\r
-            snr.setParent(sn);\r
-            maxdist.setParent(sn);\r
-\r
-            sn.setRight(snr);\r
-            sn.setLeft(maxdist);\r
-\r
-            top = sn;\r
-\r
-            ycount = 0;\r
-            reCount(top);\r
-            findHeight(top);\r
-        }\r
-\r
-        return top;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     */\r
-    public static void printN(SequenceNode node)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() != null) && (node.right() != null))\r
-        {\r
-            printN((SequenceNode) node.left());\r
-            printN((SequenceNode) node.right());\r
-        }\r
-        else\r
-        {\r
-            System.out.println(" name = " +\r
-                ((SequenceI) node.element()).getName());\r
-        }\r
-\r
-        System.out.println(" dist = " + ((SequenceNode) node).dist + " " +\r
-            ((SequenceNode) node).count + " " + ((SequenceNode) node).height);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     */\r
-    public void reCount(SequenceNode node)\r
-    {\r
-        ycount = 0;\r
-        _reCount(node);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     */\r
-    public void _reCount(SequenceNode node)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() != null) && (node.right() != null))\r
-        {\r
-            _reCount((SequenceNode) node.left());\r
-            _reCount((SequenceNode) node.right());\r
-\r
-            SequenceNode l = (SequenceNode) node.left();\r
-            SequenceNode r = (SequenceNode) node.right();\r
-\r
-            ((SequenceNode) node).count = l.count + r.count;\r
-            ((SequenceNode) node).ycount = (l.ycount + r.ycount) / 2;\r
-        }\r
-        else\r
-        {\r
-            ((SequenceNode) node).count = 1;\r
-            ((SequenceNode) node).ycount = ycount++;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     */\r
-    public void swapNodes(SequenceNode node)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        SequenceNode tmp = (SequenceNode) node.left();\r
-\r
-        node.setLeft(node.right());\r
-        node.setRight(tmp);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param dir DOCUMENT ME!\r
-     */\r
-    public void changeDirection(SequenceNode node, SequenceNode dir)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if (node.parent() != top)\r
-        {\r
-            changeDirection((SequenceNode) node.parent(), node);\r
-\r
-            SequenceNode tmp = (SequenceNode) node.parent();\r
-\r
-            if (dir == node.left())\r
-            {\r
-                node.setParent(dir);\r
-                node.setLeft(tmp);\r
-            }\r
-            else if (dir == node.right())\r
-            {\r
-                node.setParent(dir);\r
-                node.setRight(tmp);\r
-            }\r
-        }\r
-        else\r
-        {\r
-            if (dir == node.left())\r
-            {\r
-                node.setParent(node.left());\r
-\r
-                if (top.left() == node)\r
-                {\r
-                    node.setRight(top.right());\r
-                }\r
-                else\r
-                {\r
-                    node.setRight(top.left());\r
-                }\r
-            }\r
-            else\r
-            {\r
-                node.setParent(node.right());\r
-\r
-                if (top.left() == node)\r
-                {\r
-                    node.setLeft(top.right());\r
-                }\r
-                else\r
-                {\r
-                    node.setLeft(top.left());\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceNode getMaxDist()\r
-    {\r
-        return maxdist;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceNode getTopNode()\r
-    {\r
-        return top;\r
-    }\r
-    /**\r
-     *\r
-     * @return true if tree has real distances\r
-     */\r
-    public boolean isHasDistances() {\r
-      return hasDistances;\r
-    }\r
-\r
-    /**\r
-     *\r
-     * @return true if tree has real bootstrap values\r
-     */\r
-    public boolean isHasBootstrap() {\r
-      return hasBootstrap;\r
-    }\r
-\r
-  public boolean isHasRootDistance()\r
-  {\r
-    return hasRootDistance;\r
-  }\r
-\r
-}\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-class Cluster\r
-{\r
-    int[] value;\r
-\r
-    /**\r
-     * Creates a new Cluster object.\r
-     *\r
-     * @param value DOCUMENT ME!\r
-     */\r
-    public Cluster(int[] value)\r
-    {\r
-        this.value = value;\r
-    }\r
-}\r
-\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.analysis;
+
+import jalview.datamodel.*;
+
+import jalview.io.NewickFile;
+
+import jalview.schemes.ResidueProperties;
+
+import jalview.util.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class NJTree
+{
+    Vector cluster;
+    SequenceI[] sequence;
+
+    //SequenceData is a string representation of what the user
+    //sees. The display may contain hidden columns.
+    public AlignmentView seqData=null;
+
+    int[] done;
+    int noseqs;
+    int noClus;
+    float[][] distance;
+    int mini;
+    int minj;
+    float ri;
+    float rj;
+    Vector groups = new Vector();
+    SequenceNode maxdist;
+    SequenceNode top;
+    float maxDistValue;
+    float maxheight;
+    int ycount;
+    Vector node;
+    String type;
+    String pwtype;
+    Object found = null;
+    Object leaves = null;
+
+    boolean hasDistances = true; // normal case for jalview trees
+    boolean hasBootstrap = false; // normal case for jalview trees
+
+    private boolean hasRootDistance = true;
+
+    /**
+     * Create a new NJTree object with leaves associated with sequences in seqs,
+     * and original alignment data represented by Cigar strings.
+     * @param seqs SequenceI[]
+     * @param odata Cigar[]
+     * @param treefile NewickFile
+     */
+    public NJTree(SequenceI[] seqs, AlignmentView odata, NewickFile treefile) {
+      this(seqs, treefile);
+      if (odata!=null)
+        seqData = odata;
+      /*
+      sequenceString = new String[odata.length];
+      char gapChar = jalview.util.Comparison.GapChars.charAt(0);
+      for (int i = 0; i < odata.length; i++)
+      {
+        SequenceI oseq_aligned = odata[i].getSeq(gapChar);
+          sequenceString[i] = oseq_aligned.getSequence();
+      } */
+    }
+
+    /**
+     * Creates a new NJTree object from a tree from an external source
+     *
+     * @param seqs SequenceI which should be associated with leafs of treefile
+     * @param treefile A parsed tree
+     */
+    public NJTree(SequenceI[] seqs,  NewickFile treefile)
+    {
+        this.sequence = seqs;
+        top = treefile.getTree();
+
+        /**
+         * There is no dependent alignment to be recovered from an
+         * imported tree.
+         *
+        if (sequenceString == null)
+        {
+          sequenceString = new String[seqs.length];
+          for (int i = 0; i < seqs.length; i++)
+          {
+            sequenceString[i] = seqs[i].getSequence();
+          }
+        }
+        */
+
+        hasDistances = treefile.HasDistances();
+        hasBootstrap = treefile.HasBootstrap();
+        hasRootDistance = treefile.HasRootDistance();
+
+        maxheight = findHeight(top);
+
+        SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs);
+
+        Vector leaves = new Vector();
+        findLeaves(top, leaves);
+
+        int i = 0;
+        int namesleft = seqs.length;
+
+        SequenceNode j;
+        SequenceI nam;
+        String realnam;
+
+        while (i < leaves.size())
+        {
+            j = (SequenceNode) leaves.elementAt(i++);
+            realnam = j.getName();
+            nam = null;
+
+            if (namesleft > -1)
+            {
+                nam = algnIds.findIdMatch(realnam);
+            }
+
+            if (nam != null)
+            {
+                j.setElement(nam);
+                namesleft--;
+            }
+            else
+            {
+                j.setElement(new Sequence(realnam, "THISISAPLACEHLDER"));
+                j.setPlaceholder(true);
+            }
+        }
+    }
+
+    /**
+     * Creates a new NJTree object.
+     *
+     * @param sequence DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     * @param pwtype DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     */
+    public NJTree(SequenceI[] sequence,
+                  AlignmentView seqData,
+                  String type,
+                  String pwtype,
+                  int start, int end)
+    {
+        this.sequence = sequence;
+        this.node = new Vector();
+        this.type = type;
+        this.pwtype = pwtype;
+        if (seqData!=null) {
+          this.seqData = seqData;
+        } else {
+          SeqCigar[] seqs = new SeqCigar[sequence.length];
+          for(int i=0; i<sequence.length; i++)
+            {
+              seqs[i] = new SeqCigar(sequence[i], start, end);
+            }
+            CigarArray sdata = new CigarArray(seqs);
+            sdata.addOperation(CigarArray.M, end-start+1);
+            this.seqData = new AlignmentView(sdata);
+        }
+
+        if (!(type.equals("NJ")))
+        {
+            type = "AV";
+        }
+
+        if (!(pwtype.equals("PID")))
+        {
+            type = "BL";
+        }
+
+        int i = 0;
+
+        done = new int[sequence.length];
+
+        while ((i < sequence.length) && (sequence[i] != null))
+        {
+            done[i] = 0;
+            i++;
+        }
+
+        noseqs = i++;
+
+        distance = findDistances(this.seqData.getSequenceStrings(Comparison.GapChars.charAt(0)));
+
+        makeLeaves();
+
+        noClus = cluster.size();
+
+        cluster();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String toString()
+    {
+        jalview.io.NewickFile fout = new jalview.io.NewickFile(getTopNode());
+
+        return fout.print(false, true); // distances only
+    }
+
+    /**
+     *
+     * used when the alignment associated to a tree has changed.
+     *
+     * @param alignment Vector
+     */
+    public void UpdatePlaceHolders(Vector alignment)
+    {
+        Vector leaves = new Vector();
+        findLeaves(top, leaves);
+
+        int sz = leaves.size();
+        SequenceIdMatcher seqmatcher = null;
+        int i = 0;
+
+        while (i < sz)
+        {
+            SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);
+
+            if (alignment.contains(leaf.element()))
+            {
+                leaf.setPlaceholder(false);
+            }
+            else
+            {
+                if (seqmatcher == null)
+                {
+                    // Only create this the first time we need it
+                    SequenceI[] seqs = new SequenceI[alignment.size()];
+
+                    for (int j = 0; j < seqs.length; j++)
+                        seqs[j] = (SequenceI) alignment.elementAt(j);
+
+                    seqmatcher = new SequenceIdMatcher(seqs);
+                }
+
+                SequenceI nam = seqmatcher.findIdMatch(leaf.getName());
+
+                if (nam != null)
+                {
+                    leaf.setPlaceholder(false);
+                    leaf.setElement(nam);
+                }
+                else
+                {
+                    leaf.setPlaceholder(true);
+                }
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void cluster()
+    {
+        while (noClus > 2)
+        {
+            if (type.equals("NJ"))
+            {
+                findMinNJDistance();
+            }
+            else
+            {
+                findMinDistance();
+            }
+
+            Cluster c = joinClusters(mini, minj);
+
+            done[minj] = 1;
+
+            cluster.setElementAt(null, minj);
+            cluster.setElementAt(c, mini);
+
+            noClus--;
+        }
+
+        boolean onefound = false;
+
+        int one = -1;
+        int two = -1;
+
+        for (int i = 0; i < noseqs; i++)
+        {
+            if (done[i] != 1)
+            {
+                if (onefound == false)
+                {
+                    two = i;
+                    onefound = true;
+                }
+                else
+                {
+                    one = i;
+                }
+            }
+        }
+
+        joinClusters(one, two);
+        top = (SequenceNode) (node.elementAt(one));
+
+        reCount(top);
+        findHeight(top);
+        findMaxDist(top);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Cluster joinClusters(int i, int j)
+    {
+        float dist = distance[i][j];
+
+        int noi = ((Cluster) cluster.elementAt(i)).value.length;
+        int noj = ((Cluster) cluster.elementAt(j)).value.length;
+
+        int[] value = new int[noi + noj];
+
+        for (int ii = 0; ii < noi; ii++)
+        {
+            value[ii] = ((Cluster) cluster.elementAt(i)).value[ii];
+        }
+
+        for (int ii = noi; ii < (noi + noj); ii++)
+        {
+            value[ii] = ((Cluster) cluster.elementAt(j)).value[ii - noi];
+        }
+
+        Cluster c = new Cluster(value);
+
+        ri = findr(i, j);
+        rj = findr(j, i);
+
+        if (type.equals("NJ"))
+        {
+            findClusterNJDistance(i, j);
+        }
+        else
+        {
+            findClusterDistance(i, j);
+        }
+
+        SequenceNode sn = new SequenceNode();
+
+        sn.setLeft((SequenceNode) (node.elementAt(i)));
+        sn.setRight((SequenceNode) (node.elementAt(j)));
+
+        SequenceNode tmpi = (SequenceNode) (node.elementAt(i));
+        SequenceNode tmpj = (SequenceNode) (node.elementAt(j));
+
+        if (type.equals("NJ"))
+        {
+            findNewNJDistances(tmpi, tmpj, dist);
+        }
+        else
+        {
+            findNewDistances(tmpi, tmpj, dist);
+        }
+
+        tmpi.setParent(sn);
+        tmpj.setParent(sn);
+
+        node.setElementAt(sn, i);
+
+        return c;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param tmpi DOCUMENT ME!
+     * @param tmpj DOCUMENT ME!
+     * @param dist DOCUMENT ME!
+     */
+    public void findNewNJDistances(SequenceNode tmpi, SequenceNode tmpj,
+        float dist)
+    {
+
+        tmpi.dist = ((dist + ri) - rj) / 2;
+        tmpj.dist = (dist - tmpi.dist);
+
+        if (tmpi.dist < 0)
+        {
+            tmpi.dist = 0;
+        }
+
+        if (tmpj.dist < 0)
+        {
+            tmpj.dist = 0;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param tmpi DOCUMENT ME!
+     * @param tmpj DOCUMENT ME!
+     * @param dist DOCUMENT ME!
+     */
+    public void findNewDistances(SequenceNode tmpi, SequenceNode tmpj,
+        float dist)
+    {
+        float ih = 0;
+        float jh = 0;
+
+        SequenceNode sni = tmpi;
+        SequenceNode snj = tmpj;
+
+        while (sni != null)
+        {
+            ih = ih + sni.dist;
+            sni = (SequenceNode) sni.left();
+        }
+
+        while (snj != null)
+        {
+            jh = jh + snj.dist;
+            snj = (SequenceNode) snj.left();
+        }
+
+        tmpi.dist = ((dist / 2) - ih);
+        tmpj.dist = ((dist / 2) - jh);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     */
+    public void findClusterDistance(int i, int j)
+    {
+        int noi = ((Cluster) cluster.elementAt(i)).value.length;
+        int noj = ((Cluster) cluster.elementAt(j)).value.length;
+
+        // New distances from cluster to others
+        float[] newdist = new float[noseqs];
+
+        for (int l = 0; l < noseqs; l++)
+        {
+            if ((l != i) && (l != j))
+            {
+                newdist[l] = ((distance[i][l] * noi) + (distance[j][l] * noj)) / (noi +
+                    noj);
+            }
+            else
+            {
+                newdist[l] = 0;
+            }
+        }
+
+        for (int ii = 0; ii < noseqs; ii++)
+        {
+            distance[i][ii] = newdist[ii];
+            distance[ii][i] = newdist[ii];
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     */
+    public void findClusterNJDistance(int i, int j)
+    {
+
+        // New distances from cluster to others
+        float[] newdist = new float[noseqs];
+
+        for (int l = 0; l < noseqs; l++)
+        {
+            if ((l != i) && (l != j))
+            {
+                newdist[l] = ((distance[i][l] + distance[j][l]) -
+                    distance[i][j]) / 2;
+            }
+            else
+            {
+                newdist[l] = 0;
+            }
+        }
+
+        for (int ii = 0; ii < noseqs; ii++)
+        {
+            distance[i][ii] = newdist[ii];
+            distance[ii][i] = newdist[ii];
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float findr(int i, int j)
+    {
+        float tmp = 1;
+
+        for (int k = 0; k < noseqs; k++)
+        {
+            if ((k != i) && (k != j) && (done[k] != 1))
+            {
+                tmp = tmp + distance[i][k];
+            }
+        }
+
+        if (noClus > 2)
+        {
+            tmp = tmp / (noClus - 2);
+        }
+
+        return tmp;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float findMinNJDistance()
+    {
+        float min = 100000;
+
+        for (int i = 0; i < (noseqs - 1); i++)
+        {
+            for (int j = i + 1; j < noseqs; j++)
+            {
+                if ((done[i] != 1) && (done[j] != 1))
+                {
+                    float tmp = distance[i][j] - (findr(i, j) + findr(j, i));
+
+                    if (tmp < min)
+                    {
+                        mini = i;
+                        minj = j;
+
+                        min = tmp;
+                    }
+                }
+            }
+        }
+
+        return min;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float findMinDistance()
+    {
+        float min = 100000;
+
+        for (int i = 0; i < (noseqs - 1); i++)
+        {
+            for (int j = i + 1; j < noseqs; j++)
+            {
+                if ((done[i] != 1) && (done[j] != 1))
+                {
+                    if (distance[i][j] < min)
+                    {
+                        mini = i;
+                        minj = j;
+
+                        min = distance[i][j];
+                    }
+                }
+            }
+        }
+
+        return min;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float[][] findDistances(String[] sequenceString)
+    {
+        float[][] distance = new float[noseqs][noseqs];
+
+        if (pwtype.equals("PID"))
+        {
+            for (int i = 0; i < (noseqs - 1); i++)
+            {
+                for (int j = i; j < noseqs; j++)
+                {
+                    if (j == i)
+                    {
+                        distance[i][i] = 0;
+                    }
+                    else
+                    {
+                        distance[i][j] = 100 -
+                             Comparison.PID(sequenceString[i], sequenceString[j]);
+
+                        distance[j][i] = distance[i][j];
+                    }
+                }
+            }
+        }
+        else if (pwtype.equals("BL"))
+        {
+            int maxscore = 0;
+            int end = sequenceString[0].length();
+            for (int i = 0; i < (noseqs - 1); i++)
+            {
+                for (int j = i; j < noseqs; j++)
+                {
+                    int score = 0;
+
+                    for (int k = 0; k < end; k++)
+                    {
+                        try
+                        {
+                            score += ResidueProperties.getBLOSUM62(
+                              sequenceString[i].substring(k, k + 1),
+                              sequenceString[j].substring(k, k + 1));
+                        }
+                        catch (Exception ex)
+                        {
+                            System.err.println("err creating BLOSUM62 tree");
+                            ex.printStackTrace();
+                        }
+                    }
+
+                    distance[i][j] = (float) score;
+
+                    if (score > maxscore)
+                    {
+                        maxscore = score;
+                    }
+                }
+            }
+
+            for (int i = 0; i < (noseqs - 1); i++)
+            {
+                for (int j = i; j < noseqs; j++)
+                {
+                    distance[i][j] = (float) maxscore - distance[i][j];
+                    distance[j][i] = distance[i][j];
+                }
+            }
+        }
+      /*  else if (pwtype.equals("SW"))
+        {
+            float max = -1;
+
+            for (int i = 0; i < (noseqs - 1); i++)
+            {
+                for (int j = i; j < noseqs; j++)
+                {
+                    AlignSeq as = new AlignSeq(sequence[i], sequence[j], "pep");
+                    as.calcScoreMatrix();
+                    as.traceAlignment();
+                    as.printAlignment(System.out);
+                    distance[i][j] = (float) as.maxscore;
+
+                    if (max < distance[i][j])
+                    {
+                        max = distance[i][j];
+                    }
+                }
+            }
+
+            for (int i = 0; i < (noseqs - 1); i++)
+            {
+                for (int j = i; j < noseqs; j++)
+                {
+                    distance[i][j] = max - distance[i][j];
+                    distance[j][i] = distance[i][j];
+                }
+            }
+        }/*/
+
+        return distance;
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void makeLeaves()
+    {
+        cluster = new Vector();
+
+        for (int i = 0; i < noseqs; i++)
+        {
+            SequenceNode sn = new SequenceNode();
+
+            sn.setElement(sequence[i]);
+            sn.setName(sequence[i].getName());
+            node.addElement(sn);
+
+            int[] value = new int[1];
+            value[0] = i;
+
+            Cluster c = new Cluster(value);
+            cluster.addElement(c);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param leaves DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector findLeaves(SequenceNode node, Vector leaves)
+    {
+        if (node == null)
+        {
+            return leaves;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            leaves.addElement(node);
+
+            return leaves;
+        }
+        else
+        {
+            findLeaves((SequenceNode) node.left(), leaves);
+            findLeaves((SequenceNode) node.right(), leaves);
+        }
+
+        return leaves;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param count DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Object findLeaf(SequenceNode node, int count)
+    {
+        found = _findLeaf(node, count);
+
+        return found;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param count DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Object _findLeaf(SequenceNode node, int count)
+    {
+        if (node == null)
+        {
+            return null;
+        }
+
+        if (node.ycount == count)
+        {
+            found = node.element();
+
+            return found;
+        }
+        else
+        {
+            _findLeaf((SequenceNode) node.left(), count);
+            _findLeaf((SequenceNode) node.right(), count);
+        }
+
+        return found;
+    }
+
+    /**
+     * printNode is mainly for debugging purposes.
+     *
+     * @param node SequenceNode
+     */
+    public void printNode(SequenceNode node)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            System.out.println("Leaf = " +
+                ((SequenceI) node.element()).getName());
+            System.out.println("Dist " + ((SequenceNode) node).dist);
+            System.out.println("Boot " + node.getBootstrap());
+        }
+        else
+        {
+            System.out.println("Dist " + ((SequenceNode) node).dist);
+            printNode((SequenceNode) node.left());
+            printNode((SequenceNode) node.right());
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     */
+    public void findMaxDist(SequenceNode node)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            float dist = ((SequenceNode) node).dist;
+
+            if (dist > maxDistValue)
+            {
+                maxdist = (SequenceNode) node;
+                maxDistValue = dist;
+            }
+        }
+        else
+        {
+            findMaxDist((SequenceNode) node.left());
+            findMaxDist((SequenceNode) node.right());
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getGroups()
+    {
+        return groups;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float getMaxHeight()
+    {
+        return maxheight;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param threshold DOCUMENT ME!
+     */
+    public void groupNodes(SequenceNode node, float threshold)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.height / maxheight) > threshold)
+        {
+            groups.addElement(node);
+        }
+        else
+        {
+            groupNodes((SequenceNode) node.left(), threshold);
+            groupNodes((SequenceNode) node.right(), threshold);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float findHeight(SequenceNode node)
+    {
+        if (node == null)
+        {
+            return maxheight;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            node.height = ((SequenceNode) node.parent()).height + node.dist;
+
+            if (node.height > maxheight)
+            {
+                return node.height;
+            }
+            else
+            {
+                return maxheight;
+            }
+        }
+        else
+        {
+            if (node.parent() != null)
+            {
+                node.height = ((SequenceNode) node.parent()).height +
+                    node.dist;
+            }
+            else
+            {
+                maxheight = 0;
+                node.height = (float) 0.0;
+            }
+
+            maxheight = findHeight((SequenceNode) (node.left()));
+            maxheight = findHeight((SequenceNode) (node.right()));
+        }
+
+        return maxheight;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceNode reRoot()
+    {
+        if (maxdist != null)
+        {
+            ycount = 0;
+
+            float tmpdist = maxdist.dist;
+
+            // New top
+            SequenceNode sn = new SequenceNode();
+            sn.setParent(null);
+
+            // New right hand of top
+            SequenceNode snr = (SequenceNode) maxdist.parent();
+            changeDirection(snr, maxdist);
+            System.out.println("Printing reversed tree");
+            printN(snr);
+            snr.dist = tmpdist / 2;
+            maxdist.dist = tmpdist / 2;
+
+            snr.setParent(sn);
+            maxdist.setParent(sn);
+
+            sn.setRight(snr);
+            sn.setLeft(maxdist);
+
+            top = sn;
+
+            ycount = 0;
+            reCount(top);
+            findHeight(top);
+        }
+
+        return top;
+    }
+    /**
+     *
+     * @return true if original sequence data can be recovered
+     */
+    public boolean hasOriginalSequenceData() {
+      return seqData!=null;
+    }
+    /**
+     * Returns original alignment data used for calculation - or null where
+     * not available.
+     *
+     * @return null or cut'n'pasteable alignment
+     */
+    public String printOriginalSequenceData(char gapChar)
+    {
+      if (seqData==null)
+        return null;
+
+      StringBuffer sb = new StringBuffer();
+      String[] seqdatas = seqData.getSequenceStrings(gapChar);
+      for(int i=0; i<seqdatas.length; i++)
+      {
+        sb.append(new jalview.util.Format("%-" + 15 + "s").form(
+            sequence[i].getName()));
+        sb.append(" "+seqdatas[i]+"\n");
+      }
+      return sb.toString();
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     */
+    public void printN(SequenceNode node)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() != null) && (node.right() != null))
+        {
+            printN((SequenceNode) node.left());
+            printN((SequenceNode) node.right());
+        }
+        else
+        {
+            System.out.println(" name = " +
+                ((SequenceI) node.element()).getName());
+        }
+
+        System.out.println(" dist = " + ((SequenceNode) node).dist + " " +
+            ((SequenceNode) node).count + " " + ((SequenceNode) node).height);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     */
+    public void reCount(SequenceNode node)
+    {
+        ycount = 0;
+        _reCount(node);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     */
+    public void _reCount(SequenceNode node)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() != null) && (node.right() != null))
+        {
+            _reCount((SequenceNode) node.left());
+            _reCount((SequenceNode) node.right());
+
+            SequenceNode l = (SequenceNode) node.left();
+            SequenceNode r = (SequenceNode) node.right();
+
+            ((SequenceNode) node).count = l.count + r.count;
+            ((SequenceNode) node).ycount = (l.ycount + r.ycount) / 2;
+        }
+        else
+        {
+            ((SequenceNode) node).count = 1;
+            ((SequenceNode) node).ycount = ycount++;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     */
+    public void swapNodes(SequenceNode node)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        SequenceNode tmp = (SequenceNode) node.left();
+
+        node.setLeft(node.right());
+        node.setRight(tmp);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param dir DOCUMENT ME!
+     */
+    public void changeDirection(SequenceNode node, SequenceNode dir)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if (node.parent() != top)
+        {
+            changeDirection((SequenceNode) node.parent(), node);
+
+            SequenceNode tmp = (SequenceNode) node.parent();
+
+            if (dir == node.left())
+            {
+                node.setParent(dir);
+                node.setLeft(tmp);
+            }
+            else if (dir == node.right())
+            {
+                node.setParent(dir);
+                node.setRight(tmp);
+            }
+        }
+        else
+        {
+            if (dir == node.left())
+            {
+                node.setParent(node.left());
+
+                if (top.left() == node)
+                {
+                    node.setRight(top.right());
+                }
+                else
+                {
+                    node.setRight(top.left());
+                }
+            }
+            else
+            {
+                node.setParent(node.right());
+
+                if (top.left() == node)
+                {
+                    node.setLeft(top.right());
+                }
+                else
+                {
+                    node.setLeft(top.left());
+                }
+            }
+        }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceNode getMaxDist()
+    {
+        return maxdist;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceNode getTopNode()
+    {
+        return top;
+    }
+    /**
+     *
+     * @return true if tree has real distances
+     */
+    public boolean isHasDistances() {
+      return hasDistances;
+    }
+
+    /**
+     *
+     * @return true if tree has real bootstrap values
+     */
+    public boolean isHasBootstrap() {
+      return hasBootstrap;
+    }
+
+  public boolean isHasRootDistance()
+  {
+    return hasRootDistance;
+  }
+
+}
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+class Cluster
+{
+    int[] value;
+
+    /**
+     * Creates a new Cluster object.
+     *
+     * @param value DOCUMENT ME!
+     */
+    public Cluster(int[] value)
+    {
+        this.value = value;
+    }
+}
+
index 4e7100d..4c96f69 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.analysis;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.math.*;\r
-\r
-import java.io.*;\r
-\r
-/**\r
- * Performs Principal Component Analysis on given sequences\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class PCA implements Runnable\r
-{\r
-    Matrix m;\r
-    Matrix symm;\r
-    Matrix m2;\r
-    double[] eigenvalue;\r
-    Matrix eigenvector;\r
-    StringBuffer details = new StringBuffer();\r
-\r
-\r
-    /**\r
-     * Creates a new PCA object.\r
-     *\r
-     * @param s Set of sequences to perform PCA on\r
-     */\r
-    public PCA(SequenceI[] s)\r
-    {\r
-\r
-        BinarySequence[] bs = new BinarySequence[s.length];\r
-        int ii = 0;\r
-\r
-        while ((ii < s.length) && (s[ii] != null))\r
-        {\r
-            bs[ii] = new BinarySequence(s[ii]);\r
-            bs[ii].encode();\r
-            ii++;\r
-        }\r
-\r
-        BinarySequence[] bs2 = new BinarySequence[s.length];\r
-        ii = 0;\r
-\r
-        while ((ii < s.length) && (s[ii] != null))\r
-        {\r
-            bs2[ii] = new BinarySequence(s[ii]);\r
-            bs2[ii].blosumEncode();\r
-            ii++;\r
-        }\r
-\r
-        //System.out.println("Created binary encoding");\r
-        //printMemory(rt);\r
-        int count = 0;\r
-\r
-        while ((count < bs.length) && (bs[count] != null))\r
-        {\r
-            count++;\r
-        }\r
-\r
-        double[][] seqmat = new double[count][bs[0].getDBinary().length];\r
-        double[][] seqmat2 = new double[count][bs2[0].getDBinary().length];\r
-        int i = 0;\r
-\r
-        while (i < count)\r
-        {\r
-            seqmat[i] = bs[i].getDBinary();\r
-            seqmat2[i] = bs2[i].getDBinary();\r
-            i++;\r
-        }\r
-\r
-        //System.out.println("Created array");\r
-        //printMemory(rt);\r
-        //    System.out.println(" --- Original matrix ---- ");\r
-        m = new Matrix(seqmat, count, bs[0].getDBinary().length);\r
-        m2 = new Matrix(seqmat2, count, bs2[0].getDBinary().length);\r
-\r
-      }\r
-\r
-      /**\r
-       * Returns the matrix used in PCA calculation\r
-       *\r
-       * @return java.math.Matrix object\r
-       */\r
-\r
-      public Matrix getM()\r
-      {\r
-        return m;\r
-      }\r
-\r
-    /**\r
-     * Returns Eigenvalue\r
-     *\r
-     * @param i Index of diagonal within matrix\r
-     *\r
-     * @return Returns value of diagonal from matrix\r
-     */\r
-    public double getEigenvalue(int i)\r
-    {\r
-        return eigenvector.d[i];\r
-    }\r
-\r
-     /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param l DOCUMENT ME!\r
-     * @param n DOCUMENT ME!\r
-     * @param mm DOCUMENT ME!\r
-     * @param factor DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float[][] getComponents(int l, int n, int mm, float factor)\r
-    {\r
-        float[][] out = new float[m.rows][3];\r
-\r
-        for (int i = 0; i < m.rows; i++)\r
-        {\r
-            out[i][0] = (float) component(i, l) * factor;\r
-            out[i][1] = (float) component(i, n) * factor;\r
-            out[i][2] = (float) component(i, mm) * factor;\r
-        }\r
-\r
-        return out;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public double[] component(int n)\r
-    {\r
-        // n = index of eigenvector\r
-        double[] out = new double[m.rows];\r
-\r
-        for (int i = 0; i < m.rows; i++)\r
-        {\r
-            out[i] = component(i, n);\r
-        }\r
-\r
-        return out;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param row DOCUMENT ME!\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    double component(int row, int n)\r
-    {\r
-        double out = 0.0;\r
-\r
-        for (int i = 0; i < symm.cols; i++)\r
-        {\r
-            out += (symm.value[row][i] * eigenvector.value[i][n]);\r
-        }\r
-\r
-        return out / eigenvector.d[n];\r
-    }\r
-\r
-    public String getDetails()\r
-    {\r
-      return details.toString();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void run()\r
-    {\r
-        Matrix mt = m.transpose();\r
-\r
-        details.append(" --- OrigT * Orig ---- \n");\r
-        eigenvector = mt.preMultiply(m2);\r
-\r
-        PrintStream  ps = new PrintStream(System.out)\r
-           {\r
-              public void print(String x) {\r
-                   details.append(x);\r
-               }\r
-               public void println()\r
-               {\r
-                 details.append("\n");\r
-               }\r
-            };\r
-\r
-\r
-        eigenvector.print( ps );\r
-\r
-        symm = eigenvector.copy();\r
-\r
-        eigenvector.tred();\r
-\r
-        details.append(" ---Tridiag transform matrix ---\n");\r
-        details.append(" --- D vector ---\n");\r
-        eigenvector.printD(ps);\r
-        ps.println();\r
-        details.append("--- E vector ---\n");\r
-        eigenvector.printE(ps);\r
-        ps.println();\r
-\r
-        // Now produce the diagonalization matrix\r
-        eigenvector.tqli();\r
-\r
-\r
-        details.append(" --- New diagonalization matrix ---\n");\r
-        details.append(" --- Eigenvalues ---\n");\r
-        eigenvector.printD(ps);\r
-        ps.println();\r
-        //  taps.println();\r
-        //  taps.println("Transformed sequences = ");\r
-        // Matrix trans =  m.preMultiply(eigenvector);\r
-        //  trans.print(System.out);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.analysis;
+
+import jalview.datamodel.*;
+
+import jalview.math.*;
+
+import java.io.*;
+
+/**
+ * Performs Principal Component Analysis on given sequences
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class PCA implements Runnable
+{
+    Matrix m;
+    Matrix symm;
+    Matrix m2;
+    double[] eigenvalue;
+    Matrix eigenvector;
+    StringBuffer details = new StringBuffer();
+
+
+    /**
+     * Creates a new PCA object.
+     *
+     * @param s Set of sequences to perform PCA on
+     */
+    public PCA(String[] s)
+    {
+
+        BinarySequence[] bs = new BinarySequence[s.length];
+        int ii = 0;
+
+        while ((ii < s.length) && (s[ii] != null))
+        {
+            bs[ii] = new BinarySequence(s[ii]);
+            bs[ii].encode();
+            ii++;
+        }
+
+        BinarySequence[] bs2 = new BinarySequence[s.length];
+        ii = 0;
+
+        while ((ii < s.length) && (s[ii] != null))
+        {
+            bs2[ii] = new BinarySequence(s[ii]);
+            bs2[ii].blosumEncode();
+            ii++;
+        }
+
+        //System.out.println("Created binary encoding");
+        //printMemory(rt);
+        int count = 0;
+
+        while ((count < bs.length) && (bs[count] != null))
+        {
+            count++;
+        }
+
+        double[][] seqmat = new double[count][bs[0].getDBinary().length];
+        double[][] seqmat2 = new double[count][bs2[0].getDBinary().length];
+        int i = 0;
+
+        while (i < count)
+        {
+            seqmat[i] = bs[i].getDBinary();
+            seqmat2[i] = bs2[i].getDBinary();
+            i++;
+        }
+
+        //System.out.println("Created array");
+        //printMemory(rt);
+        //    System.out.println(" --- Original matrix ---- ");
+        m = new Matrix(seqmat, count, bs[0].getDBinary().length);
+        m2 = new Matrix(seqmat2, count, bs2[0].getDBinary().length);
+
+      }
+
+      /**
+       * Returns the matrix used in PCA calculation
+       *
+       * @return java.math.Matrix object
+       */
+
+      public Matrix getM()
+      {
+        return m;
+      }
+
+    /**
+     * Returns Eigenvalue
+     *
+     * @param i Index of diagonal within matrix
+     *
+     * @return Returns value of diagonal from matrix
+     */
+    public double getEigenvalue(int i)
+    {
+        return eigenvector.d[i];
+    }
+
+     /**
+     * DOCUMENT ME!
+     *
+     * @param l DOCUMENT ME!
+     * @param n DOCUMENT ME!
+     * @param mm DOCUMENT ME!
+     * @param factor DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float[][] getComponents(int l, int n, int mm, float factor)
+    {
+        float[][] out = new float[m.rows][3];
+
+        for (int i = 0; i < m.rows; i++)
+        {
+            out[i][0] = (float) component(i, l) * factor;
+            out[i][1] = (float) component(i, n) * factor;
+            out[i][2] = (float) component(i, mm) * factor;
+        }
+
+        return out;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public double[] component(int n)
+    {
+        // n = index of eigenvector
+        double[] out = new double[m.rows];
+
+        for (int i = 0; i < m.rows; i++)
+        {
+            out[i] = component(i, n);
+        }
+
+        return out;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param row DOCUMENT ME!
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    double component(int row, int n)
+    {
+        double out = 0.0;
+
+        for (int i = 0; i < symm.cols; i++)
+        {
+            out += (symm.value[row][i] * eigenvector.value[i][n]);
+        }
+
+        return out / eigenvector.d[n];
+    }
+
+    public String getDetails()
+    {
+      return details.toString();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void run()
+    {
+        Matrix mt = m.transpose();
+
+        details.append(" --- OrigT * Orig ---- \n");
+        eigenvector = mt.preMultiply(m2);
+
+        PrintStream  ps = new PrintStream(System.out)
+           {
+              public void print(String x) {
+                   details.append(x);
+               }
+               public void println()
+               {
+                 details.append("\n");
+               }
+            };
+
+
+        eigenvector.print( ps );
+
+        symm = eigenvector.copy();
+
+        eigenvector.tred();
+
+        details.append(" ---Tridiag transform matrix ---\n");
+        details.append(" --- D vector ---\n");
+        eigenvector.printD(ps);
+        ps.println();
+        details.append("--- E vector ---\n");
+        eigenvector.printE(ps);
+        ps.println();
+
+        // Now produce the diagonalization matrix
+        eigenvector.tqli();
+
+
+        details.append(" --- New diagonalization matrix ---\n");
+        details.append(" --- Eigenvalues ---\n");
+        eigenvector.printD(ps);
+        ps.println();
+        //  taps.println();
+        //  taps.println("Transformed sequences = ");
+        // Matrix trans =  m.preMultiply(eigenvector);
+        //  trans.print(System.out);
+    }
+}
index 691b905..f8e9431 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.analysis;\r
-\r
-import java.util.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-/**\r
- * <p>Title: </p>\r
- *\r
- * <p>Description: </p>\r
- *\r
- * <p>Copyright: Copyright (c) 2004</p>\r
- *\r
- * <p>Company: Dundee University</p>\r
- *\r
- * @author not attributable\r
- * @version 1.0\r
- */\r
-public class SeqsetUtils\r
-{\r
-\r
-  /**\r
-   * Store essential properties of a sequence in a hashtable for later recovery\r
-   *  Keys are Name, Start, End, SeqFeatures, PdbId\r
-   * @param seq SequenceI\r
-   * @return Hashtable\r
-   */\r
-  public static Hashtable SeqCharacterHash(SequenceI seq)\r
-  {\r
-    Hashtable sqinfo = new Hashtable();\r
-    sqinfo.put("Name", seq.getName());\r
-    sqinfo.put("Start", new Integer(seq.getStart()));\r
-    sqinfo.put("End", new Integer(seq.getEnd()));\r
-    Vector sfeat = new Vector();\r
-    jalview.datamodel.SequenceFeature[] sfarray=seq.getSequenceFeatures();\r
-    if (sfarray!=null && sfarray.length>0) {\r
-      for (int i=0;i<sfarray.length;i++)\r
-        sfeat.add(sfarray[i]);\r
-    }\r
-    sqinfo.put("SeqFeatures", sfeat);\r
-    sqinfo.put("PdbId",\r
-               (seq.getPDBId() != null) ? seq.getPDBId() : new Vector());\r
-    sqinfo.put("datasetSequence", (seq.getDatasetSequence() !=null) ? seq.getDatasetSequence() : new Sequence("THISISAPLACEHOLDER",""));\r
-    return sqinfo;\r
-  }\r
-\r
-  /**\r
-   * Recover essential properties of a sequence from a hashtable\r
-   * TODO: replace these methods with something more elegant.\r
-   * @param sq SequenceI\r
-   * @param sqinfo Hashtable\r
-   * @return boolean true if name was not updated from sqinfo Name entry\r
-   */\r
-  public static boolean SeqCharacterUnhash(SequenceI sq, Hashtable sqinfo)\r
-  {\r
-    boolean namePresent = true;\r
-    if (sqinfo==null)\r
-      return false;\r
-    String oldname = (String) sqinfo.get("Name");\r
-    Integer start = (Integer) sqinfo.get("Start");\r
-    Integer end = (Integer) sqinfo.get("End");\r
-    Vector sfeatures = (Vector) sqinfo.get(\r
-        "SeqFeatures");\r
-    Vector pdbid = (Vector) sqinfo.get("PdbId");\r
-    Sequence seqds = (Sequence) sqinfo.get("datasetSequence");\r
-    if (oldname == null)\r
-    {\r
-      namePresent = false;\r
-    }\r
-    else\r
-    {\r
-      sq.setName(oldname);\r
-    }\r
-    if (pdbid!=null && pdbid.size()>0)\r
-    {\r
-      sq.setPDBId(pdbid);\r
-    }\r
-\r
-    if ( (start != null) && (end != null))\r
-    {\r
-      sq.setStart(start.intValue());\r
-      sq.setEnd(end.intValue());\r
-    }\r
-\r
-    if ((sfeatures != null) && (sfeatures.size()>0))\r
-    {\r
-      SequenceFeature[] sfarray = (SequenceFeature[]) sfeatures.toArray();\r
-      sq.setSequenceFeatures(sfarray);\r
-    }\r
-\r
-    if ((seqds!=null) && !(seqds.getName().equals("THISISAPLACEHOLDER") && seqds.getLength()==0)) {\r
-      sq.setDatasetSequence(seqds);\r
-    }\r
-\r
-    return namePresent;\r
-  }\r
-\r
-  /**\r
-   * Form of the unique name used in uniquify for the i'th sequence in an ordered vector of sequences.\r
-   * @param i int\r
-   * @return String\r
-   */\r
-  public static String unique_name(int i)\r
-  {\r
-    return new String("Sequence" + i);\r
-  }\r
-\r
-  /**\r
-   * Generates a hash of SeqCharacterHash properties for each sequence\r
-   * in a sequence set, and optionally renames the sequences to an\r
-   * unambiguous 'safe' name.\r
-   * @param sequences SequenceI[]\r
-   * @param write_names boolean set this to rename each of the sequences to its unique_name(index) name\r
-   * @return Hashtable to be passed to @see deuniquify to recover original names (and properties) for renamed sequences\r
-   */\r
-  public static Hashtable uniquify(SequenceI[] sequences, boolean write_names)\r
-  {\r
-    // Generate a safely named sequence set and a hash to recover the sequence names\r
-    Hashtable map = new Hashtable();\r
-    //String[] un_names = new String[sequences.length];\r
-\r
-    for (int i = 0; i < sequences.length; i++)\r
-    {\r
-      String safename = unique_name(i);\r
-      map.put(safename, SeqCharacterHash(sequences[i]));\r
-\r
-      if (write_names)\r
-      {\r
-        sequences[i].setName(safename);\r
-      }\r
-    }\r
-\r
-\r
-    return map;\r
-  }\r
-  /**\r
-   * recover unsafe sequence names and original properties for a sequence\r
-   * set using a map generated by @see uniquify(sequences,true)\r
-   * @param map Hashtable\r
-   * @param sequences SequenceI[]\r
-   * @return boolean\r
-   */\r
-  public static boolean deuniquify(Hashtable map, SequenceI[] sequences)\r
-  {\r
-    jalview.analysis.SequenceIdMatcher matcher = new SequenceIdMatcher(sequences);\r
-    SequenceI msq = null;\r
-    Enumeration keys = map.keys();\r
-    Vector unmatched = new Vector();\r
-    for (int i=0, j=sequences.length; i<j; i++)\r
-      unmatched.add(sequences[i]);\r
-    while (keys.hasMoreElements()) {\r
-      Object key = keys.nextElement();\r
-      if (key instanceof String) {\r
-        if ((msq = matcher.findIdMatch((String) key))!=null) {\r
-          Hashtable sqinfo = (Hashtable) map.get(key);\r
-          unmatched.remove(msq);\r
-          SeqCharacterUnhash(msq, sqinfo);\r
-        }\r
-        else\r
-        {\r
-          System.err.println("Can't find '"+((String) key)+"' in uniquified alignment");\r
-        }\r
-      }\r
-    }\r
-    if (unmatched.size()>0) {\r
-      System.err.println("Did not find matches for :");\r
-      for (Enumeration i = unmatched.elements(); i.hasMoreElements(); System.out.println(((SequenceI) i.nextElement()).getName()))\r
-           ;\r
-      return false;\r
-    }\r
-\r
-    return true;\r
-  }\r
-  /**\r
-   * returns a subset of the sequenceI seuqences,\r
-   * including only those that contain at least one residue.\r
-   * @param sequences SequenceI[]\r
-   * @return SequenceI[]\r
-   */\r
-  public static SequenceI[] getNonEmptySequenceSet(SequenceI[] sequences) {\r
-      // Identify first row of alignment with residues for prediction\r
-      boolean ungapped[] = new boolean[sequences.length];\r
-      int msflen=0;\r
-      for (int i=0,j=sequences.length; i<j;i++) {\r
-        String tempseq = jalview.analysis.AlignSeq.extractGaps(jalview.util.Comparison.GapChars, sequences[i].getSequence());\r
-        if (tempseq.length()==0)\r
-          ungapped[i]=false;\r
-        else {\r
-          ungapped[i]=true;\r
-          msflen++;\r
-        }\r
-      }\r
-      if (msflen==0)\r
-        return null; // no minimal set\r
-      // compose minimal set\r
-      SequenceI[] mset = new SequenceI[msflen];\r
-      for (int i=0,j=sequences.length,k=0; i<j;i++) {\r
-        if (ungapped[i])\r
-          mset[k++] = sequences[i];\r
-      }\r
-      ungapped = null;\r
-      return mset;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.analysis;
+
+import java.util.*;
+
+import jalview.datamodel.*;
+
+/**
+ * <p>Title: </p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2004</p>
+ *
+ * <p>Company: Dundee University</p>
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class SeqsetUtils
+{
+
+  /**
+   * Store essential properties of a sequence in a hashtable for later recovery
+   *  Keys are Name, Start, End, SeqFeatures, PdbId
+   * @param seq SequenceI
+   * @return Hashtable
+   */
+  public static Hashtable SeqCharacterHash(SequenceI seq)
+  {
+    Hashtable sqinfo = new Hashtable();
+    sqinfo.put("Name", seq.getName());
+    sqinfo.put("Start", new Integer(seq.getStart()));
+    sqinfo.put("End", new Integer(seq.getEnd()));
+    Vector sfeat = new Vector();
+    jalview.datamodel.SequenceFeature[] sfarray=seq.getSequenceFeatures();
+    if (sfarray!=null && sfarray.length>0) {
+      for (int i=0;i<sfarray.length;i++)
+        sfeat.add(sfarray[i]);
+    }
+    sqinfo.put("SeqFeatures", sfeat);
+    sqinfo.put("PdbId",
+               (seq.getPDBId() != null) ? seq.getPDBId() : new Vector());
+    sqinfo.put("datasetSequence", (seq.getDatasetSequence() !=null) ? seq.getDatasetSequence() : new Sequence("THISISAPLACEHOLDER",""));
+    return sqinfo;
+  }
+
+  /**
+   * Recover essential properties of a sequence from a hashtable
+   * TODO: replace these methods with something more elegant.
+   * @param sq SequenceI
+   * @param sqinfo Hashtable
+   * @return boolean true if name was not updated from sqinfo Name entry
+   */
+  public static boolean SeqCharacterUnhash(SequenceI sq, Hashtable sqinfo)
+  {
+    boolean namePresent = true;
+    if (sqinfo==null)
+      return false;
+    String oldname = (String) sqinfo.get("Name");
+    Integer start = (Integer) sqinfo.get("Start");
+    Integer end = (Integer) sqinfo.get("End");
+    Vector sfeatures = (Vector) sqinfo.get(
+        "SeqFeatures");
+    Vector pdbid = (Vector) sqinfo.get("PdbId");
+    Sequence seqds = (Sequence) sqinfo.get("datasetSequence");
+    if (oldname == null)
+    {
+      namePresent = false;
+    }
+    else
+    {
+      sq.setName(oldname);
+    }
+    if (pdbid!=null && pdbid.size()>0)
+    {
+      sq.setPDBId(pdbid);
+    }
+
+    if ( (start != null) && (end != null))
+    {
+      sq.setStart(start.intValue());
+      sq.setEnd(end.intValue());
+    }
+
+    if ((sfeatures != null) && (sfeatures.size()>0))
+    {
+      SequenceFeature[] sfarray = (SequenceFeature[]) sfeatures.toArray();
+      sq.setSequenceFeatures(sfarray);
+    }
+
+    if ((seqds!=null) && !(seqds.getName().equals("THISISAPLACEHOLDER") && seqds.getLength()==0)) {
+      sq.setDatasetSequence(seqds);
+    }
+
+    return namePresent;
+  }
+
+  /**
+   * Form of the unique name used in uniquify for the i'th sequence in an ordered vector of sequences.
+   * @param i int
+   * @return String
+   */
+  public static String unique_name(int i)
+  {
+    return new String("Sequence" + i);
+  }
+
+  /**
+   * Generates a hash of SeqCharacterHash properties for each sequence
+   * in a sequence set, and optionally renames the sequences to an
+   * unambiguous 'safe' name.
+   * @param sequences SequenceI[]
+   * @param write_names boolean set this to rename each of the sequences to its unique_name(index) name
+   * @return Hashtable to be passed to @see deuniquify to recover original names (and properties) for renamed sequences
+   */
+  public static Hashtable uniquify(SequenceI[] sequences, boolean write_names)
+  {
+    // Generate a safely named sequence set and a hash to recover the sequence names
+    Hashtable map = new Hashtable();
+    //String[] un_names = new String[sequences.length];
+
+    for (int i = 0; i < sequences.length; i++)
+    {
+      String safename = unique_name(i);
+      map.put(safename, SeqCharacterHash(sequences[i]));
+
+      if (write_names)
+      {
+        sequences[i].setName(safename);
+      }
+    }
+
+
+    return map;
+  }
+  /**
+   * recover unsafe sequence names and original properties for a sequence
+   * set using a map generated by @see uniquify(sequences,true)
+   * @param map Hashtable
+   * @param sequences SequenceI[]
+   * @return boolean
+   */
+  public static boolean deuniquify(Hashtable map, SequenceI[] sequences)
+  {
+    jalview.analysis.SequenceIdMatcher matcher = new SequenceIdMatcher(sequences);
+    SequenceI msq = null;
+    Enumeration keys = map.keys();
+    Vector unmatched = new Vector();
+    for (int i=0, j=sequences.length; i<j; i++)
+      unmatched.add(sequences[i]);
+    while (keys.hasMoreElements()) {
+      Object key = keys.nextElement();
+      if (key instanceof String) {
+        if ((msq = matcher.findIdMatch((String) key))!=null) {
+          Hashtable sqinfo = (Hashtable) map.get(key);
+          unmatched.remove(msq);
+          SeqCharacterUnhash(msq, sqinfo);
+        }
+        else
+        {
+          System.err.println("Can't find '"+((String) key)+"' in uniquified alignment");
+        }
+      }
+    }
+    if (unmatched.size()>0) {
+      System.err.println("Did not find matches for :");
+      for (Enumeration i = unmatched.elements(); i.hasMoreElements(); System.out.println(((SequenceI) i.nextElement()).getName()))
+           ;
+      return false;
+    }
+
+    return true;
+  }
+  /**
+   * returns a subset of the sequenceI seuqences,
+   * including only those that contain at least one residue.
+   * @param sequences SequenceI[]
+   * @return SequenceI[]
+   */
+  public static SequenceI[] getNonEmptySequenceSet(SequenceI[] sequences) {
+      // Identify first row of alignment with residues for prediction
+      boolean ungapped[] = new boolean[sequences.length];
+      int msflen=0;
+      for (int i=0,j=sequences.length; i<j;i++) {
+        String tempseq = jalview.analysis.AlignSeq.extractGaps(jalview.util.Comparison.GapChars, sequences[i].getSequence());
+        if (tempseq.length()==0)
+          ungapped[i]=false;
+        else {
+          ungapped[i]=true;
+          msflen++;
+        }
+      }
+      if (msflen==0)
+        return null; // no minimal set
+      // compose minimal set
+      SequenceI[] mset = new SequenceI[msflen];
+      for (int i=0,j=sequences.length,k=0; i<j;i++) {
+        if (ungapped[i])
+          mset[k++] = sequences[i];
+      }
+      ungapped = null;
+      return mset;
+  }
+}
index 9d33996..2aabc66 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.analysis;\r
-\r
-import java.util.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-/**\r
- * <p>Title: </p>\r
- * SequenceIdMatcher\r
- * <p>Description: </p>\r
- * Routine which does approximate Sequence Id resolution by name using\r
- * string containment (on word boundaries) rather than equivalence\r
- * <p>Copyright: Copyright (c) 2004</p>\r
- *\r
- * <p>Company: Dundee University</p>\r
- *\r
- * @author not attributable\r
- * @version 1.0\r
- */\r
-public class SequenceIdMatcher\r
-{\r
-  private Hashtable names;\r
-\r
-  public SequenceIdMatcher(SequenceI[] seqs)\r
-  {\r
-    names = new Hashtable();\r
-    for (int i = 0; i < seqs.length; i++)\r
-    {\r
-      names.put(new SeqIdName(seqs[i].getName()), seqs[i]);\r
-    }\r
-  }\r
-\r
-  SequenceI findIdMatch(SequenceI seq)\r
-  {\r
-    SeqIdName nam = new SeqIdName(seq.getName());\r
-\r
-    if (names.containsKey(nam))\r
-    {\r
-      return (SequenceI) names.get(nam);\r
-    }\r
-\r
-    return null;\r
-  }\r
-\r
-  SequenceI findIdMatch(String seqnam)\r
-  {\r
-    SeqIdName nam = new SeqIdName(seqnam);\r
-\r
-    if (names.containsKey(nam))\r
-    {\r
-      return (SequenceI) names.get(nam);\r
-    }\r
-\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   * findIdMatch\r
-   *\r
-   * Return pointers to sequences (or sequence object containers)\r
-   * which have same Id as a given set of different sequence objects\r
-   *\r
-   * @param seqs SequenceI[]\r
-   * @return SequenceI[]\r
-   */\r
-  SequenceI[] findIdMatch(SequenceI[] seqs)\r
-  {\r
-    SequenceI[] namedseqs = null;\r
-    int i = 0;\r
-    SeqIdName nam;\r
-\r
-    if (seqs.length > 0)\r
-    {\r
-      namedseqs = new SequenceI[seqs.length];\r
-      do\r
-      {\r
-        nam = new SeqIdName(seqs[i].getName());\r
-\r
-        if (names.containsKey(nam))\r
-        {\r
-          namedseqs[i] = (SequenceI) names.get(nam);\r
-        }\r
-        else\r
-        {\r
-          namedseqs[i] = null;\r
-        }\r
-      }\r
-      while (++i < seqs.length);\r
-    }\r
-\r
-    return namedseqs;\r
-  }\r
-\r
-  private class SeqIdName\r
-  {\r
-    String id;\r
-\r
-    SeqIdName(String s)\r
-    {\r
-      if (s!=null)\r
-        id = new String(s);\r
-      else\r
-        id = "";\r
-    }\r
-\r
-    public int hashCode()\r
-    {\r
-      return ((id.length()>=4) ? id.substring(0, 4).hashCode() : id.hashCode());\r
-    }\r
-\r
-    public boolean equals(Object s)\r
-    {\r
-      if (s instanceof SeqIdName)\r
-      {\r
-        return this.equals( (SeqIdName) s);\r
-      }\r
-      else\r
-      {\r
-        if (s instanceof String)\r
-        {\r
-          return this.equals( (String) s);\r
-        }\r
-      }\r
-\r
-      return false;\r
-    }\r
-\r
-    /**\r
-     * Characters that define the end of a unique sequence ID at\r
-     * the beginning of an arbitrary ID string\r
-     * JBPNote: This is a heuristic that will fail for arbritrarily extended sequence id's\r
-     * (like portions of an aligned set of repeats from one sequence)\r
-     */\r
-    private String WORD_SEP="~. |#\\/<>!\"£$%^*)}[@',?";\r
-\r
-   /**\r
-    * matches if one ID properly contains another at a whitespace boundary.\r
-    * TODO: (JBPNote) These are not efficient. should use char[] for speed\r
-    * todo: (JBPNote) Set separator characters appropriately\r
-    * @param s SeqIdName\r
-    * @return boolean\r
-    */\r
-    public boolean equals(SeqIdName s)\r
-    {\r
-      if (id.length()>s.id.length()) {\r
-        return id.startsWith(s.id) ?\r
-            (WORD_SEP.indexOf(id.charAt(s.id.length()))>-1)\r
-            : false;\r
-      } else\r
-        return s.id.startsWith(id) ?\r
-            (s.id.equals(id) ? true :\r
-             (WORD_SEP.indexOf(s.id.charAt(id.length()))>-1))\r
-            : false;\r
-    }\r
-\r
-    public boolean equals(String s)\r
-    {\r
-      if (id.length()>s.length()) {\r
-        return id.startsWith(s) ?\r
-            (WORD_SEP.indexOf(id.charAt(s.length()))>-1)\r
-            : false;\r
-      } else\r
-        return s.startsWith(id) ?\r
-            (s.equals(id) ? true :\r
-             (WORD_SEP.indexOf(s.charAt(id.length()))>-1))\r
-            : false;\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.analysis;
+
+import java.util.*;
+
+import jalview.datamodel.*;
+
+/**
+ * <p>Title: </p>
+ * SequenceIdMatcher
+ * <p>Description: </p>
+ * Routine which does approximate Sequence Id resolution by name using
+ * string containment (on word boundaries) rather than equivalence
+ * <p>Copyright: Copyright (c) 2004</p>
+ *
+ * <p>Company: Dundee University</p>
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class SequenceIdMatcher
+{
+  private Hashtable names;
+
+  public SequenceIdMatcher(SequenceI[] seqs)
+  {
+    names = new Hashtable();
+    for (int i = 0; i < seqs.length; i++)
+    {
+      names.put(new SeqIdName(seqs[i].getName()), seqs[i]);
+    }
+  }
+
+  SequenceI findIdMatch(SequenceI seq)
+  {
+    SeqIdName nam = new SeqIdName(seq.getName());
+
+    if (names.containsKey(nam))
+    {
+      return (SequenceI) names.get(nam);
+    }
+
+    return null;
+  }
+
+  SequenceI findIdMatch(String seqnam)
+  {
+    SeqIdName nam = new SeqIdName(seqnam);
+
+    if (names.containsKey(nam))
+    {
+      return (SequenceI) names.get(nam);
+    }
+
+    return null;
+  }
+
+  /**
+   * findIdMatch
+   *
+   * Return pointers to sequences (or sequence object containers)
+   * which have same Id as a given set of different sequence objects
+   *
+   * @param seqs SequenceI[]
+   * @return SequenceI[]
+   */
+  SequenceI[] findIdMatch(SequenceI[] seqs)
+  {
+    SequenceI[] namedseqs = null;
+    int i = 0;
+    SeqIdName nam;
+
+    if (seqs.length > 0)
+    {
+      namedseqs = new SequenceI[seqs.length];
+      do
+      {
+        nam = new SeqIdName(seqs[i].getName());
+
+        if (names.containsKey(nam))
+        {
+          namedseqs[i] = (SequenceI) names.get(nam);
+        }
+        else
+        {
+          namedseqs[i] = null;
+        }
+      }
+      while (++i < seqs.length);
+    }
+
+    return namedseqs;
+  }
+
+  private class SeqIdName
+  {
+    String id;
+
+    SeqIdName(String s)
+    {
+      if (s!=null)
+        id = new String(s);
+      else
+        id = "";
+    }
+
+    public int hashCode()
+    {
+      return ((id.length()>=4) ? id.substring(0, 4).hashCode() : id.hashCode());
+    }
+
+    public boolean equals(Object s)
+    {
+      if (s instanceof SeqIdName)
+      {
+        return this.equals( (SeqIdName) s);
+      }
+      else
+      {
+        if (s instanceof String)
+        {
+          return this.equals( (String) s);
+        }
+      }
+
+      return false;
+    }
+
+    /**
+     * Characters that define the end of a unique sequence ID at
+     * the beginning of an arbitrary ID string
+     * JBPNote: This is a heuristic that will fail for arbritrarily extended sequence id's
+     * (like portions of an aligned set of repeats from one sequence)
+     */
+    private String WORD_SEP="~. |#\\/<>!\"£$%^*)}[@',?";
+
+   /**
+    * matches if one ID properly contains another at a whitespace boundary.
+    * TODO: (JBPNote) These are not efficient. should use char[] for speed
+    * todo: (JBPNote) Set separator characters appropriately
+    * @param s SeqIdName
+    * @return boolean
+    */
+    public boolean equals(SeqIdName s)
+    {
+      if (id.length()>s.id.length()) {
+        return id.startsWith(s.id) ?
+            (WORD_SEP.indexOf(id.charAt(s.id.length()))>-1)
+            : false;
+      } else
+        return s.id.startsWith(id) ?
+            (s.id.equals(id) ? true :
+             (WORD_SEP.indexOf(s.id.charAt(id.length()))>-1))
+            : false;
+    }
+
+    public boolean equals(String s)
+    {
+      if (id.length()>s.length()) {
+        return id.startsWith(s) ?
+            (WORD_SEP.indexOf(id.charAt(s.length()))>-1)
+            : false;
+      } else
+        return s.startsWith(id) ?
+            (s.equals(id) ? true :
+             (WORD_SEP.indexOf(s.charAt(id.length()))>-1))
+            : false;
+    }
+  }
+}
index b85c7d2..3e25d44 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.util.Vector;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-\r
-public class APopupMenu\r
-    extends java.awt.PopupMenu implements ActionListener, ItemListener\r
-{\r
-  Menu groupMenu = new Menu();\r
-  protected MenuItem clustalColour = new MenuItem();\r
-  protected MenuItem zappoColour = new MenuItem();\r
-  protected MenuItem taylorColour = new MenuItem();\r
-  protected MenuItem hydrophobicityColour = new MenuItem();\r
-  protected MenuItem helixColour = new MenuItem();\r
-  protected MenuItem strandColour = new MenuItem();\r
-  protected MenuItem turnColour = new MenuItem();\r
-  protected MenuItem buriedColour = new MenuItem();\r
-  protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();\r
-  protected MenuItem userDefinedColour = new MenuItem();\r
-  protected MenuItem PIDColour = new MenuItem();\r
-  protected MenuItem BLOSUM62Colour = new MenuItem();\r
-  MenuItem noColourmenuItem = new MenuItem();\r
-  protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();\r
-\r
-  final AlignmentPanel ap;\r
-  MenuItem unGroupMenuItem = new MenuItem();\r
-  MenuItem nucleotideMenuItem = new MenuItem();\r
-  Menu colourMenu = new Menu();\r
-  CheckboxMenuItem showBoxes = new CheckboxMenuItem();\r
-  CheckboxMenuItem showText = new CheckboxMenuItem();\r
-  CheckboxMenuItem showColourText = new CheckboxMenuItem();\r
-\r
-  public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links)\r
-  {\r
-    ///////////////////////////////////////////////////////////\r
-    // If this is activated from the sequence panel, the user may want to\r
-    // edit or annotate a particular residue. Therefore display the residue menu\r
-    //\r
-    // If from the IDPanel, we must display the sequence menu\r
-    //////////////////////////////////////////////////////////\r
-\r
-    this.ap = apanel;\r
-\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    SequenceGroup sg = ap.av.getSelectionGroup();\r
-    if (sg != null)\r
-    {\r
-      showText.setState(sg.getDisplayText());\r
-      showColourText.setState(sg.getColourText());\r
-      showBoxes.setState(sg.getDisplayBoxes());\r
-    }\r
-\r
-    if (!ap.av.alignment.getGroups().contains(sg))\r
-    {\r
-      groupMenu.remove(unGroupMenuItem);\r
-    }\r
-\r
-    if (seq != null && links!=null)\r
-    {\r
-      Menu linkMenu = new Menu("Link");\r
-      MenuItem item;\r
-      String link;\r
-      for(int i=0; i<links.size(); i++)\r
-      {\r
-        link = links.elementAt(i).toString();\r
-        final String target = link.substring(0, link.indexOf("|"));\r
-        item = new MenuItem(target);\r
-        String id = seq.getName();\r
-        if(id.indexOf("|")>-1)\r
-             id = id.substring(id.lastIndexOf("|")+1);\r
-\r
-        final String url = link.substring(link.indexOf("|")+1, link.indexOf("$SEQUENCE_ID$"))\r
-               + id +\r
-               link.substring(link.indexOf("$SEQUENCE_ID$") + 13);\r
-\r
-           item.addActionListener(new java.awt.event.ActionListener()\r
-           {\r
-               public void actionPerformed(ActionEvent e)\r
-               {\r
-                  ap.alignFrame.showURL(url, target);\r
-               }\r
-           });\r
-          linkMenu.add(item);\r
-      }\r
-      add(linkMenu);\r
-\r
-      item = new MenuItem("Show PDB Structure");\r
-      item.addActionListener(new java.awt.event.ActionListener()\r
-           {\r
-               public void actionPerformed(ActionEvent e)\r
-               {\r
-                  addPDB(seq);\r
-               }\r
-           });\r
-\r
-      add(item);\r
-\r
-\r
-    }\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if(evt.getSource()==abovePIDColour)\r
-      abovePIDColour_itemStateChanged();\r
-    else if(evt.getSource()==showColourText)\r
-      showColourText_itemStateChanged();\r
-    else if(evt.getSource()==showText)\r
-      showText_itemStateChanged();\r
-    else if(evt.getSource()==showBoxes)\r
-       showBoxes_itemStateChanged()   ;\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==clustalColour)\r
-      clustalColour_actionPerformed();\r
-    else if(evt.getSource()==zappoColour)\r
-      zappoColour_actionPerformed();\r
-    else if(evt.getSource()==taylorColour)\r
-      taylorColour_actionPerformed();\r
-    else if(evt.getSource()==hydrophobicityColour)\r
-      hydrophobicityColour_actionPerformed();\r
-    else if(evt.getSource()==helixColour)\r
-      helixColour_actionPerformed();\r
-    else if(evt.getSource()==strandColour)\r
-      strandColour_actionPerformed();\r
-    else if(evt.getSource()==clustalColour)\r
-      turnColour_actionPerformed();\r
-    else if(evt.getSource()==buriedColour)\r
-      buriedColour_actionPerformed();\r
-    else if(evt.getSource()==nucleotideMenuItem)\r
-      nucleotideMenuItem_actionPerformed();\r
-\r
-    else if(evt.getSource()==userDefinedColour)\r
-          userDefinedColour_actionPerformed();\r
-        else if(evt.getSource()==PIDColour)\r
-       PIDColour_actionPerformed();\r
-     else if(evt.getSource()==BLOSUM62Colour)\r
-      BLOSUM62Colour_actionPerformed();\r
-    else if(evt.getSource()==noColourmenuItem)\r
-      noColourmenuItem_actionPerformed();\r
-    else if(evt.getSource()==conservationMenuItem)\r
-        conservationMenuItem_itemStateChanged();\r
-      else if(evt.getSource()==unGroupMenuItem)\r
-      unGroupMenuItem_actionPerformed();\r
-\r
-  }\r
-\r
-  void addPDB(Sequence seq)\r
-  {\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);\r
-    cap.setText("Paste your PDB file here.");\r
-    cap.setPDBImport(seq);\r
-    Frame frame = new Frame();\r
-    frame.add(cap);\r
-    jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    groupMenu.setLabel("Group");\r
-    groupMenu.setLabel("Define");\r
-\r
-    unGroupMenuItem.setLabel("Remove Group");\r
-    unGroupMenuItem.addActionListener(this);\r
-\r
-    nucleotideMenuItem.setLabel("Nucleotide");\r
-    nucleotideMenuItem.addActionListener(this);\r
-    conservationMenuItem.addItemListener(this);\r
-    abovePIDColour.addItemListener(this);\r
-    colourMenu.setLabel("Group Colour");\r
-    showBoxes.setLabel("Boxes");\r
-    showBoxes.setState(true);\r
-    showBoxes.addItemListener(this);\r
-\r
-    showText.setLabel("Text");\r
-    showText.addItemListener(this);\r
-    showColourText.setLabel("Colour Text");\r
-    showColourText.addItemListener(this);\r
-\r
-    add(groupMenu);\r
-    groupMenu.add(unGroupMenuItem);\r
-    groupMenu.add(colourMenu);\r
-    groupMenu.addSeparator();\r
-    groupMenu.add(showBoxes);\r
-    groupMenu.add(showText);\r
-    groupMenu.add(showColourText);\r
-    colourMenu.add(noColourmenuItem);\r
-    colourMenu.add(clustalColour);\r
-    colourMenu.add(BLOSUM62Colour);\r
-    colourMenu.add(PIDColour);\r
-    colourMenu.add(zappoColour);\r
-    colourMenu.add(taylorColour);\r
-    colourMenu.add(hydrophobicityColour);\r
-    colourMenu.add(helixColour);\r
-    colourMenu.add(strandColour);\r
-    colourMenu.add(turnColour);\r
-    colourMenu.add(buriedColour);\r
-    colourMenu.add(nucleotideMenuItem);\r
-    colourMenu.add(userDefinedColour);\r
-    colourMenu.addSeparator();\r
-    colourMenu.add(abovePIDColour);\r
-    colourMenu.add(conservationMenuItem);\r
-\r
-    noColourmenuItem.setLabel("None");\r
-    noColourmenuItem.addActionListener(this);\r
-\r
-    clustalColour.setLabel("Clustalx colours");\r
-    clustalColour.addActionListener(this);\r
-    zappoColour.setLabel("Zappo");\r
-    zappoColour.addActionListener(this);\r
-    taylorColour.setLabel("Taylor");\r
-    taylorColour.addActionListener(this);\r
-    hydrophobicityColour.setLabel("Hydrophobicity");\r
-    hydrophobicityColour.addActionListener(this);\r
-    helixColour.setLabel("Helix propensity");\r
-    helixColour.addActionListener(this);\r
-    strandColour.setLabel("Strand propensity");\r
-    strandColour.addActionListener(this);\r
-    turnColour.setLabel("Turn propensity");\r
-    turnColour.addActionListener(this);\r
-    buriedColour.setLabel("Buried Index");\r
-    buriedColour.addActionListener(this);\r
-    abovePIDColour.setLabel("Above % Identity");\r
-\r
-    userDefinedColour.setLabel("User Defined");\r
-    userDefinedColour.addActionListener(this);\r
-    PIDColour.setLabel("Percentage Identity");\r
-    PIDColour.addActionListener(this);\r
-    BLOSUM62Colour.setLabel("BLOSUM62");\r
-    BLOSUM62Colour.addActionListener(this);\r
-    conservationMenuItem.setLabel("Conservation");\r
-\r
-  }\r
-\r
-  void refresh()\r
-  {\r
-    ap.seqPanel.seqCanvas.repaint();\r
-    if(ap.overviewPanel!=null)\r
-      ap.overviewPanel.updateOverviewImage();\r
-  }\r
-\r
-  protected void clustalColour_actionPerformed()\r
-  {\r
-    SequenceGroup sg = getGroup();\r
-    sg.cs = new ClustalxColourScheme(sg.sequences, ap.av.alignment.getWidth());\r
-    refresh();\r
-  }\r
-\r
-  protected void zappoColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new ZappoColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void taylorColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new TaylorColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void hydrophobicityColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new HydrophobicColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void helixColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new HelixColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void strandColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new StrandColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void turnColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new TurnColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void buriedColour_actionPerformed()\r
-  {\r
-    getGroup().cs = new BuriedColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  public void nucleotideMenuItem_actionPerformed()\r
-  {\r
-    getGroup().cs = new NucleotideColourScheme();\r
-    refresh();\r
-  }\r
-\r
-  protected void abovePIDColour_itemStateChanged()\r
-  {\r
-    SequenceGroup sg = getGroup();\r
-    if(sg.cs==null)\r
-          return;\r
-\r
-    if (abovePIDColour.getState())\r
-    {\r
-      sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-                                               ap.av.alignment.getWidth()));\r
-      int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,\r
-          getGroup().getName());\r
-\r
-      sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());\r
-\r
-      SliderPanel.showPIDSlider();\r
-\r
-    }\r
-    else // remove PIDColouring\r
-    {\r
-      sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
-    }\r
-\r
-    refresh();\r
-\r
-  }\r
-\r
-  protected void userDefinedColour_actionPerformed()\r
-  {\r
-    new UserDefinedColours(ap, getGroup());\r
-  }\r
-\r
-  protected void PIDColour_actionPerformed()\r
-  {\r
-    SequenceGroup sg = getGroup();\r
-    sg.cs = new PIDColourScheme();\r
-    sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-                                             ap.av.alignment.getWidth()));\r
-    refresh();\r
-  }\r
-\r
-  protected void BLOSUM62Colour_actionPerformed()\r
-  {\r
-    SequenceGroup sg = getGroup();\r
-\r
-    sg.cs = new Blosum62ColourScheme();\r
-\r
-    sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-                                             ap.av.alignment.getWidth()));\r
-\r
-    refresh();\r
-  }\r
-\r
-  protected void noColourmenuItem_actionPerformed()\r
-  {\r
-    getGroup().cs = null;\r
-    refresh();\r
-  }\r
-\r
-  protected void conservationMenuItem_itemStateChanged()\r
-  {\r
-    SequenceGroup sg = getGroup();\r
-    if(sg.cs==null)\r
-          return;\r
-\r
-    if (conservationMenuItem.getState())\r
-    {\r
-\r
-      Conservation c = new Conservation("Group",\r
-                                        ResidueProperties.propHash, 3,\r
-                                        sg.sequences, 0,\r
-                                        ap.av.alignment.getWidth());\r
-\r
-      c.calculate();\r
-      c.verdict(false, ap.av.ConsPercGaps);\r
-\r
-      sg.cs.setConservation(c);\r
-\r
-      SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());\r
-      SliderPanel.showConservationSlider();\r
-    }\r
-    else // remove ConservationColouring\r
-    {\r
-      sg.cs.setConservation(null);\r
-    }\r
-\r
-    refresh();\r
-  }\r
-\r
-\r
-  SequenceGroup getGroup()\r
-  {\r
-    SequenceGroup sg = ap.av.getSelectionGroup();\r
-\r
-    // this method won't add a new group if it already exists\r
-    if(sg!=null)\r
-      ap.av.alignment.addGroup(sg);\r
-\r
-    return sg;\r
-  }\r
-\r
-  void unGroupMenuItem_actionPerformed()\r
-  {\r
-    SequenceGroup sg = ap.av.getSelectionGroup();\r
-    ap.av.alignment.deleteGroup(sg);\r
-    ap.av.setSelectionGroup(null);\r
-    ap.repaint();\r
-  }\r
-\r
-  public void showColourText_itemStateChanged()\r
-  {\r
-    getGroup().setColourText(showColourText.getState());\r
-    refresh();\r
-  }\r
-\r
-  public void showText_itemStateChanged()\r
-  {\r
-    getGroup().setDisplayText(showText.getState());\r
-    refresh();\r
-  }\r
-\r
-  public void showBoxes_itemStateChanged()\r
-  {\r
-    getGroup().setDisplayBoxes(showBoxes.getState());\r
-    refresh();\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Vector;
+
+import jalview.analysis.*;
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+public class APopupMenu
+    extends java.awt.PopupMenu implements ActionListener, ItemListener
+{
+  Menu groupMenu = new Menu();
+  protected MenuItem clustalColour = new MenuItem();
+  protected MenuItem zappoColour = new MenuItem();
+  protected MenuItem taylorColour = new MenuItem();
+  protected MenuItem hydrophobicityColour = new MenuItem();
+  protected MenuItem helixColour = new MenuItem();
+  protected MenuItem strandColour = new MenuItem();
+  protected MenuItem turnColour = new MenuItem();
+  protected MenuItem buriedColour = new MenuItem();
+  protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();
+  protected MenuItem userDefinedColour = new MenuItem();
+  protected MenuItem PIDColour = new MenuItem();
+  protected MenuItem BLOSUM62Colour = new MenuItem();
+  MenuItem noColourmenuItem = new MenuItem();
+  protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
+
+  final AlignmentPanel ap;
+  MenuItem unGroupMenuItem = new MenuItem();
+  MenuItem nucleotideMenuItem = new MenuItem();
+  Menu colourMenu = new Menu();
+  CheckboxMenuItem showBoxes = new CheckboxMenuItem();
+  CheckboxMenuItem showText = new CheckboxMenuItem();
+  CheckboxMenuItem showColourText = new CheckboxMenuItem();
+  Menu editMenu = new Menu("Edit");
+  MenuItem copy = new MenuItem("Copy (Jalview Only)");
+  MenuItem cut = new MenuItem("Cut (Jalview Only)");
+  MenuItem toUpper = new MenuItem("To Upper Case");
+  MenuItem toLower = new MenuItem("To Lower Case");
+  MenuItem toggleCase = new MenuItem("Toggle Case");
+  Menu outputmenu = new Menu();
+  Menu seqMenu = new Menu();
+  MenuItem pdb = new MenuItem();
+  MenuItem hideSeqs = new MenuItem();
+  MenuItem repGroup = new MenuItem();
+
+  Sequence seq;
+  MenuItem revealAll = new MenuItem();
+
+  public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links)
+  {
+    ///////////////////////////////////////////////////////////
+    // If this is activated from the sequence panel, the user may want to
+    // edit or annotate a particular residue. Therefore display the residue menu
+    //
+    // If from the IDPanel, we must display the sequence menu
+    //////////////////////////////////////////////////////////
+
+    this.ap = apanel;
+    this.seq = seq;
+
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++)
+    {
+      MenuItem item = new MenuItem( jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i] );
+
+      item.addActionListener(this);
+      outputmenu.add(item);
+    }
+
+    SequenceGroup sg = ap.av.getSelectionGroup();
+
+    if (sg != null && sg.getSize(false)>0)
+    {
+      showText.setState(sg.getDisplayText());
+      showColourText.setState(sg.getColourText());
+      showBoxes.setState(sg.getDisplayBoxes());
+      if (!ap.av.alignment.getGroups().contains(sg))
+      {
+        groupMenu.remove(unGroupMenuItem);
+      }
+
+    }
+    else
+    {
+      remove(hideSeqs);
+      remove(groupMenu);
+    }
+
+    if (links!=null)
+    {
+      Menu linkMenu = new Menu("Link");
+      MenuItem item;
+      String link;
+      for(int i=0; i<links.size(); i++)
+      {
+        link = links.elementAt(i).toString();
+        final String target = link.substring(0, link.indexOf("|"));
+        item = new MenuItem(target);
+
+        final String url;
+
+        if (link.indexOf("$SEQUENCE_ID$") > -1)
+        {
+          String id = seq.getName();
+          if (id.indexOf("|") > -1)
+            id = id.substring(id.lastIndexOf("|") + 1);
+
+          url = link.substring(link.indexOf("|") + 1,
+                               link.indexOf("$SEQUENCE_ID$"))
+              + id +
+              link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
+        }
+        else
+          url = link.substring(link.lastIndexOf("|")+1);
+
+        System.out.println("add "+url +" "+target);
+           item.addActionListener(new java.awt.event.ActionListener()
+           {
+               public void actionPerformed(ActionEvent e)
+               {
+                  ap.alignFrame.showURL(url, target);
+               }
+           });
+          linkMenu.add(item);
+      }
+      if(seq!=null)
+        seqMenu.add(linkMenu);
+      else
+        add(linkMenu);
+    }
+    if(seq!=null)
+    {
+      seqMenu.setLabel(seq.getName());
+      repGroup.setLabel("Represent Group with " + seq.getName());
+    }
+    else
+      remove(seqMenu);
+
+    if(!ap.av.hasHiddenRows)
+      remove(revealAll);
+  }
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if(evt.getSource()==abovePIDColour)
+      abovePIDColour_itemStateChanged();
+    else if(evt.getSource()==showColourText)
+      showColourText_itemStateChanged();
+    else if(evt.getSource()==showText)
+      showText_itemStateChanged();
+    else if(evt.getSource()==showBoxes)
+       showBoxes_itemStateChanged()   ;
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    Object source = evt.getSource();
+    if(source==clustalColour)
+      clustalColour_actionPerformed();
+    else if(source==zappoColour)
+      zappoColour_actionPerformed();
+    else if(source==taylorColour)
+      taylorColour_actionPerformed();
+    else if(source==hydrophobicityColour)
+      hydrophobicityColour_actionPerformed();
+    else if(source==helixColour)
+      helixColour_actionPerformed();
+    else if(source==strandColour)
+      strandColour_actionPerformed();
+    else if(source==clustalColour)
+      turnColour_actionPerformed();
+    else if(source==buriedColour)
+      buriedColour_actionPerformed();
+    else if(source==nucleotideMenuItem)
+      nucleotideMenuItem_actionPerformed();
+
+    else if (source == userDefinedColour)
+      userDefinedColour_actionPerformed();
+    else if (source == PIDColour)
+      PIDColour_actionPerformed();
+    else if (source == BLOSUM62Colour)
+      BLOSUM62Colour_actionPerformed();
+    else if (source == noColourmenuItem)
+      noColourmenuItem_actionPerformed();
+    else if (source == conservationMenuItem)
+      conservationMenuItem_itemStateChanged();
+    else if (source == unGroupMenuItem)
+      unGroupMenuItem_actionPerformed();
+
+    else if(source == pdb)
+      addPDB();
+    else if(source == hideSeqs)
+      hideSequences(false);
+    else if(source == repGroup)
+      hideSequences(true);
+    else if(source == revealAll)
+    {
+        ap.av.showAllHiddenSeqs();
+    }
+
+    else if(source==copy)
+      ap.alignFrame.copy_actionPerformed();
+    else if(source==cut)
+      ap.alignFrame.cut_actionPerformed();
+    else if(source==toUpper || source==toLower || source==toggleCase)
+    {
+      SequenceGroup sg = ap.av.getSelectionGroup();
+      if (sg != null)
+      {
+        for (int g = 0; g < sg.getSize(true); g++)
+        {
+          int start = sg.getStartRes();
+          int end = sg.getEndRes() + 1;
+
+          do
+          {
+            if (ap.av.hasHiddenColumns)
+            {
+              end = ap.av.colSel.getHiddenBoundaryRight(start);
+              if (start == end)
+                end = sg.getEndRes() + 1;
+              if (end > sg.getEndRes())
+                end = sg.getEndRes() + 1;
+            }
+
+            if (source == toggleCase)
+              ( (SequenceI) sg.getSequences(true).elementAt(g))
+                  .toggleCase(start, end);
+            else
+              ( (SequenceI) sg.getSequences(true).elementAt(g))
+                  .changeCase(source == toUpper, start, end);
+
+            if (ap.av.hasHiddenColumns)
+            {
+              start = ap.av.colSel.adjustForHiddenColumns(end);
+              start = ap.av.colSel.getHiddenBoundaryLeft(start) + 1;
+            }
+
+          }
+        while (end < sg.getEndRes());
+        }
+        ap.seqPanel.seqCanvas.repaint();
+      }
+    }
+    else
+      outputText(evt);
+
+  }
+
+  void outputText(ActionEvent e)
+  {
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);
+    Vector vseqs = new Vector();
+
+      String [] selection = ap.av.getViewAsString(true);
+      SequenceI [] seqs = ap.av.getSelectionAsNewSequence();
+      if (selection != null)
+      {
+        for (int i = 0; i < selection.length; i++)
+        {
+          Sequence seq = new Sequence(
+              seqs[i].getName(),
+              selection[i],
+              seqs[i].getStart(), seqs[i].getEnd());
+          seq.setDescription(seqs[i].getDescription());
+          vseqs.addElement( seq );
+      }
+    }
+
+    Frame frame = new Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame,
+                                     "Selection output - " + e.getActionCommand(),
+                                     600, 500);
+
+    cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(
+        e.getActionCommand(),
+        vseqs,
+        ap.av.showJVSuffix));
+
+  }
+
+  void addPDB()
+  {
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
+    cap.setText("Paste your PDB file here.");
+    cap.setPDBImport(seq);
+    Frame frame = new Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    groupMenu.setLabel("Group");
+    groupMenu.setLabel("Selection");
+
+    unGroupMenuItem.setLabel("Remove Group");
+    unGroupMenuItem.addActionListener(this);
+
+    nucleotideMenuItem.setLabel("Nucleotide");
+    nucleotideMenuItem.addActionListener(this);
+    conservationMenuItem.addItemListener(this);
+    abovePIDColour.addItemListener(this);
+    colourMenu.setLabel("Group Colour");
+    showBoxes.setLabel("Boxes");
+    showBoxes.setState(true);
+    showBoxes.addItemListener(this);
+
+    showText.setLabel("Text");
+    showText.addItemListener(this);
+    showColourText.setLabel("Colour Text");
+    showColourText.addItemListener(this);
+    outputmenu.setLabel("Output to Textbox...");
+    seqMenu.setLabel("Sequence");
+    pdb.setLabel("View PDB Structure");
+    hideSeqs.setLabel("Hide Sequences");
+    repGroup.setLabel("Represent Group with");
+    revealAll.setLabel("Reveal All");
+
+    add(groupMenu);
+    this.add(seqMenu);
+    this.add(hideSeqs);
+    this.add(revealAll);
+    groupMenu.add(editMenu);
+    groupMenu.add(outputmenu);
+    groupMenu.addSeparator();
+    groupMenu.add(unGroupMenuItem);
+    groupMenu.add(colourMenu);
+    groupMenu.add(showBoxes);
+    groupMenu.add(showText);
+    groupMenu.add(showColourText);
+    colourMenu.add(noColourmenuItem);
+    colourMenu.add(clustalColour);
+    colourMenu.add(BLOSUM62Colour);
+    colourMenu.add(PIDColour);
+    colourMenu.add(zappoColour);
+    colourMenu.add(taylorColour);
+    colourMenu.add(hydrophobicityColour);
+    colourMenu.add(helixColour);
+    colourMenu.add(strandColour);
+    colourMenu.add(turnColour);
+    colourMenu.add(buriedColour);
+    colourMenu.add(nucleotideMenuItem);
+    colourMenu.add(userDefinedColour);
+    colourMenu.addSeparator();
+    colourMenu.add(abovePIDColour);
+    colourMenu.add(conservationMenuItem);
+
+    noColourmenuItem.setLabel("None");
+    noColourmenuItem.addActionListener(this);
+
+    clustalColour.setLabel("Clustalx colours");
+    clustalColour.addActionListener(this);
+    zappoColour.setLabel("Zappo");
+    zappoColour.addActionListener(this);
+    taylorColour.setLabel("Taylor");
+    taylorColour.addActionListener(this);
+    hydrophobicityColour.setLabel("Hydrophobicity");
+    hydrophobicityColour.addActionListener(this);
+    helixColour.setLabel("Helix propensity");
+    helixColour.addActionListener(this);
+    strandColour.setLabel("Strand propensity");
+    strandColour.addActionListener(this);
+    turnColour.setLabel("Turn propensity");
+    turnColour.addActionListener(this);
+    buriedColour.setLabel("Buried Index");
+    buriedColour.addActionListener(this);
+    abovePIDColour.setLabel("Above % Identity");
+
+    userDefinedColour.setLabel("User Defined");
+    userDefinedColour.addActionListener(this);
+    PIDColour.setLabel("Percentage Identity");
+    PIDColour.addActionListener(this);
+    BLOSUM62Colour.setLabel("BLOSUM62");
+    BLOSUM62Colour.addActionListener(this);
+    conservationMenuItem.setLabel("Conservation");
+
+    editMenu.add(copy);
+    copy.addActionListener(this);
+    editMenu.add(cut);
+    cut.addActionListener(this);
+    editMenu.add(toUpper);
+    toUpper.addActionListener(this);
+    editMenu.add(toLower);
+    toLower.addActionListener(this);
+    editMenu.add(toggleCase);
+    seqMenu.add(pdb);
+    seqMenu.add(repGroup);
+    toggleCase.addActionListener(this);
+    pdb.addActionListener(this);
+    hideSeqs.addActionListener(this);
+    repGroup.addActionListener(this);
+    revealAll.addActionListener(this);
+
+  }
+
+  void refresh()
+  {
+    ap.seqPanel.seqCanvas.repaint();
+    if(ap.overviewPanel!=null)
+      ap.overviewPanel.updateOverviewImage();
+  }
+
+  protected void clustalColour_actionPerformed()
+  {
+    SequenceGroup sg = getGroup();
+    sg.cs = new ClustalxColourScheme(sg.getSequences(true), ap.av.alignment.getWidth());
+    refresh();
+  }
+
+  protected void zappoColour_actionPerformed()
+  {
+    getGroup().cs = new ZappoColourScheme();
+    refresh();
+  }
+
+  protected void taylorColour_actionPerformed()
+  {
+    getGroup().cs = new TaylorColourScheme();
+    refresh();
+  }
+
+  protected void hydrophobicityColour_actionPerformed()
+  {
+    getGroup().cs = new HydrophobicColourScheme();
+    refresh();
+  }
+
+  protected void helixColour_actionPerformed()
+  {
+    getGroup().cs = new HelixColourScheme();
+    refresh();
+  }
+
+  protected void strandColour_actionPerformed()
+  {
+    getGroup().cs = new StrandColourScheme();
+    refresh();
+  }
+
+  protected void turnColour_actionPerformed()
+  {
+    getGroup().cs = new TurnColourScheme();
+    refresh();
+  }
+
+  protected void buriedColour_actionPerformed()
+  {
+    getGroup().cs = new BuriedColourScheme();
+    refresh();
+  }
+
+  public void nucleotideMenuItem_actionPerformed()
+  {
+    getGroup().cs = new NucleotideColourScheme();
+    refresh();
+  }
+
+  protected void abovePIDColour_itemStateChanged()
+  {
+    SequenceGroup sg = getGroup();
+    if(sg.cs==null)
+          return;
+
+    if (abovePIDColour.getState())
+    {
+      sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,
+                                               ap.av.alignment.getWidth()));
+      int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,
+          getGroup().getName());
+
+      sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
+
+      SliderPanel.showPIDSlider();
+
+    }
+    else // remove PIDColouring
+    {
+      sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
+    }
+
+    refresh();
+
+  }
+
+  protected void userDefinedColour_actionPerformed()
+  {
+    new UserDefinedColours(ap, getGroup());
+  }
+
+  protected void PIDColour_actionPerformed()
+  {
+    SequenceGroup sg = getGroup();
+    sg.cs = new PIDColourScheme();
+    sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,
+                                             ap.av.alignment.getWidth()));
+    refresh();
+  }
+
+  protected void BLOSUM62Colour_actionPerformed()
+  {
+    SequenceGroup sg = getGroup();
+
+    sg.cs = new Blosum62ColourScheme();
+
+    sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,
+                                             ap.av.alignment.getWidth()));
+
+    refresh();
+  }
+
+  protected void noColourmenuItem_actionPerformed()
+  {
+    getGroup().cs = null;
+    refresh();
+  }
+
+  protected void conservationMenuItem_itemStateChanged()
+  {
+    SequenceGroup sg = getGroup();
+    if(sg.cs==null)
+          return;
+
+    if (conservationMenuItem.getState())
+    {
+
+      Conservation c = new Conservation("Group",
+                                        ResidueProperties.propHash, 3,
+                                        sg.getSequences(true), 0,
+                                        ap.av.alignment.getWidth());
+
+      c.calculate();
+      c.verdict(false, ap.av.ConsPercGaps);
+
+      sg.cs.setConservation(c);
+
+      SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
+      SliderPanel.showConservationSlider();
+    }
+    else // remove ConservationColouring
+    {
+      sg.cs.setConservation(null);
+    }
+
+    refresh();
+  }
+
+
+  SequenceGroup getGroup()
+  {
+    SequenceGroup sg = ap.av.getSelectionGroup();
+
+    // this method won't add a new group if it already exists
+    if(sg!=null)
+      ap.av.alignment.addGroup(sg);
+
+    return sg;
+  }
+
+  void unGroupMenuItem_actionPerformed()
+  {
+    SequenceGroup sg = ap.av.getSelectionGroup();
+    ap.av.alignment.deleteGroup(sg);
+    ap.av.setSelectionGroup(null);
+    ap.repaint();
+  }
+
+  public void showColourText_itemStateChanged()
+  {
+    getGroup().setColourText(showColourText.getState());
+    refresh();
+  }
+
+  public void showText_itemStateChanged()
+  {
+    getGroup().setDisplayText(showText.getState());
+    refresh();
+  }
+
+  public void showBoxes_itemStateChanged()
+  {
+    getGroup().setDisplayBoxes(showBoxes.getState());
+    refresh();
+  }
+
+  void hideSequences(boolean representGroup)
+  {
+    SequenceGroup sg = ap.av.getSelectionGroup();
+    if(sg==null || sg.getSize(false)<1)
+    {
+      ap.av.hideSequence(seq);
+      return;
+    }
+
+      int index = 0;
+      while(index < sg.getSize(false))
+      {
+        if(representGroup && sg.getSequenceAt(index)!=seq)
+        {
+          seq.addHiddenSequence(sg.getSequenceAt(index));
+          ap.av.hideSequence(sg.getSequenceAt(index));
+        }
+        else if(!representGroup)
+        {
+          ap.av.hideSequence(sg.getSequenceAt(index));
+        }
+        index ++;
+      }
+
+      ap.av.setSelectionGroup(null);
+    }
+
+}
index 189a36d..e37061a 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import jalview.schemes.*;\r
-import jalview.datamodel.*;\r
-import jalview.analysis.*;\r
-import jalview.io.*;\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.util.*;\r
-import java.io.InputStreamReader;\r
-import java.io.BufferedReader;\r
-import java.net.URL;\r
-\r
-\r
-public class AlignFrame extends Frame implements ActionListener,\r
-    ItemListener, KeyListener, MouseListener\r
-{\r
-  public AlignmentPanel alignPanel;\r
-  public AlignViewport viewport;\r
-  int NEW_WINDOW_WIDTH = 700;\r
-  int NEW_WINDOW_HEIGHT = 500;\r
-  jalview.bin.JalviewLite applet;\r
-\r
-\r
-   public AlignFrame(AlignmentI al,\r
-                     jalview.bin.JalviewLite applet,\r
-                     String title,\r
-                     boolean embedded)\r
-  {\r
-    try{\r
-      jbInit();\r
-    }catch(Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    this.applet = applet;\r
-    viewport = new AlignViewport(al, applet);\r
-    alignPanel = new AlignmentPanel(this, viewport);\r
-\r
-    annotationPanelMenuItem.setState(viewport.showAnnotation);\r
-\r
-    if(applet!=null)\r
-    {\r
-      String param = applet.getParameter("sortBy");\r
-      if (param != null)\r
-      {\r
-        if (param.equalsIgnoreCase("Id"))\r
-          sortIDMenuItem_actionPerformed();\r
-        else if (param.equalsIgnoreCase("Pairwise Identity"))\r
-          sortPairwiseMenuItem_actionPerformed();\r
-      }\r
-\r
-      param = applet.getParameter("wrap");\r
-      if (param != null)\r
-      {\r
-        if (param.equalsIgnoreCase("true"))\r
-        {\r
-          wrapMenuItem.setState(true);\r
-          wrapMenuItem_actionPerformed();\r
-        }\r
-      }\r
-\r
-      try\r
-      {\r
-        param = applet.getParameter("windowWidth");\r
-        if (param != null)\r
-        {\r
-          int width = Integer.parseInt(param);\r
-          NEW_WINDOW_WIDTH = width;\r
-        }\r
-        param = applet.getParameter("windowHeight");\r
-        if (param != null)\r
-        {\r
-          int height = Integer.parseInt(param);\r
-          NEW_WINDOW_HEIGHT = height;\r
-        }\r
-      }\r
-      catch (Exception ex)\r
-      {}\r
-\r
-    }\r
-\r
-   //Some JVMS send keyevents to Top frame or lowest panel,\r
-   //Havent worked out why yet. So add to both this frame and seqCanvas for now\r
-   this.addKeyListener(this);\r
-   alignPanel.seqPanel.seqCanvas.addKeyListener(this);\r
-   alignPanel.idPanel.idCanvas.addKeyListener(this);\r
-\r
-    viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
-    {\r
-     public void propertyChange(java.beans.PropertyChangeEvent evt)\r
-     {\r
-       if (evt.getPropertyName().equals("alignment"))\r
-       {\r
-         alignmentChanged();\r
-       }\r
-     }\r
-   });\r
-\r
-\r
-   if(embedded)\r
-   {\r
-     setEmbedded();\r
-   }\r
-   else\r
-   {\r
-     add(alignPanel, BorderLayout.CENTER);\r
-     jalview.bin.JalviewLite.addFrame(this, title, NEW_WINDOW_WIDTH,\r
-                                      NEW_WINDOW_HEIGHT);\r
-   }\r
-   alignPanel.validate();\r
-   alignPanel.repaint();\r
-  }\r
-  public AlignViewport getAlignViewport()\r
-  {\r
-    return viewport;\r
-  }\r
-\r
-  public SeqCanvas getSeqcanvas()\r
-  {\r
-    return alignPanel.seqPanel.seqCanvas;\r
-  }\r
-\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param String DOCUMENT ME!\r
-   */\r
-\r
-  public void parseFeaturesFile(String file)\r
-  {\r
-    String line = null;\r
-    try\r
-    {\r
-      BufferedReader in = null;\r
-      java.io.InputStream is = getClass().getResourceAsStream("/" + file);\r
-      if (is != null)\r
-      {\r
-        in = new BufferedReader(new java.io.InputStreamReader(is));\r
-      }\r
-      else\r
-      {\r
-        URL url = new URL(file);\r
-        in = new BufferedReader(new InputStreamReader(url.openStream()));\r
-      }\r
-\r
-      SequenceI seq = null;\r
-      String type, desc, token;\r
-\r
-      int index, start, end;\r
-      StringTokenizer st;\r
-      SequenceFeature sf;\r
-      FeatureRenderer fr = alignPanel.seqPanel.seqCanvas.getFeatureRenderer();\r
-      int lineNo = 0;\r
-      String featureGroup = null;\r
-      while ( (line = in.readLine()) != null)\r
-      {\r
-        lineNo++;\r
-        st = new StringTokenizer(line, "\t");\r
-        if (st.countTokens() == 2)\r
-        {\r
-          type = st.nextToken();\r
-          if(type.equalsIgnoreCase("startgroup"))\r
-          {\r
-            featureGroup = st.nextToken();\r
-          }\r
-          else if(type.equalsIgnoreCase("endgroup"))\r
-          {\r
-            //We should check whether this is the current group,\r
-            //but at present theres no way of showing more than 1 group\r
-            st.nextToken();\r
-            featureGroup = null;\r
-          }\r
-          else\r
-          {\r
-            UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
-            fr.setColour(type, ucs.findColour("A"));\r
-          }\r
-          continue;\r
-        }\r
-\r
-        while (st.hasMoreElements())\r
-        {\r
-          desc = st.nextToken();\r
-          token = st.nextToken();\r
-          if (!token.equals("ID_NOT_SPECIFIED"))\r
-          {\r
-            index = viewport.alignment.findIndex(viewport.alignment.findName(\r
-                token));\r
-            st.nextToken();\r
-          }\r
-          else\r
-          {\r
-            index = Integer.parseInt(st.nextToken());\r
-          }\r
-\r
-          start = Integer.parseInt(st.nextToken());\r
-          end = Integer.parseInt(st.nextToken());\r
-\r
-          seq = viewport.alignment.getSequenceAt(index);\r
-\r
-          type = st.nextToken();\r
-\r
-          if(fr.getColour(type)==null)\r
-          {\r
-            // Probably the old style groups file\r
-            UserColourScheme ucs = new UserColourScheme(type);\r
-            fr.setColour(type, ucs.findColour("A"));\r
-          }\r
-\r
-          sf = new SequenceFeature(type, desc, "", start, end, featureGroup);\r
-\r
-          seq.addSequenceFeature(sf);\r
-        }\r
-      }\r
-\r
-      viewport.showSequenceFeatures = true;\r
-      sequenceFeatures.setState(true);\r
-\r
-      alignPanel.repaint();\r
-\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-      System.out.println("Error parsing groups file: " + ex +"\n"+line);\r
-    }\r
-  }\r
-\r
-  public void keyPressed(KeyEvent evt)\r
-  {\r
-    switch (evt.getKeyCode())\r
-    {\r
-      case 27: // escape key\r
-        deselectAllSequenceMenuItem_actionPerformed();\r
-        break;\r
-      case KeyEvent.VK_X:\r
-        if (evt.isControlDown() || evt.isMetaDown())\r
-        {\r
-          cut_actionPerformed();\r
-        }\r
-        break;\r
-      case KeyEvent.VK_C:\r
-        if (evt.isControlDown() || evt.isMetaDown())\r
-        {\r
-          copy_actionPerformed();\r
-        }\r
-        break;\r
-      case KeyEvent.VK_V:\r
-        if (evt.isControlDown() || evt.isMetaDown())\r
-        {\r
-          paste(true);\r
-        }\r
-        break;\r
-      case KeyEvent.VK_A:\r
-        if (evt.isControlDown() || evt.isMetaDown())\r
-        {\r
-          selectAllSequenceMenuItem_actionPerformed();\r
-        }\r
-        break;\r
-      case KeyEvent.VK_DOWN:\r
-        moveSelectedSequences(false);\r
-        break;\r
-      case KeyEvent.VK_UP:\r
-        moveSelectedSequences(true);\r
-        break;\r
-      case KeyEvent.VK_F:\r
-        if (evt.isControlDown())\r
-        {\r
-          findMenuItem_actionPerformed();\r
-        }\r
-        break;\r
-      case KeyEvent.VK_BACK_SPACE:\r
-      case KeyEvent.VK_DELETE:\r
-        cut_actionPerformed();\r
-        break;\r
-    }\r
-  }\r
-  public void keyReleased(KeyEvent evt)\r
-  {}\r
-  public void keyTyped(KeyEvent evt)\r
-  {}\r
-\r
-public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if(evt.getSource()==colourTextMenuItem)\r
-            colourTextMenuItem_actionPerformed();\r
-    else if(evt.getSource()==wrapMenuItem)\r
-            wrapMenuItem_actionPerformed();\r
-    else if(evt.getSource()==scaleAbove)\r
-            scaleAbove_actionPerformed();\r
-    else if(evt.getSource()==scaleLeft)\r
-            scaleLeft_actionPerformed();\r
-    else if(evt.getSource()==scaleRight)\r
-            scaleRight_actionPerformed();\r
-     else if(evt.getSource()==seqLimits)\r
-      seqLimits_itemStateChanged();\r
-    else if(evt.getSource()==viewBoxesMenuItem)\r
-            viewBoxesMenuItem_actionPerformed();\r
-    else if(evt.getSource()==viewTextMenuItem)\r
-            viewTextMenuItem_actionPerformed();\r
-    else if(evt.getSource()==renderGapsMenuItem)\r
-            renderGapsMenuItem_actionPerformed();\r
-    else if(evt.getSource()==annotationPanelMenuItem)\r
-            annotationPanelMenuItem_actionPerformed();\r
-      else if(evt.getSource()==sequenceFeatures)\r
-      {\r
-           viewport.showSequenceFeatures(sequenceFeatures.getState());\r
-            alignPanel.seqPanel.seqCanvas.repaint();\r
-      }\r
-      else if(evt.getSource()==conservationMenuItem)\r
-            conservationMenuItem_actionPerformed();\r
-      else if(evt.getSource()==abovePIDThreshold)\r
-            abovePIDThreshold_actionPerformed();\r
-          else if(evt.getSource()==applyToAllGroups)\r
-            applyToAllGroups_actionPerformed();\r
-  }\r
- public void actionPerformed(ActionEvent evt)\r
- {\r
-    if(evt.getSource()==inputText)\r
-      inputText_actionPerformed();\r
-    else if(evt.getSource()==loadTree)\r
-      loadTree_actionPerformed();\r
-    else if(evt.getSource()==closeMenuItem)\r
-      closeMenuItem_actionPerformed();\r
-    else if(evt.getSource()==copy)\r
-      copy_actionPerformed();\r
-    else if(evt.getSource()==undoMenuItem)\r
-      undoMenuItem_actionPerformed();\r
-    else if(evt.getSource()==redoMenuItem)\r
-      redoMenuItem_actionPerformed();\r
-    else if(evt.getSource()==inputText)\r
-            inputText_actionPerformed();\r
-    else if(evt.getSource()==closeMenuItem)\r
-            closeMenuItem_actionPerformed();\r
-    else if(evt.getSource()==undoMenuItem)\r
-            undoMenuItem_actionPerformed();\r
-    else if(evt.getSource()==redoMenuItem)\r
-            redoMenuItem_actionPerformed();\r
-    else if(evt.getSource()==copy)\r
-            copy_actionPerformed();\r
-    else if(evt.getSource()==pasteNew)\r
-            pasteNew_actionPerformed();\r
-    else if(evt.getSource()==pasteThis)\r
-            pasteThis_actionPerformed();\r
-    else if(evt.getSource()==cut)\r
-            cut_actionPerformed();\r
-    else if(evt.getSource()==delete)\r
-            delete_actionPerformed();\r
-    else if(evt.getSource()==deleteGroups)\r
-            deleteGroups_actionPerformed();\r
-    else if(evt.getSource()==selectAllSequenceMenuItem)\r
-            selectAllSequenceMenuItem_actionPerformed();\r
-    else if(evt.getSource()==deselectAllSequenceMenuItem)\r
-            deselectAllSequenceMenuItem_actionPerformed();\r
-    else if(evt.getSource()==invertSequenceMenuItem)\r
-            invertSequenceMenuItem_actionPerformed();\r
-    else if(evt.getSource()==remove2LeftMenuItem)\r
-            remove2LeftMenuItem_actionPerformed();\r
-    else if(evt.getSource()==remove2RightMenuItem)\r
-            remove2RightMenuItem_actionPerformed();\r
-    else if(evt.getSource()==removeGappedColumnMenuItem)\r
-            removeGappedColumnMenuItem_actionPerformed();\r
-    else if(evt.getSource()==removeAllGapsMenuItem)\r
-            removeAllGapsMenuItem_actionPerformed();\r
-    else if(evt.getSource()==findMenuItem)\r
-            findMenuItem_actionPerformed();\r
-    else if(evt.getSource()==font)\r
-            font_actionPerformed();\r
-    else if(evt.getSource()==featureSettings)\r
-            featureSettings_actionPerformed();\r
-    else if(evt.getSource()==overviewMenuItem)\r
-            overviewMenuItem_actionPerformed();\r
-    else if(evt.getSource()==noColourmenuItem)\r
-            noColourmenuItem_actionPerformed();\r
-    else if(evt.getSource()==clustalColour)\r
-            clustalColour_actionPerformed();\r
-    else if(evt.getSource()==zappoColour)\r
-            zappoColour_actionPerformed();\r
-    else if(evt.getSource()==taylorColour)\r
-            taylorColour_actionPerformed();\r
-    else if(evt.getSource()==hydrophobicityColour)\r
-            hydrophobicityColour_actionPerformed();\r
-    else if(evt.getSource()==helixColour)\r
-            helixColour_actionPerformed();\r
-    else if(evt.getSource()==strandColour)\r
-            strandColour_actionPerformed();\r
-    else if(evt.getSource()==turnColour)\r
-            turnColour_actionPerformed();\r
-    else if(evt.getSource()==buriedColour)\r
-            buriedColour_actionPerformed();\r
-    else if(evt.getSource()==nucleotideColour)\r
-            nucleotideColour_actionPerformed();\r
-    else if(evt.getSource()==modifyPID)\r
-            modifyPID_actionPerformed();\r
-    else if(evt.getSource()==modifyConservation)\r
-            modifyConservation_actionPerformed();\r
-    else if(evt.getSource()==userDefinedColour)\r
-            userDefinedColour_actionPerformed();\r
-    else if(evt.getSource()==PIDColour)\r
-            PIDColour_actionPerformed();\r
-    else if(evt.getSource()==BLOSUM62Colour)\r
-            BLOSUM62Colour_actionPerformed();\r
-    else if(evt.getSource()==annotationColour)\r
-           new AnnotationColourChooser(viewport, alignPanel);\r
-    else if(evt.getSource()==sortPairwiseMenuItem)\r
-            sortPairwiseMenuItem_actionPerformed();\r
-    else if(evt.getSource()==sortIDMenuItem)\r
-            sortIDMenuItem_actionPerformed();\r
-    else if(evt.getSource()==sortGroupMenuItem)\r
-            sortGroupMenuItem_actionPerformed();\r
-    else if(evt.getSource()==removeRedundancyMenuItem)\r
-            removeRedundancyMenuItem_actionPerformed();\r
-    else if(evt.getSource()==pairwiseAlignmentMenuItem)\r
-            pairwiseAlignmentMenuItem_actionPerformed();\r
-    else if(evt.getSource()==PCAMenuItem)\r
-            PCAMenuItem_actionPerformed();\r
-    else if(evt.getSource()==averageDistanceTreeMenuItem)\r
-            averageDistanceTreeMenuItem_actionPerformed();\r
-    else if(evt.getSource()==neighbourTreeMenuItem)\r
-            neighbourTreeMenuItem_actionPerformed();\r
-    else if(evt.getSource()==njTreeBlosumMenuItem)\r
-            njTreeBlosumMenuItem_actionPerformed();\r
-    else if(evt.getSource()==avDistanceTreeBlosumMenuItem)\r
-            avTreeBlosumMenuItem_actionPerformed();\r
-    else if(evt.getSource()==documentation)\r
-            documentation_actionPerformed();\r
-    else if(evt.getSource()==about)\r
-            about_actionPerformed();\r
-\r
- }\r
-\r
-  public void inputText_actionPerformed()\r
-  {\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);\r
-    Frame frame = new Frame();\r
-    frame.add(cap);\r
-    jalview.bin.JalviewLite.addFrame(frame, "Cut & Paste Input", 500, 500);\r
-  }\r
-\r
-  protected void outputText_actionPerformed(ActionEvent e)\r
-  {\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);\r
-    Frame frame = new Frame();\r
-    frame.add(cap);\r
-    jalview.bin.JalviewLite.addFrame(frame,\r
-                                     "Alignment output - " + e.getActionCommand(),\r
-                                     600, 500);\r
-    cap.setText(new AppletFormatAdapter().formatSequences(e.getActionCommand(),\r
-                                              viewport.getAlignment().getSequences(),\r
-                                                      viewport.showJVSuffix));\r
-  }\r
-\r
-  public void closeMenuItem_actionPerformed()\r
-  {\r
-    PaintRefresher.components.remove(viewport.alignment);\r
-    if(PaintRefresher.components.size()==0 && applet==null)\r
-      System.exit(0);\r
-\r
-    this.dispose();\r
-  }\r
-\r
-  Stack historyList = new Stack();\r
-  Stack redoList = new Stack();\r
-\r
-  void updateEditMenuBar()\r
-  {\r
-    if (historyList.size() > 0)\r
-    {\r
-      undoMenuItem.setEnabled(true);\r
-      HistoryItem hi = (HistoryItem) historyList.peek();\r
-      undoMenuItem.setLabel("Undo " + hi.getDescription());\r
-    }\r
-    else\r
-    {\r
-      undoMenuItem.setEnabled(false);\r
-      undoMenuItem.setLabel("Undo");\r
-    }\r
-\r
-    if (redoList.size() > 0)\r
-    {\r
-      redoMenuItem.setEnabled(true);\r
-      HistoryItem hi = (HistoryItem) redoList.peek();\r
-      redoMenuItem.setLabel("Redo " + hi.getDescription());\r
-    }\r
-    else\r
-    {\r
-      redoMenuItem.setEnabled(false);\r
-      redoMenuItem.setLabel("Redo");\r
-    }\r
-  }\r
-\r
-  public void addHistoryItem(HistoryItem hi)\r
-  {\r
-    historyList.push(hi);\r
-    updateEditMenuBar();\r
-  }\r
-\r
-  protected void undoMenuItem_actionPerformed()\r
-  {\r
-    HistoryItem hi = (HistoryItem) historyList.pop();\r
-    redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
-                                  HistoryItem.HIDE));\r
-    restoreHistoryItem(hi);\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  protected void redoMenuItem_actionPerformed()\r
-  {\r
-    HistoryItem hi = (HistoryItem) redoList.pop();\r
-    restoreHistoryItem(hi);\r
-    updateEditMenuBar();\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  // used by undo and redo\r
-  void restoreHistoryItem(HistoryItem hi)\r
-  {\r
-    hi.restore();\r
-\r
-    updateEditMenuBar();\r
-\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  public void moveSelectedSequences(boolean up)\r
-  {\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-    if (sg == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (up)\r
-    {\r
-      for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
-      {\r
-        SequenceI seq = viewport.alignment.getSequenceAt(i);\r
-        if (!sg.sequences.contains(seq))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
-        if (sg.sequences.contains(temp))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        viewport.alignment.getSequences().setElementAt(temp, i);\r
-        viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
-      {\r
-        SequenceI seq = viewport.alignment.getSequenceAt(i);\r
-        if (!sg.sequences.contains(seq))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
-        if (sg.sequences.contains(temp))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        viewport.alignment.getSequences().setElementAt(temp, i);\r
-        viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
-      }\r
-    }\r
-\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  StringBuffer copiedSequences;\r
-  protected void copy_actionPerformed()\r
-  {\r
-    if (viewport.getSelectionGroup() == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-    copiedSequences = new StringBuffer();\r
-    Hashtable orderedSeqs = new Hashtable();\r
-    for (int i = 0; i < sg.getSize(); i++)\r
-    {\r
-      SequenceI seq = sg.getSequenceAt(i);\r
-      int index = viewport.alignment.findIndex(seq);\r
-      orderedSeqs.put(index + "", seq);\r
-    }\r
-\r
-    int index = 0, startRes, endRes;\r
-    char ch;\r
-\r
-    for (int i = 0; i < sg.getSize(); i++)\r
-    {\r
-        SequenceI seq = null;\r
-\r
-        while (seq == null)\r
-        {\r
-            if (orderedSeqs.containsKey(index + ""))\r
-            {\r
-                seq = (SequenceI) orderedSeqs.get(index + "");\r
-                index++;\r
-\r
-                break;\r
-            }\r
-            else\r
-            {\r
-                index++;\r
-            }\r
-        }\r
-\r
-        //FIND START RES\r
-        //Returns residue following index if gap\r
-        startRes = seq.findPosition(sg.getStartRes());\r
-\r
-        //FIND END RES\r
-        //Need to find the residue preceeding index if gap\r
-        endRes = 0;\r
-\r
-        for (int j = 0; j < sg.getEndRes()+1 && j < seq.getLength(); j++)\r
-        {\r
-          ch = seq.getCharAt(j);\r
-          if (!jalview.util.Comparison.isGap( (ch)))\r
-          {\r
-            endRes++;\r
-          }\r
-        }\r
-\r
-        if(endRes>0)\r
-        {\r
-          endRes += seq.getStart() -1;\r
-        }\r
-\r
-        copiedSequences.append(seq.getName() + "\t" +\r
-            startRes + "\t" +\r
-            endRes + "\t" +\r
-            seq.getSequence(sg.getStartRes(),\r
-                sg.getEndRes() + 1) + "\n");\r
-    }\r
-\r
-  }\r
-\r
-  protected void pasteNew_actionPerformed()\r
-  {\r
-    paste(true);\r
-  }\r
-\r
-  protected void pasteThis_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
-                                   HistoryItem.PASTE));\r
-    paste(false);\r
-  }\r
-\r
-  void paste(boolean newAlignment)\r
-  {\r
-    try\r
-    {\r
-      if (copiedSequences == null)\r
-      {\r
-        return;\r
-      }\r
-\r
-      StringTokenizer st = new StringTokenizer(copiedSequences.toString());\r
-      Vector seqs = new Vector();\r
-      while (st.hasMoreElements())\r
-      {\r
-        String name = st.nextToken();\r
-        int start = Integer.parseInt(st.nextToken());\r
-        int end = Integer.parseInt(st.nextToken());\r
-        Sequence sequence = new Sequence(name, st.nextToken(), start, end);\r
-\r
-        if (!newAlignment)\r
-        {\r
-          viewport.alignment.addSequence(sequence);\r
-        }\r
-        else\r
-        {\r
-          seqs.addElement(sequence);\r
-        }\r
-      }\r
-\r
-      if (newAlignment)\r
-      {\r
-        SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
-        for (int i = 0; i < seqs.size(); i++)\r
-        {\r
-          newSeqs[i] = (SequenceI) seqs.elementAt(i);\r
-        }\r
-\r
-        String newtitle = new String("Copied sequences");\r
-        if (getTitle().startsWith("Copied sequences"))\r
-        {\r
-          newtitle = getTitle();\r
-        }\r
-        else\r
-        {\r
-          newtitle = newtitle.concat("- from " + getTitle());\r
-        }\r
-        AlignFrame af = new AlignFrame(new Alignment(newSeqs),\r
-                                       applet,\r
-                                       newtitle,\r
-                                       false);\r
-\r
-        jalview.bin.JalviewLite.addFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
-                                         NEW_WINDOW_HEIGHT);\r
-      }\r
-      else\r
-      {\r
-        viewport.setEndSeq(viewport.alignment.getHeight());\r
-        viewport.alignment.getWidth();\r
-        viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-      }\r
-\r
-    }\r
-    catch (Exception ex)\r
-    {} // could be anything being pasted in here\r
-\r
-  }\r
-\r
-  protected void cut_actionPerformed()\r
-  {\r
-    copy_actionPerformed();\r
-    delete_actionPerformed();\r
-  }\r
-\r
-  protected void delete_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
-                                   HistoryItem.HIDE));\r
-    if (viewport.getSelectionGroup() == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-    boolean allSequences = false;\r
-    if(sg.sequences.size()==viewport.alignment.getHeight())\r
-          allSequences = true;\r
-\r
-    for (int i = 0; i < sg.sequences.size(); i++)\r
-    {\r
-      SequenceI seq = sg.getSequenceAt(i);\r
-      int index = viewport.getAlignment().findIndex(seq);\r
-      seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
-\r
-      // If the cut affects all sequences, remove highlighted columns\r
-      if (allSequences)\r
-      {\r
-        viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
-                                                     sg.getEndRes() + 1);\r
-      }\r
-\r
-\r
-      if (seq.getSequence().length() < 1)\r
-      {\r
-        viewport.getAlignment().deleteSequence(seq);\r
-      }\r
-      else\r
-      {\r
-        viewport.getAlignment().getSequences().setElementAt(seq, index);\r
-      }\r
-    }\r
-\r
-    viewport.setSelectionGroup(null);\r
-    viewport.alignment.deleteGroup(sg);\r
-    viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getSize().height);\r
-    if (viewport.getAlignment().getHeight() < 1)\r
-    {\r
-      try\r
-      {\r
-        this.setVisible(false);\r
-      }\r
-      catch (Exception ex)\r
-      {}\r
-    }\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-\r
-  }\r
-\r
-  protected void deleteGroups_actionPerformed()\r
-  {\r
-    viewport.alignment.deleteAllGroups();\r
-    viewport.setSelectionGroup(null);\r
-\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void selectAllSequenceMenuItem_actionPerformed()\r
-  {\r
-    SequenceGroup sg = new SequenceGroup();\r
-    for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)\r
-    {\r
-      sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
-    }\r
-    sg.setEndRes(viewport.alignment.getWidth()-1);\r
-    viewport.setSelectionGroup(sg);\r
-    alignPanel.repaint();\r
-    PaintRefresher.Refresh(null, viewport.alignment);\r
-  }\r
-\r
-  public void deselectAllSequenceMenuItem_actionPerformed()\r
-  {\r
-    viewport.setSelectionGroup(null);\r
-    viewport.getColumnSelection().clear();\r
-    viewport.setSelectionGroup(null);\r
-    alignPanel.idPanel.idCanvas.searchResults = null;\r
-    alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);\r
-    alignPanel.repaint();\r
-    PaintRefresher.Refresh(null, viewport.alignment);\r
-  }\r
-\r
-  public void invertSequenceMenuItem_actionPerformed()\r
-  {\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-    for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)\r
-    {\r
-      sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
-    }\r
-\r
-    PaintRefresher.Refresh(null, viewport.alignment);\r
-  }\r
-\r
-  public void remove2LeftMenuItem_actionPerformed()\r
-  {\r
-    ColumnSelection colSel = viewport.getColumnSelection();\r
-    if (colSel.size() > 0)\r
-    {\r
-      addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
-                                     HistoryItem.HIDE));\r
-      int min = colSel.getMin();\r
-      viewport.getAlignment().trimLeft(min);\r
-      colSel.compensateForEdit(0, min);\r
-\r
-      if (viewport.getSelectionGroup() != null)\r
-      {\r
-        viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
-      }\r
-\r
-      Vector groups = viewport.alignment.getGroups();\r
-      for (int i = 0; i < groups.size(); i++)\r
-      {\r
-        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-        if (!sg.adjustForRemoveLeft(min))\r
-        {\r
-          viewport.alignment.deleteGroup(sg);\r
-        }\r
-      }\r
-      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-    }\r
-  }\r
-\r
-  public void remove2RightMenuItem_actionPerformed()\r
-  {\r
-    ColumnSelection colSel = viewport.getColumnSelection();\r
-    if (colSel.size() > 0)\r
-    {\r
-      addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
-                                     HistoryItem.HIDE));\r
-      int max = colSel.getMax();\r
-      viewport.getAlignment().trimRight(max);\r
-      if (viewport.getSelectionGroup() != null)\r
-      {\r
-        viewport.getSelectionGroup().adjustForRemoveRight(max);\r
-      }\r
-\r
-      Vector groups = viewport.alignment.getGroups();\r
-      for (int i = 0; i < groups.size(); i++)\r
-      {\r
-        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-        if (!sg.adjustForRemoveRight(max))\r
-        {\r
-          viewport.alignment.deleteGroup(sg);\r
-        }\r
-      }\r
-      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-    }\r
-\r
-  }\r
-\r
-  public void removeGappedColumnMenuItem_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
-                                   viewport.alignment,\r
-                                   HistoryItem.HIDE));\r
-\r
-    //This is to maintain viewport position on first residue\r
-    //of first sequence\r
-    SequenceI seq = viewport.alignment.getSequenceAt(0);\r
-    int startRes = seq.findPosition(viewport.startRes);\r
-\r
-    viewport.getAlignment().removeGaps();\r
-\r
-    viewport.setStartRes(seq.findIndex(startRes)-1);\r
-\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  public void removeAllGapsMenuItem_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
-                                   HistoryItem.HIDE));\r
-\r
-    //This is to maintain viewport position on first residue\r
-    //of first sequence\r
-    SequenceI seq = viewport.alignment.getSequenceAt(0);\r
-    int startRes = seq.findPosition(viewport.startRes);\r
-\r
-    SequenceI current;\r
-    int jSize;\r
-\r
-    Vector seqs=null;\r
-\r
-    int start=0, end = viewport.alignment.getWidth();\r
-\r
-    if (viewport.getSelectionGroup() != null\r
-        && viewport.getSelectionGroup().sequences != null\r
-        && viewport.getSelectionGroup().sequences.size()>0)\r
-    {\r
-      seqs = viewport.getSelectionGroup().sequences;\r
-      start = viewport.getSelectionGroup().getStartRes();\r
-      end = viewport.getSelectionGroup().getEndRes()+1;\r
-    }\r
-    else\r
-      seqs = viewport.alignment.getSequences();\r
-\r
-    for (int i = 0; i < seqs.size(); i++)\r
-    {\r
-      current = (SequenceI) seqs.elementAt(i);\r
-      jSize = current.getLength();\r
-\r
-      // Removing a range is much quicker than removing gaps\r
-      // one by one for long sequences\r
-      int j = start;\r
-      int rangeStart=-1, rangeEnd=-1;\r
-\r
-      do\r
-      {\r
-        if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
-        {\r
-          if(rangeStart==-1)\r
-           {\r
-             rangeStart = j;\r
-             rangeEnd = j+1;\r
-           }\r
-           else\r
-           {\r
-             rangeEnd++;\r
-           }\r
-           j++;\r
-        }\r
-        else\r
-        {\r
-          if(rangeStart>-1)\r
-          {\r
-            current.deleteChars(rangeStart, rangeEnd);\r
-            j-=rangeEnd-rangeStart;\r
-            jSize-=rangeEnd-rangeStart;\r
-            rangeStart = -1;\r
-            rangeEnd = -1;\r
-          }\r
-          else\r
-            j++;\r
-        }\r
-      }\r
-      while (j < end && j < jSize);\r
-      if(rangeStart>-1)\r
-      {\r
-       current.deleteChars(rangeStart, rangeEnd);\r
-      }\r
-    }\r
-    viewport.setStartRes(seq.findIndex(startRes)-1);\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  public void alignmentChanged()\r
-  {\r
-    viewport.updateConsensus();\r
-    viewport.updateConservation ();\r
-    resetAllColourSchemes();\r
-    if(alignPanel.overviewPanel!=null)\r
-      alignPanel.overviewPanel.updateOverviewImage();\r
-\r
-    viewport.alignment.adjustSequenceAnnotations();\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  void resetAllColourSchemes()\r
-  {\r
-    ColourSchemeI cs = viewport.globalColourScheme;\r
-    if(cs!=null)\r
-    {\r
-      if (cs instanceof ClustalxColourScheme)\r
-      {\r
-        ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
-            resetClustalX(viewport.alignment.getSequences(),\r
-                          viewport.alignment.getWidth());\r
-      }\r
-\r
-      cs.setConsensus(viewport.vconsensus);\r
-      if (cs.conservationApplied())\r
-      {\r
-        Alignment al = (Alignment) viewport.alignment;\r
-        Conservation c = new Conservation("All",\r
-                                          ResidueProperties.propHash, 3,\r
-                                          al.getSequences(), 0,\r
-                                          al.getWidth() - 1);\r
-        c.calculate();\r
-        c.verdict(false, viewport.ConsPercGaps);\r
-\r
-        cs.setConservation(c);\r
-      }\r
-    }\r
-\r
-    int s, sSize = viewport.alignment.getGroups().size();\r
-    for(s=0; s<sSize; s++)\r
-    {\r
-      SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
-      if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
-      {\r
-        ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
-      }\r
-      sg.recalcConservation();\r
-    }\r
-  }\r
-\r
-\r
-\r
-  public void findMenuItem_actionPerformed()\r
-  {\r
-    new Finder(alignPanel);\r
-  }\r
-\r
-  public void font_actionPerformed()\r
-  {\r
-    new FontChooser(alignPanel);\r
-  }\r
-\r
-\r
-  public void seqLimits_itemStateChanged()\r
-  {\r
-    viewport.setShowJVSuffix(seqLimits.getState());\r
-    alignPanel.fontChanged();\r
-    alignPanel.repaint();\r
-  }\r
-\r
-\r
-  protected void colourTextMenuItem_actionPerformed()\r
-  {\r
-    viewport.setColourText(colourTextMenuItem.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  protected void wrapMenuItem_actionPerformed()\r
-  {\r
-    viewport.setWrapAlignment(wrapMenuItem.getState());\r
-    alignPanel.setWrapAlignment(wrapMenuItem.getState());\r
-    scaleAbove.setEnabled(wrapMenuItem.getState());\r
-    scaleLeft.setEnabled(wrapMenuItem.getState());\r
-    scaleRight.setEnabled(wrapMenuItem.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  protected void scaleAbove_actionPerformed()\r
-  {\r
-    viewport.setScaleAboveWrapped(scaleAbove.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  protected void scaleLeft_actionPerformed()\r
-  {\r
-    viewport.setScaleLeftWrapped(scaleLeft.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  protected void scaleRight_actionPerformed()\r
-  {\r
-    viewport.setScaleRightWrapped(scaleRight.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void viewBoxesMenuItem_actionPerformed()\r
-  {\r
-    viewport.setShowBoxes(viewBoxesMenuItem.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void viewTextMenuItem_actionPerformed()\r
-  {\r
-    viewport.setShowText(viewTextMenuItem.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  protected void renderGapsMenuItem_actionPerformed()\r
-  {\r
-    viewport.setRenderGaps(renderGapsMenuItem.getState());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void annotationPanelMenuItem_actionPerformed()\r
-  {\r
-    viewport.setShowAnnotation(annotationPanelMenuItem.getState());\r
-    alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());\r
-  }\r
-\r
-  public void featureSettings_actionPerformed()\r
-  {\r
-    new FeatureSettings(viewport, alignPanel);\r
-  }\r
-\r
-  public void overviewMenuItem_actionPerformed()\r
-  {\r
-    if (alignPanel.overviewPanel != null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    Frame frame = new Frame();\r
-    OverviewPanel overview = new OverviewPanel(alignPanel);\r
-    frame.add(overview);\r
-    // +50 must allow for applet frame window\r
-    jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),\r
-                                     overview.preferredSize().width,\r
-                                     overview.preferredSize().height + 50);\r
-\r
-    frame.pack();\r
-    frame.addWindowListener(new WindowAdapter()\r
-    {\r
-      public void windowClosing(WindowEvent e)\r
-      {\r
-        alignPanel.setOverviewPanel(null);\r
-      };\r
-    });\r
-\r
-    alignPanel.setOverviewPanel(overview);\r
-\r
-  }\r
-\r
-  protected void noColourmenuItem_actionPerformed()\r
-  {\r
-    changeColour(null);\r
-  }\r
-\r
-  public void clustalColour_actionPerformed()\r
-  {\r
-    abovePIDThreshold.setState(false);\r
-    changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(),\r
-                                          viewport.alignment.getWidth()));\r
-  }\r
-\r
-  public void zappoColour_actionPerformed()\r
-  {\r
-    changeColour(new ZappoColourScheme());\r
-  }\r
-\r
-  public void taylorColour_actionPerformed()\r
-  {\r
-    changeColour(new TaylorColourScheme());\r
-  }\r
-\r
-  public void hydrophobicityColour_actionPerformed()\r
-  {\r
-    changeColour(new HydrophobicColourScheme());\r
-  }\r
-\r
-  public void helixColour_actionPerformed()\r
-  {\r
-    changeColour(new HelixColourScheme());\r
-  }\r
-\r
-  public void strandColour_actionPerformed()\r
-  {\r
-    changeColour(new StrandColourScheme());\r
-  }\r
-\r
-  public void turnColour_actionPerformed()\r
-  {\r
-    changeColour(new TurnColourScheme());\r
-  }\r
-\r
-  public void buriedColour_actionPerformed()\r
-  {\r
-    changeColour(new BuriedColourScheme());\r
-  }\r
-\r
-  public void nucleotideColour_actionPerformed()\r
-  {\r
-    changeColour(new NucleotideColourScheme());\r
-  }\r
-\r
-  protected void applyToAllGroups_actionPerformed()\r
-  {\r
-    viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());\r
-  }\r
-\r
-  void changeColour(ColourSchemeI cs)\r
-  {\r
-    int threshold = 0;\r
-\r
-    if(cs!=null)\r
-    {\r
-      if (viewport.getAbovePIDThreshold())\r
-      {\r
-        threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
-\r
-        cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
-\r
-        viewport.setGlobalColourScheme(cs);\r
-      }\r
-      else\r
-      {\r
-        cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
-      }\r
-\r
-      if (viewport.getConservationSelected())\r
-      {\r
-\r
-        Alignment al = (Alignment) viewport.alignment;\r
-        Conservation c = new Conservation("All",\r
-                                          ResidueProperties.propHash, 3,\r
-                                          al.getSequences(), 0,\r
-                                          al.getWidth() - 1);\r
-\r
-        c.calculate();\r
-        c.verdict(false, viewport.ConsPercGaps);\r
-\r
-        cs.setConservation(c);\r
-\r
-        cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
-            "Background"));\r
-\r
-      }\r
-      else\r
-      {\r
-        cs.setConservation(null);\r
-      }\r
-\r
-      cs.setConsensus(viewport.vconsensus);\r
-\r
-    }\r
-    viewport.setGlobalColourScheme(cs);\r
-\r
-    if (viewport.getColourAppliesToAllGroups())\r
-    {\r
-      Vector groups = viewport.alignment.getGroups();\r
-      for (int i = 0; i < groups.size(); i++)\r
-      {\r
-        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-\r
-        if(cs==null)\r
-        {\r
-          sg.cs = null;\r
-          continue;\r
-        }\r
-        if (cs instanceof ClustalxColourScheme)\r
-        {\r
-          sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
-        }\r
-        else\r
-        {\r
-          try\r
-          {\r
-            sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
-          }\r
-          catch (Exception ex)\r
-          {\r
-            ex.printStackTrace();\r
-            sg.cs = cs;\r
-          }\r
-        }\r
-\r
-        if (viewport.getAbovePIDThreshold()\r
-            || cs instanceof PIDColourScheme\r
-            || cs instanceof Blosum62ColourScheme)\r
-        {\r
-          sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
-          sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
-        }\r
-        else\r
-          sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
-\r
-        if (viewport.getConservationSelected())\r
-        {\r
-          Conservation c = new Conservation("Group",\r
-                                            ResidueProperties.propHash, 3,\r
-                                            sg.sequences, 0,\r
-                                            viewport.alignment.getWidth() - 1);\r
-          c.calculate();\r
-          c.verdict(false, viewport.ConsPercGaps);\r
-          sg.cs.setConservation(c);\r
-        }\r
-        else\r
-        {\r
-          sg.cs.setConservation(null);\r
-          sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
-        }\r
-\r
-      }\r
-    }\r
-\r
-\r
-    if (alignPanel.getOverviewPanel() != null)\r
-    {\r
-      alignPanel.getOverviewPanel().updateOverviewImage();\r
-    }\r
-\r
-    alignPanel.repaint();\r
-  }\r
-\r
-\r
-\r
-  protected void modifyPID_actionPerformed()\r
-  {\r
-    if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
-    {\r
-      SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
-                                     "Background");\r
-      SliderPanel.showPIDSlider();\r
-    }\r
-  }\r
-\r
-  protected void modifyConservation_actionPerformed()\r
-  {\r
-    if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
-    {\r
-      SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
-                                        "Background");\r
-      SliderPanel.showConservationSlider();\r
-    }\r
-  }\r
-\r
-  protected void conservationMenuItem_actionPerformed()\r
-  {\r
-    viewport.setConservationSelected(conservationMenuItem.getState());\r
-\r
-    viewport.setAbovePIDThreshold(false);\r
-    abovePIDThreshold.setState(false);\r
-\r
-    changeColour(viewport.getGlobalColourScheme());\r
-\r
-    modifyConservation_actionPerformed();\r
-  }\r
-\r
-  public void abovePIDThreshold_actionPerformed()\r
-  {\r
-    viewport.setAbovePIDThreshold(abovePIDThreshold.getState());\r
-\r
-    conservationMenuItem.setState(false);\r
-    viewport.setConservationSelected(false);\r
-\r
-    changeColour(viewport.getGlobalColourScheme());\r
-\r
-    modifyPID_actionPerformed();\r
-  }\r
-\r
-  public void userDefinedColour_actionPerformed()\r
-  {\r
-    new UserDefinedColours(alignPanel, null);\r
-  }\r
-\r
-  public void PIDColour_actionPerformed()\r
-  {\r
-    changeColour(new PIDColourScheme());\r
-  }\r
-\r
-  public void BLOSUM62Colour_actionPerformed()\r
-  {\r
-    changeColour(new Blosum62ColourScheme());\r
-  }\r
-\r
-  public void sortPairwiseMenuItem_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
-                                   HistoryItem.SORT));\r
-    AlignmentSorter.sortByPID(viewport.getAlignment(),\r
-                              viewport.getAlignment().getSequenceAt(0));\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void sortIDMenuItem_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
-                                   HistoryItem.SORT));\r
-    AlignmentSorter.sortByID(viewport.getAlignment());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void sortGroupMenuItem_actionPerformed()\r
-  {\r
-    addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
-                                   HistoryItem.SORT));\r
-    AlignmentSorter.sortByGroup(viewport.getAlignment());\r
-    alignPanel.repaint();\r
-\r
-  }\r
-\r
-  public void removeRedundancyMenuItem_actionPerformed()\r
-  {\r
-    RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
-    Frame frame = new Frame();\r
-    frame.add(sp);\r
-    jalview.bin.JalviewLite.addFrame(frame, "Redundancy threshold selection",\r
-                                     400, 120);\r
-\r
-  }\r
-\r
-  public void pairwiseAlignmentMenuItem_actionPerformed()\r
-  {\r
-    if (viewport.getSelectionGroup().getSize() > 1)\r
-    {\r
-      Frame frame = new Frame();\r
-      frame.add(new PairwiseAlignPanel(alignPanel));\r
-      jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);\r
-    }\r
-  }\r
-\r
-  public void PCAMenuItem_actionPerformed()\r
-  {\r
-    //are the sequences aligned?\r
-    if (!viewport.alignment.isAligned())\r
-    {\r
-      SequenceI current;\r
-      int Width = viewport.getAlignment().getWidth();\r
-\r
-      for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
-           i++)\r
-      {\r
-        current = viewport.getAlignment().getSequenceAt(i);\r
-\r
-        if (current.getLength() < Width)\r
-        {\r
-          current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
-        }\r
-      }\r
-      alignPanel.repaint();\r
-    }\r
-\r
-    if ( (viewport.getSelectionGroup() != null &&\r
-          viewport.getSelectionGroup().getSize() < 4 &&\r
-          viewport.getSelectionGroup().getSize() > 0)\r
-        || viewport.getAlignment().getHeight() < 4)\r
-    {\r
-      return;\r
-    }\r
-\r
-    try\r
-    {\r
-      new PCAPanel(viewport);\r
-    }\r
-    catch (java.lang.OutOfMemoryError ex)\r
-    {\r
-    }\r
-\r
-  }\r
-\r
-  public void averageDistanceTreeMenuItem_actionPerformed()\r
-  {\r
-    NewTreePanel("AV", "PID", "Average distance tree using PID");\r
-  }\r
-\r
-  public void neighbourTreeMenuItem_actionPerformed()\r
-  {\r
-    NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
-  }\r
-\r
-  protected void njTreeBlosumMenuItem_actionPerformed()\r
-  {\r
-    NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
-  }\r
-\r
-  protected void avTreeBlosumMenuItem_actionPerformed()\r
-  {\r
-    NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
-  }\r
-\r
-  void NewTreePanel(String type, String pwType, String title)\r
-  {\r
-    //are the sequences aligned?\r
-    if (!viewport.alignment.isAligned())\r
-    {\r
-      SequenceI current;\r
-      int Width = viewport.getAlignment().getWidth();\r
-\r
-      for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
-           i++)\r
-      {\r
-        current = viewport.getAlignment().getSequenceAt(i);\r
-\r
-        if (current.getLength() < Width)\r
-        {\r
-          current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
-        }\r
-      }\r
-      alignPanel.repaint();\r
-\r
-    }\r
-\r
-    final TreePanel tp;\r
-    if (viewport.getSelectionGroup() != null &&\r
-        viewport.getSelectionGroup().getSize() > 3)\r
-    {\r
-      tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
-                         pwType,\r
-                         0, viewport.alignment.getWidth());\r
-    }\r
-    else\r
-    {\r
-      tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
-                         type, pwType, 0, viewport.alignment.getWidth());\r
-    }\r
-\r
-    addTreeMenuItem(tp, title);\r
-\r
-    jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);\r
-  }\r
-\r
-  void loadTree_actionPerformed()\r
-  {\r
-    TreePanel tp = null;\r
-\r
-      CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);\r
-      cap.setText("Paste your Newick tree file here.");\r
-      cap.treeImport = true;\r
-      Frame frame = new Frame();\r
-      frame.add(cap);\r
-      jalview.bin.JalviewLite.addFrame(frame, "Paste Newick file ", 400, 300);\r
-  }\r
-\r
-  public void loadTree(jalview.io.NewickFile tree, String treeFile)\r
-  {\r
-    TreePanel tp = new TreePanel(viewport,\r
-                      viewport.getAlignment().getSequences(),\r
-                      tree, "From File - ", treeFile);\r
-    jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);\r
-    addTreeMenuItem(tp, treeFile);\r
-  }\r
-\r
-  void addTreeMenuItem(final TreePanel treePanel, String title)\r
-  {\r
-    final MenuItem item = new MenuItem(title);\r
-    sortByTreeMenu.add(item);\r
-    item.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent evt)\r
-      {\r
-        addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
-                                       HistoryItem.SORT));\r
-        AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
-        alignPanel.repaint();\r
-      }\r
-    });\r
-\r
-    treePanel.addWindowListener(new WindowAdapter()\r
-    {\r
-      public void windowClosing(WindowEvent e)\r
-      {\r
-        sortByTreeMenu.remove(item);\r
-      };\r
-    });\r
-  }\r
-\r
-  protected void documentation_actionPerformed()\r
-  {\r
-    showURL("http://www.jalview.org/help.html", "HELP");\r
-  }\r
-\r
-  protected void about_actionPerformed()\r
-  {\r
-\r
-    class AboutPanel extends Canvas\r
-    {\r
-      String version;\r
-      public AboutPanel(String version)\r
-      { this.version = version; }\r
-\r
-      public void paint(Graphics g)\r
-      {\r
-        g.setColor(Color.white);\r
-        g.fillRect(0, 0, getSize().width, getSize().height);\r
-        g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
-        FontMetrics fm = g.getFontMetrics();\r
-        int fh = fm.getHeight();\r
-        int y = 5, x = 7;\r
-        g.setColor(Color.black);\r
-        g.setFont(new Font("Helvetica", Font.BOLD, 14));\r
-        g.drawString("Jalview - Release "+version, 200, y += fh);\r
-        g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
-        g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",\r
-                     x, y += fh * 2);\r
-        g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",\r
-                     x, y += fh);\r
-        g.drawString(\r
-            "For any issues relating to Jalview, email help@jalview.org", x,\r
-            y += fh);\r
-        g.drawString("If  you use JalView, please cite:", x, y += fh + 8);\r
-        g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",\r
-                     x, y += fh);\r
-        g.drawString("Bioinformatics,  2004 12;426-7.", x, y += fh);\r
-      }\r
-    }\r
-\r
-    String version = "test";\r
-    java.net.URL url = getClass().getResource("/.build_properties");\r
-    if (url != null)\r
-    {\r
-      try\r
-      {\r
-        BufferedReader reader = new BufferedReader(new InputStreamReader(\r
-            url.openStream()));\r
-        String line;\r
-        while ( (line = reader.readLine()) != null)\r
-        {\r
-          if (line.indexOf("VERSION") > -1)\r
-          {\r
-            version = line.substring(line.indexOf("=") + 1);\r
-          }\r
-        }\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-\r
-\r
-    Frame frame = new Frame();\r
-    frame.add(new AboutPanel(version));\r
-    jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);\r
-\r
-  }\r
-\r
-  public void showURL(String url, String target)\r
-  {\r
-    if (applet == null)\r
-    {\r
-      System.out.println("Not running as applet - no browser available.");\r
-    }\r
-    else\r
-    {\r
-      try\r
-      {\r
-        applet.getAppletContext().showDocument(new java.net.URL(url),\r
-                                               target);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-  }\r
-\r
-\r
-  //////////////////////////////////////////////////////////////////////////////////\r
-  //JBuilder Graphics here\r
-\r
-    protected MenuBar alignFrameMenuBar = new MenuBar();\r
-    protected Menu fileMenu = new Menu("File");\r
-    protected MenuItem loadTree = new MenuItem("Load Associated Tree");\r
-    protected MenuItem closeMenuItem = new MenuItem("Close");\r
-    protected Menu editMenu = new Menu("Edit");\r
-    protected Menu viewMenu = new Menu("View");\r
-    protected Menu colourMenu = new Menu("Colour");\r
-    protected Menu calculateMenu = new Menu("Calculate");\r
-    protected MenuItem selectAllSequenceMenuItem = new MenuItem("Select all");\r
-    protected MenuItem deselectAllSequenceMenuItem = new MenuItem("Deselect All");\r
-    protected MenuItem invertSequenceMenuItem = new MenuItem("Invert Selection");\r
-    protected MenuItem remove2LeftMenuItem = new MenuItem();\r
-    protected MenuItem remove2RightMenuItem = new MenuItem();\r
-    protected MenuItem removeGappedColumnMenuItem = new MenuItem();\r
-    protected MenuItem removeAllGapsMenuItem = new MenuItem();\r
-    protected CheckboxMenuItem viewBoxesMenuItem = new CheckboxMenuItem();\r
-    protected CheckboxMenuItem viewTextMenuItem = new CheckboxMenuItem();\r
-    protected MenuItem sortPairwiseMenuItem = new MenuItem();\r
-    protected MenuItem sortIDMenuItem = new MenuItem();\r
-    protected MenuItem sortGroupMenuItem = new MenuItem();\r
-    protected MenuItem removeRedundancyMenuItem = new MenuItem();\r
-    protected MenuItem pairwiseAlignmentMenuItem = new MenuItem();\r
-    protected MenuItem PCAMenuItem = new MenuItem();\r
-    protected MenuItem averageDistanceTreeMenuItem = new MenuItem();\r
-    protected MenuItem neighbourTreeMenuItem = new MenuItem();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-    public Label statusBar = new Label();\r
-    protected Menu outputTextboxMenu = new Menu();\r
-    protected MenuItem clustalColour = new MenuItem();\r
-    protected MenuItem zappoColour = new MenuItem();\r
-    protected MenuItem taylorColour = new MenuItem();\r
-    protected MenuItem hydrophobicityColour = new MenuItem();\r
-    protected MenuItem helixColour = new MenuItem();\r
-    protected MenuItem strandColour = new MenuItem();\r
-    protected MenuItem turnColour = new MenuItem();\r
-    protected MenuItem buriedColour = new MenuItem();\r
-    protected MenuItem userDefinedColour = new MenuItem();\r
-    protected MenuItem PIDColour = new MenuItem();\r
-    protected MenuItem BLOSUM62Colour = new MenuItem();\r
-    MenuItem njTreeBlosumMenuItem = new MenuItem();\r
-    MenuItem avDistanceTreeBlosumMenuItem = new MenuItem();\r
-    protected CheckboxMenuItem annotationPanelMenuItem = new CheckboxMenuItem();\r
-    protected CheckboxMenuItem colourTextMenuItem = new CheckboxMenuItem();\r
-    MenuItem overviewMenuItem = new MenuItem();\r
-    protected MenuItem undoMenuItem = new MenuItem();\r
-    protected MenuItem redoMenuItem = new MenuItem();\r
-    protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();\r
-    MenuItem noColourmenuItem = new MenuItem();\r
-    protected CheckboxMenuItem wrapMenuItem = new CheckboxMenuItem();\r
-    protected CheckboxMenuItem renderGapsMenuItem = new CheckboxMenuItem();\r
-    MenuItem findMenuItem = new MenuItem();\r
-    Menu searchMenu = new Menu();\r
-    protected CheckboxMenuItem abovePIDThreshold = new CheckboxMenuItem();\r
-    protected MenuItem nucleotideColour = new MenuItem();\r
-    MenuItem deleteGroups = new MenuItem();\r
-    MenuItem delete = new MenuItem();\r
-    MenuItem copy = new MenuItem();\r
-    MenuItem cut = new MenuItem();\r
-    Menu pasteMenu = new Menu();\r
-    MenuItem pasteNew = new MenuItem();\r
-    MenuItem pasteThis = new MenuItem();\r
-    protected CheckboxMenuItem applyToAllGroups = new CheckboxMenuItem();\r
-    protected MenuItem font = new MenuItem();\r
-    protected CheckboxMenuItem scaleAbove = new CheckboxMenuItem();\r
-    protected CheckboxMenuItem scaleLeft = new CheckboxMenuItem();\r
-    protected CheckboxMenuItem scaleRight = new CheckboxMenuItem();\r
-    MenuItem modifyPID = new MenuItem();\r
-    MenuItem modifyConservation = new MenuItem();\r
-    protected Menu sortByTreeMenu = new Menu();\r
-    Menu sort = new Menu();\r
-    Menu calculate = new Menu();\r
-    MenuItem inputText = new MenuItem();\r
-    Menu helpMenu = new Menu();\r
-    MenuItem documentation = new MenuItem();\r
-    MenuItem about = new MenuItem();\r
-    protected CheckboxMenuItem seqLimits = new CheckboxMenuItem();\r
-  Panel embeddedMenu;\r
-  Label embeddedEdit;\r
-  Label embeddedSearch;\r
-  Label embeddedView;\r
-  Label embeddedColour;\r
-  Label embeddedFile;\r
-  Label embeddedHelp;\r
-  Label embeddedCalculate;\r
-  FlowLayout flowLayout1;\r
-\r
-  private void jbInit() throws Exception {\r
-\r
-      setMenuBar(alignFrameMenuBar);\r
-\r
-      MenuItem item;\r
-\r
-      // dynamically fill save as menu with available formats\r
-      for (int i = 0; i < jalview.io.AppletFormatAdapter.formats.size(); i++)\r
-      {\r
-\r
-        item = new MenuItem( (String) jalview.io.AppletFormatAdapter.formats.\r
-                            elementAt(\r
-                                i));\r
-        item.addActionListener(new java.awt.event.ActionListener()\r
-        {\r
-          public void actionPerformed(ActionEvent e)\r
-          {\r
-            outputText_actionPerformed(e);\r
-          }\r
-        });\r
-\r
-        outputTextboxMenu.add(item);\r
-      }\r
-        closeMenuItem.addActionListener(this);\r
-\r
-        loadTree.addActionListener(this);\r
-        selectAllSequenceMenuItem.addActionListener(this);\r
-        deselectAllSequenceMenuItem.addActionListener(this);\r
-        invertSequenceMenuItem.addActionListener(this);\r
-        remove2LeftMenuItem.setLabel("Remove Left");\r
-        remove2LeftMenuItem.addActionListener(this);\r
-        remove2RightMenuItem.setLabel("Remove Right");\r
-        remove2RightMenuItem.addActionListener(this);\r
-        removeGappedColumnMenuItem.setLabel("Remove Empty Columns");\r
-        removeGappedColumnMenuItem.addActionListener(this);\r
-        removeAllGapsMenuItem.setLabel("Remove All Gaps");\r
-        removeAllGapsMenuItem.addActionListener(this);\r
-        viewBoxesMenuItem.setLabel("Boxes");\r
-        viewBoxesMenuItem.setState(true);\r
-        viewBoxesMenuItem.addItemListener(this);\r
-        viewTextMenuItem.setLabel("Text");\r
-        viewTextMenuItem.setState(true);\r
-        viewTextMenuItem.addItemListener(this);\r
-        sortPairwiseMenuItem.setLabel("by Pairwise Identity");\r
-        sortPairwiseMenuItem.addActionListener(this);\r
-        sortIDMenuItem.setLabel("by ID");\r
-        sortIDMenuItem.addActionListener(this);\r
-        sortGroupMenuItem.setLabel("by Group");\r
-        sortGroupMenuItem.addActionListener(this);\r
-        removeRedundancyMenuItem.setLabel("Remove Redundancy...");\r
-        removeRedundancyMenuItem.addActionListener(this);\r
-        pairwiseAlignmentMenuItem.setLabel("Pairwise Alignments...");\r
-        pairwiseAlignmentMenuItem.addActionListener(this);\r
-        PCAMenuItem.setLabel("Principal Component Analysis");\r
-        PCAMenuItem.addActionListener(this);\r
-        averageDistanceTreeMenuItem.setLabel(\r
-            "Average Distance Using % Identity");\r
-        averageDistanceTreeMenuItem.addActionListener(this);\r
-        neighbourTreeMenuItem.setLabel("Neighbour Joining Using % Identity");\r
-        neighbourTreeMenuItem.addActionListener(this);\r
-        alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        statusBar.setBackground(Color.white);\r
-        statusBar.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        statusBar.setText("Status bar");\r
-        outputTextboxMenu.setLabel("Output to Textbox");\r
-        clustalColour.setLabel("Clustalx");\r
-\r
-        clustalColour.addActionListener(this);\r
-        zappoColour.setLabel("Zappo");\r
-        zappoColour.addActionListener(this);\r
-        taylorColour.setLabel("Taylor");\r
-        taylorColour.addActionListener(this);\r
-        hydrophobicityColour.setLabel("Hydrophobicity");\r
-        hydrophobicityColour.addActionListener(this);\r
-        helixColour.setLabel("Helix Propensity");\r
-        helixColour.addActionListener(this);\r
-        strandColour.setLabel("Strand Propensity");\r
-        strandColour.addActionListener(this);\r
-        turnColour.setLabel("Turn Propensity");\r
-        turnColour.addActionListener(this);\r
-        buriedColour.setLabel("Buried Index");\r
-        buriedColour.addActionListener(this);\r
-        userDefinedColour.setLabel("User Defined...");\r
-        userDefinedColour.addActionListener(this);\r
-        PIDColour.setLabel("Percentage Identity");\r
-        PIDColour.addActionListener(this);\r
-        BLOSUM62Colour.setLabel("BLOSUM62 Score");\r
-        BLOSUM62Colour.addActionListener(this);\r
-        avDistanceTreeBlosumMenuItem.setLabel(\r
-            "Average Distance Using BLOSUM62");\r
-        avDistanceTreeBlosumMenuItem.addActionListener(this);\r
-        njTreeBlosumMenuItem.setLabel("Neighbour Joining Using BLOSUM62");\r
-        njTreeBlosumMenuItem.addActionListener(this);\r
-        annotationPanelMenuItem.setLabel("Show Annotations");\r
-        annotationPanelMenuItem.addItemListener(this);\r
-        colourTextMenuItem.setLabel("Colour Text");\r
-        colourTextMenuItem.addItemListener(this);\r
-        overviewMenuItem.setLabel("Overview Window");\r
-        overviewMenuItem.addActionListener(this);\r
-        undoMenuItem.setEnabled(false);\r
-        undoMenuItem.setLabel("Undo");\r
-        undoMenuItem.addActionListener(this);\r
-        redoMenuItem.setEnabled(false);\r
-        redoMenuItem.setLabel("Redo");\r
-        redoMenuItem.addActionListener(this);\r
-        conservationMenuItem.setLabel("by Conservation");\r
-        conservationMenuItem.addItemListener(this);\r
-        noColourmenuItem.setLabel("None");\r
-        noColourmenuItem.addActionListener(this);\r
-        wrapMenuItem.setLabel("Wrap");\r
-        wrapMenuItem.addItemListener(this);\r
-        renderGapsMenuItem.setLabel("Show Gaps");\r
-        renderGapsMenuItem.setState(true);\r
-        renderGapsMenuItem.addItemListener(this);\r
-        findMenuItem.setLabel("Find...");\r
-        findMenuItem.addActionListener(this);\r
-        searchMenu.setLabel("Search");\r
-\r
-        abovePIDThreshold.setLabel("Above Identity Threshold");\r
-        abovePIDThreshold.addItemListener(this);\r
-        nucleotideColour.setLabel("Nucleotide");\r
-        nucleotideColour.addActionListener(this);\r
-        deleteGroups.setLabel("Undefine Groups");\r
-        deleteGroups.addActionListener(this);\r
-        copy.setLabel("Copy");\r
-        copy.addActionListener(this);\r
-        cut.setLabel("Cut");\r
-        cut.addActionListener(this);\r
-        delete.setLabel("Delete");\r
-        delete.addActionListener(this);\r
-        pasteMenu.setLabel("Paste");\r
-        pasteNew.setLabel("To New Alignment");\r
-        pasteNew.addActionListener(this);\r
-        pasteThis.setLabel("Add To This Alignment");\r
-        pasteThis.addActionListener(this);\r
-        applyToAllGroups.setLabel("Apply Colour To All Groups");\r
-        applyToAllGroups.setState(true);\r
-        applyToAllGroups.addItemListener(this);\r
-        font.setLabel("Font...");\r
-        font.addActionListener(this);\r
-        scaleAbove.setLabel("Scale Above");\r
-        scaleAbove.setState(true);\r
-        scaleAbove.setEnabled(false);\r
-        scaleAbove.addItemListener(this);\r
-        scaleLeft.setEnabled(false);\r
-        scaleLeft.setState(true);\r
-        scaleLeft.setLabel("Scale Left");\r
-        scaleLeft.addItemListener(this);\r
-        scaleRight.setEnabled(false);\r
-        scaleRight.setState(true);\r
-        scaleRight.setLabel("Scale Right");\r
-        scaleRight.addItemListener(this);\r
-        modifyPID.setLabel("Modify Identity Threshold...");\r
-        modifyPID.addActionListener(this);\r
-        modifyConservation.setLabel("Modify Conservation Threshold...");\r
-        modifyConservation.addActionListener(this);\r
-        sortByTreeMenu.setLabel("By Tree Order");\r
-        sort.setLabel("Sort");\r
-        calculate.setLabel("Calculate Tree");\r
-        inputText.setLabel("Input from textbox");\r
-        inputText.addActionListener(this);\r
-\r
-        helpMenu.setLabel("Help");\r
-        documentation.setLabel("Documentation");\r
-        documentation.addActionListener(this);\r
-\r
-        about.setLabel("About...");\r
-        about.addActionListener(this);\r
-          seqLimits.setState(true);\r
-    seqLimits.setLabel("Show Sequence Limits");\r
-    seqLimits.addItemListener(this);\r
-    featureSettings.setLabel("Feature Settings...");\r
-    featureSettings.addActionListener(this);\r
-    sequenceFeatures.setLabel("Sequence Features");\r
-    sequenceFeatures.addItemListener(this);\r
-    sequenceFeatures.setState(false);\r
-    annotationColour.setLabel("by Annotation...");\r
-    annotationColour.addActionListener(this);\r
-\r
-    alignFrameMenuBar.add(fileMenu);\r
-        alignFrameMenuBar.add(editMenu);\r
-        alignFrameMenuBar.add(searchMenu);\r
-        alignFrameMenuBar.add(viewMenu);\r
-        alignFrameMenuBar.add(colourMenu);\r
-        alignFrameMenuBar.add(calculateMenu);\r
-        alignFrameMenuBar.add(helpMenu);\r
-        fileMenu.add(inputText);\r
-        fileMenu.add(outputTextboxMenu);\r
-        fileMenu.addSeparator();\r
-        fileMenu.add(loadTree);\r
-        fileMenu.add(closeMenuItem);\r
-        editMenu.add(undoMenuItem);\r
-        editMenu.add(redoMenuItem);\r
-        editMenu.add(cut);\r
-        editMenu.add(copy);\r
-        editMenu.add(pasteMenu);\r
-        editMenu.add(delete);\r
-        editMenu.addSeparator();\r
-        editMenu.add(selectAllSequenceMenuItem);\r
-        editMenu.add(deselectAllSequenceMenuItem);\r
-        editMenu.add(invertSequenceMenuItem);\r
-        editMenu.add(deleteGroups);\r
-        editMenu.addSeparator();\r
-        editMenu.add(remove2LeftMenuItem);\r
-        editMenu.add(remove2RightMenuItem);\r
-        editMenu.add(removeGappedColumnMenuItem);\r
-        editMenu.add(removeAllGapsMenuItem);\r
-        editMenu.add(removeRedundancyMenuItem);\r
-        searchMenu.add(findMenuItem);\r
-        viewMenu.add(font);\r
-        viewMenu.addSeparator();\r
-    viewMenu.add(seqLimits);\r
-        viewMenu.addSeparator();\r
-    viewMenu.add(wrapMenuItem);\r
-        viewMenu.add(scaleAbove);\r
-        viewMenu.add(scaleLeft);\r
-        viewMenu.add(scaleRight);\r
-        viewMenu.addSeparator();\r
-    viewMenu.add(viewBoxesMenuItem);\r
-        viewMenu.add(viewTextMenuItem);\r
-        viewMenu.add(colourTextMenuItem);\r
-        viewMenu.add(renderGapsMenuItem);\r
-        viewMenu.add(annotationPanelMenuItem);\r
-    viewMenu.addSeparator();\r
-        viewMenu.add(sequenceFeatures);\r
-        viewMenu.add(featureSettings);\r
-    viewMenu.addSeparator();\r
-        viewMenu.add(overviewMenuItem);\r
-        colourMenu.add(applyToAllGroups);\r
-        colourMenu.addSeparator();\r
-        colourMenu.add(noColourmenuItem);\r
-        colourMenu.add(clustalColour);\r
-        colourMenu.add(BLOSUM62Colour);\r
-        colourMenu.add(PIDColour);\r
-        colourMenu.add(zappoColour);\r
-        colourMenu.add(taylorColour);\r
-        colourMenu.add(hydrophobicityColour);\r
-        colourMenu.add(helixColour);\r
-        colourMenu.add(strandColour);\r
-        colourMenu.add(turnColour);\r
-        colourMenu.add(buriedColour);\r
-        colourMenu.add(nucleotideColour);\r
-        colourMenu.add(userDefinedColour);\r
-        colourMenu.addSeparator();\r
-        colourMenu.add(conservationMenuItem);\r
-        colourMenu.add(modifyConservation);\r
-        colourMenu.add(abovePIDThreshold);\r
-        colourMenu.add(modifyPID);\r
-    colourMenu.add(annotationColour);\r
-    calculateMenu.add(sort);\r
-        calculateMenu.add(calculate);\r
-        calculateMenu.addSeparator();\r
-        calculateMenu.add(pairwiseAlignmentMenuItem);\r
-        calculateMenu.add(PCAMenuItem);\r
-        this.add(statusBar, BorderLayout.SOUTH);\r
-        pasteMenu.add(pasteNew);\r
-        pasteMenu.add(pasteThis);\r
-        sort.add(sortIDMenuItem);\r
-        sort.add(sortByTreeMenu);\r
-        sort.add(sortGroupMenuItem);\r
-        sort.add(sortPairwiseMenuItem);\r
-        calculate.add(averageDistanceTreeMenuItem);\r
-        calculate.add(neighbourTreeMenuItem);\r
-        calculate.add(avDistanceTreeBlosumMenuItem);\r
-        calculate.add(njTreeBlosumMenuItem);\r
-        helpMenu.add(documentation);\r
-        helpMenu.add(about);\r
-  }\r
-\r
-  public void setEmbedded()\r
-  {\r
-\r
-    embeddedMenu = new Panel();\r
-    embeddedEdit = new Label();\r
-    embeddedSearch = new Label();\r
-    embeddedView = new Label();\r
-    embeddedColour = new Label();\r
-    embeddedFile = new Label();\r
-    embeddedHelp = new Label();\r
-    embeddedCalculate = new Label();\r
-    flowLayout1 = new FlowLayout();\r
-    embeddedMenu.setBackground(Color.lightGray);\r
-    embeddedMenu.setLayout(flowLayout1);\r
-    embeddedEdit.setText("Edit");\r
-    embeddedEdit.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedSearch.setText("Search");\r
-    embeddedSearch.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedView.setText("View");\r
-    embeddedView.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedColour.setText("Colour");\r
-    embeddedColour.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedFile.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedFile.setText("File");\r
-    embeddedHelp.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedHelp.setText("Help");\r
-    embeddedCalculate.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));\r
-    embeddedCalculate.setText("Calculate");\r
-    embeddedMenu.add(embeddedFile);\r
-    embeddedMenu.add(embeddedEdit);\r
-    embeddedMenu.add(embeddedSearch);\r
-    embeddedMenu.add(embeddedView);\r
-    embeddedMenu.add(embeddedColour);\r
-    embeddedMenu.add(embeddedCalculate);\r
-    embeddedMenu.add(embeddedHelp);\r
-    flowLayout1.setAlignment(FlowLayout.LEFT);\r
-    flowLayout1.setHgap(2);\r
-    flowLayout1.setVgap(0);\r
-    embeddedFile.addMouseListener(this);\r
-    embeddedEdit.addMouseListener(this);\r
-    embeddedSearch.addMouseListener(this);\r
-    embeddedView.addMouseListener(this);\r
-    embeddedColour.addMouseListener(this);\r
-    embeddedCalculate.addMouseListener(this);\r
-    embeddedHelp.addMouseListener(this);\r
-\r
-   // setVisible(false);\r
-    fileMenu.remove(closeMenuItem);\r
-    fileMenu.remove(2); // Seperator\r
-\r
-    applet.setLayout(new BorderLayout());\r
-    applet.add(embeddedMenu, BorderLayout.NORTH);\r
-    applet.add(statusBar, BorderLayout.SOUTH);\r
-   // applet.validate();\r
-\r
-    alignPanel.setSize(applet.size().width, applet.size().height\r
-                       - embeddedMenu.HEIGHT - statusBar.HEIGHT);\r
-\r
-     applet.add(alignPanel, BorderLayout.CENTER);\r
-     applet.validate();\r
-\r
-  }\r
-\r
-\r
-\r
-  PopupMenu filePopup, editPopup, searchPopup,\r
-      viewPopup, colourPopup, calculatePopup, helpPopup;\r
-  MenuItem featureSettings = new MenuItem();\r
-  CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();\r
-  MenuItem annotationColour = new MenuItem();\r
-\r
-  public void mousePressed(MouseEvent evt)\r
-  {\r
-    PopupMenu popup = null;\r
-    Label source = (Label)evt.getSource();\r
-    if(source==embeddedFile)\r
-    {\r
-      popup = filePopup = genPopupMenu(filePopup, fileMenu);\r
-    }\r
-    else if(source==embeddedEdit)\r
-    {\r
-      popup = editPopup = genPopupMenu(editPopup, editMenu);\r
-    }\r
-    else if(source==embeddedSearch)\r
-    {\r
-      popup = searchPopup = genPopupMenu(searchPopup, searchMenu);\r
-    }\r
-    else if(source==embeddedView)\r
-    {\r
-      popup = viewPopup = genPopupMenu(viewPopup, viewMenu);\r
-    }\r
-    else if(source==embeddedColour)\r
-    {\r
-      popup = colourPopup = genPopupMenu(colourPopup, colourMenu);\r
-    }\r
-    else if(source==embeddedCalculate)\r
-    {\r
-      popup = calculatePopup = genPopupMenu(calculatePopup, calculateMenu);\r
-    }\r
-    else if(source==embeddedHelp)\r
-    {\r
-      popup = helpPopup = genPopupMenu(helpPopup, helpMenu);\r
-    }\r
-\r
-    embeddedMenu.add(popup);\r
-    popup.show(embeddedMenu,\r
-               source.getBounds().x,\r
-               source.getBounds().y + source.getBounds().getSize().height);\r
-  }\r
-\r
-  PopupMenu genPopupMenu(PopupMenu popup, Menu original)\r
-  {\r
-    if(popup!=null)\r
-    {\r
-      return popup;\r
-    }\r
-    popup = new PopupMenu();\r
-    int m, mSize = original.getItemCount();\r
-    for(m=0; m<mSize; m++)\r
-    {\r
-      popup.add(original.getItem(m));\r
-      mSize--;\r
-      m--;\r
-    }\r
-\r
-    return popup;\r
-  }\r
-  public void mouseClicked(MouseEvent evt)\r
-  {}\r
-  public void mouseReleased(MouseEvent evt)\r
-  {}\r
-  public void mouseEntered(MouseEvent evt)\r
-  {}\r
-  public void mouseExited(MouseEvent evt)\r
-  {}\r
-\r
-}\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import jalview.schemes.*;
+import jalview.datamodel.*;
+import jalview.analysis.*;
+import jalview.io.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.net.URL;
+
+
+public class AlignFrame extends Frame implements ActionListener,
+    ItemListener, KeyListener, MouseListener
+{
+  public AlignmentPanel alignPanel;
+  public AlignViewport viewport;
+  int NEW_WINDOW_WIDTH = 700;
+  int NEW_WINDOW_HEIGHT = 500;
+
+  String jalviewServletURL;
+
+
+   public AlignFrame(AlignmentI al,
+                     jalview.bin.JalviewLite applet,
+                     String title,
+                     boolean embedded)
+  {
+
+    jalviewServletURL = applet.getParameter("APPLICATION_URL");
+
+    try{
+      jbInit();
+    }catch(Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    viewport = new AlignViewport(al, applet);
+    alignPanel = new AlignmentPanel(this, viewport);
+
+    annotationPanelMenuItem.setState(viewport.showAnnotation);
+
+    seqLimits.setState(viewport.showJVSuffix);
+
+    if(applet!=null)
+    {
+      String param = applet.getParameter("sortBy");
+      if (param != null)
+      {
+        if (param.equalsIgnoreCase("Id"))
+          sortIDMenuItem_actionPerformed();
+        else if (param.equalsIgnoreCase("Pairwise Identity"))
+          sortPairwiseMenuItem_actionPerformed();
+      }
+
+      param = applet.getParameter("wrap");
+      if (param != null)
+      {
+        if (param.equalsIgnoreCase("true"))
+        {
+          wrapMenuItem.setState(true);
+          wrapMenuItem_actionPerformed();
+        }
+      }
+
+      try
+      {
+        param = applet.getParameter("windowWidth");
+        if (param != null)
+        {
+          int width = Integer.parseInt(param);
+          NEW_WINDOW_WIDTH = width;
+        }
+        param = applet.getParameter("windowHeight");
+        if (param != null)
+        {
+          int height = Integer.parseInt(param);
+          NEW_WINDOW_HEIGHT = height;
+        }
+      }
+      catch (Exception ex)
+      {}
+
+    }
+
+   //Some JVMS send keyevents to Top frame or lowest panel,
+   //Havent worked out why yet. So add to both this frame and seqCanvas for now
+   this.addKeyListener(this);
+   alignPanel.seqPanel.seqCanvas.addKeyListener(this);
+   alignPanel.idPanel.idCanvas.addKeyListener(this);
+   alignPanel.scalePanel.addKeyListener(this);
+   alignPanel.annotationPanel.addKeyListener(this);
+
+    viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()
+    {
+     public void propertyChange(java.beans.PropertyChangeEvent evt)
+     {
+       if (evt.getPropertyName().equals("alignment"))
+       {
+         alignmentChanged();
+       }
+     }
+   });
+
+
+   if(embedded)
+   {
+     setEmbedded();
+   }
+   else
+   {
+     add(alignPanel, BorderLayout.CENTER);
+     jalview.bin.JalviewLite.addFrame(this, title, NEW_WINDOW_WIDTH,
+                                      NEW_WINDOW_HEIGHT);
+   }
+   alignPanel.validate();
+   alignPanel.repaint();
+  }
+  public AlignViewport getAlignViewport()
+  {
+    return viewport;
+  }
+
+  public SeqCanvas getSeqcanvas()
+  {
+    return alignPanel.seqPanel.seqCanvas;
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param String DOCUMENT ME!
+   */
+
+  public void parseFeaturesFile(String file, String type)
+  {
+    Hashtable featureLinks = new Hashtable();
+    boolean featuresFile = false;
+    try{
+      featuresFile = new jalview.io.FeaturesFile(file, type).parse(viewport.alignment,
+                                         alignPanel.seqPanel.seqCanvas.
+                                         getFeatureRenderer().featureColours,
+                                         featureLinks,
+                                         true);
+    }
+    catch(Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    if(featuresFile)
+    {
+      if(featureLinks.size()>0)
+        alignPanel.seqPanel.seqCanvas
+            .getFeatureRenderer().featureLinks = featureLinks;
+      viewport.showSequenceFeatures = true;
+      sequenceFeatures.setState(true);
+      alignPanel.repaint();
+    }
+
+  }
+
+
+  public void keyPressed(KeyEvent evt)
+  {
+    if (viewport.cursorMode
+        && evt.getKeyCode() >= KeyEvent.VK_0
+        && evt.getKeyCode() <= KeyEvent.VK_9)
+    {
+      alignPanel.seqPanel.numberPressed(evt.getKeyChar());
+    }
+
+    switch (evt.getKeyCode())
+    {
+      case 27: // escape key
+        deselectAllSequenceMenuItem_actionPerformed();
+        break;
+      case KeyEvent.VK_X:
+        if (evt.isControlDown() || evt.isMetaDown())
+        {
+          cut_actionPerformed();
+        }
+        break;
+      case KeyEvent.VK_C:
+        if (viewport.cursorMode && !evt.isControlDown())
+        {
+          alignPanel.seqPanel.setCursorColumn();
+        }
+        if (evt.isControlDown() || evt.isMetaDown())
+        {
+          copy_actionPerformed();
+        }
+        break;
+      case KeyEvent.VK_V:
+        if (evt.isControlDown() || evt.isMetaDown())
+        {
+          paste(true);
+        }
+        break;
+      case KeyEvent.VK_A:
+        if (evt.isControlDown() || evt.isMetaDown())
+        {
+          selectAllSequenceMenuItem_actionPerformed();
+        }
+        break;
+      case KeyEvent.VK_DOWN:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.moveCursor(0,1);
+        }
+        else
+          moveSelectedSequences(false);
+        break;
+
+      case KeyEvent.VK_UP:
+        if (viewport.cursorMode)
+        {
+          alignPanel.seqPanel.moveCursor(0,-1);
+        }
+        else
+          moveSelectedSequences(true);
+        break;
+
+      case KeyEvent.VK_LEFT:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.moveCursor(-1,0);
+        }
+        break;
+
+      case KeyEvent.VK_RIGHT:
+        if (viewport.cursorMode)
+        {
+          alignPanel.seqPanel.moveCursor(1,0);
+        }
+        break;
+      case KeyEvent.VK_SPACE:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.insertGapAtCursor(evt.isControlDown());
+        }
+        break;
+
+      case KeyEvent.VK_DELETE:
+      case KeyEvent.VK_BACK_SPACE:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.deleteGapAtCursor(evt.isControlDown());
+        }
+       else
+        {
+          cut_actionPerformed();
+          alignPanel.seqPanel.seqCanvas.repaint();
+        }
+        break;
+
+      case KeyEvent.VK_S:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.setCursorRow();
+        }
+        break;
+      case KeyEvent.VK_P:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.setCursorPosition();
+        }
+        break;
+
+      case KeyEvent.VK_ENTER:
+      case KeyEvent.VK_COMMA:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.setCursorRowAndColumn();
+        }
+        break;
+
+      case KeyEvent.VK_Q:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.setSelectionAreaAtCursor(true);
+        }
+        break;
+      case KeyEvent.VK_M:
+        if(viewport.cursorMode)
+        {
+          alignPanel.seqPanel.setSelectionAreaAtCursor(false);
+        }
+        break;
+
+     case KeyEvent.VK_F2:
+       viewport.cursorMode = ! viewport.cursorMode;
+       statusBar.setText("Keyboard editing mode is "+
+           (viewport.cursorMode ? "on" : "off"));
+       if(viewport.cursorMode)
+       {
+         alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes;
+         alignPanel.seqPanel.seqCanvas.cursorY = viewport.startSeq;
+       }
+       alignPanel.seqPanel.seqCanvas.repaint();
+       break;
+
+      case KeyEvent.VK_F:
+        if (evt.isControlDown())
+        {
+          findMenuItem_actionPerformed();
+        }
+        break;
+      case KeyEvent.VK_H:
+      {
+        boolean toggleSeqs = !evt.isControlDown();
+        boolean toggleCols = !evt.isShiftDown();
+        boolean hide = false;
+        SequenceGroup sg = viewport.getSelectionGroup();
+
+        if(toggleSeqs)
+        {
+          if (sg != null && sg.getSize(false) != viewport.alignment.getHeight())
+          {
+            hide = true;
+            viewport.hideAllSelectedSeqs();
+          }
+          else if (!(toggleCols && viewport.colSel.getSelected().size() > 0))
+            viewport.showAllHiddenSeqs();
+        }
+
+        if(toggleCols)
+        {
+          if (viewport.colSel.getSelected().size() > 0)
+          {
+            viewport.hideSelectedColumns();
+            if(!toggleSeqs)
+                   viewport.selectionGroup = sg;
+          }
+          else if (!hide)
+            viewport.showAllHiddenColumns();
+        }
+
+        alignPanel.repaint();
+        break;
+      }
+
+    }
+  }
+  public void keyReleased(KeyEvent evt)
+  {}
+  public void keyTyped(KeyEvent evt)
+  {}
+
+public void itemStateChanged(ItemEvent evt)
+  {
+    if(evt.getSource()==colourTextMenuItem)
+            colourTextMenuItem_actionPerformed();
+    else if(evt.getSource()==wrapMenuItem)
+            wrapMenuItem_actionPerformed();
+    else if(evt.getSource()==scaleAbove)
+            scaleAbove_actionPerformed();
+    else if(evt.getSource()==scaleLeft)
+            scaleLeft_actionPerformed();
+    else if(evt.getSource()==scaleRight)
+            scaleRight_actionPerformed();
+     else if(evt.getSource()==seqLimits)
+      seqLimits_itemStateChanged();
+    else if(evt.getSource()==viewBoxesMenuItem)
+            viewBoxesMenuItem_actionPerformed();
+    else if(evt.getSource()==viewTextMenuItem)
+            viewTextMenuItem_actionPerformed();
+    else if(evt.getSource()==renderGapsMenuItem)
+            renderGapsMenuItem_actionPerformed();
+    else if(evt.getSource()==annotationPanelMenuItem)
+            annotationPanelMenuItem_actionPerformed();
+      else if(evt.getSource()==sequenceFeatures)
+      {
+           viewport.showSequenceFeatures(sequenceFeatures.getState());
+            alignPanel.seqPanel.seqCanvas.repaint();
+      }
+      else if(evt.getSource()==conservationMenuItem)
+            conservationMenuItem_actionPerformed();
+      else if(evt.getSource()==abovePIDThreshold)
+            abovePIDThreshold_actionPerformed();
+          else if(evt.getSource()==applyToAllGroups)
+            applyToAllGroups_actionPerformed();
+      else if(evt.getSource()==autoCalculate)
+          viewport.autocalculateConsensus = autoCalculate.getState();
+  }
+ public void actionPerformed(ActionEvent evt)
+ {
+    Object source = evt.getSource();
+
+    if(source==inputText)
+      inputText_actionPerformed();
+    else if(source==loadTree)
+      loadTree_actionPerformed();
+    else if(source==loadApplication)
+      launchFullApplication();
+    else if(source==closeMenuItem)
+      closeMenuItem_actionPerformed();
+    else if(source==copy)
+      copy_actionPerformed();
+    else if(source==undoMenuItem)
+      undoMenuItem_actionPerformed();
+    else if(source==redoMenuItem)
+      redoMenuItem_actionPerformed();
+    else if(source==inputText)
+            inputText_actionPerformed();
+    else if(source==closeMenuItem)
+            closeMenuItem_actionPerformed();
+    else if(source==undoMenuItem)
+            undoMenuItem_actionPerformed();
+    else if(source==redoMenuItem)
+            redoMenuItem_actionPerformed();
+    else if(source==copy)
+            copy_actionPerformed();
+    else if(source==pasteNew)
+            pasteNew_actionPerformed();
+    else if(source==pasteThis)
+            pasteThis_actionPerformed();
+    else if(source==cut)
+            cut_actionPerformed();
+    else if(source==delete)
+            delete_actionPerformed();
+    else if(source==deleteGroups)
+            deleteGroups_actionPerformed();
+    else if(source==selectAllSequenceMenuItem)
+            selectAllSequenceMenuItem_actionPerformed();
+    else if(source==deselectAllSequenceMenuItem)
+            deselectAllSequenceMenuItem_actionPerformed();
+    else if(source==invertSequenceMenuItem)
+            invertSequenceMenuItem_actionPerformed();
+    else if(source==invertColSel)
+    { viewport.invertColumnSelection(); alignPanel.repaint(); }
+    else if(source==remove2LeftMenuItem)
+            remove2LeftMenuItem_actionPerformed();
+    else if(source==remove2RightMenuItem)
+            remove2RightMenuItem_actionPerformed();
+    else if(source==removeGappedColumnMenuItem)
+            removeGappedColumnMenuItem_actionPerformed();
+    else if(source==removeAllGapsMenuItem)
+            removeAllGapsMenuItem_actionPerformed();
+    else if(source==findMenuItem)
+            findMenuItem_actionPerformed();
+    else if(source==font)
+            font_actionPerformed();
+    else if(source==showColumns)
+    {
+      viewport.showAllHiddenColumns(); alignPanel.repaint();
+    }
+    else if(source==showSeqs)
+    {
+      viewport.showAllHiddenSeqs();
+    }
+    else if(source == hideColumns)
+    {
+      viewport.hideSelectedColumns(); alignPanel.repaint();
+    }
+    else if(source == hideSequences && viewport.getSelectionGroup()!=null)
+    {
+      viewport.hideAllSelectedSeqs();
+    }
+    else if(source==featureSettings)
+            featureSettings_actionPerformed();
+    else if(source==overviewMenuItem)
+            overviewMenuItem_actionPerformed();
+    else if(source==noColourmenuItem)
+            noColourmenuItem_actionPerformed();
+    else if(source==clustalColour)
+            clustalColour_actionPerformed();
+    else if(source==zappoColour)
+            zappoColour_actionPerformed();
+    else if(source==taylorColour)
+            taylorColour_actionPerformed();
+    else if(source==hydrophobicityColour)
+            hydrophobicityColour_actionPerformed();
+    else if(source==helixColour)
+            helixColour_actionPerformed();
+    else if(source==strandColour)
+            strandColour_actionPerformed();
+    else if(source==turnColour)
+            turnColour_actionPerformed();
+    else if(source==buriedColour)
+            buriedColour_actionPerformed();
+    else if(source==nucleotideColour)
+            nucleotideColour_actionPerformed();
+    else if(source==modifyPID)
+            modifyPID_actionPerformed();
+    else if(source==modifyConservation)
+            modifyConservation_actionPerformed();
+    else if(source==userDefinedColour)
+            userDefinedColour_actionPerformed();
+    else if(source==PIDColour)
+            PIDColour_actionPerformed();
+    else if(source==BLOSUM62Colour)
+            BLOSUM62Colour_actionPerformed();
+    else if(source==annotationColour)
+           new AnnotationColourChooser(viewport, alignPanel);
+    else if(source==sortPairwiseMenuItem)
+            sortPairwiseMenuItem_actionPerformed();
+    else if(source==sortIDMenuItem)
+            sortIDMenuItem_actionPerformed();
+    else if(source==sortGroupMenuItem)
+            sortGroupMenuItem_actionPerformed();
+    else if(source==removeRedundancyMenuItem)
+            removeRedundancyMenuItem_actionPerformed();
+    else if(source==pairwiseAlignmentMenuItem)
+            pairwiseAlignmentMenuItem_actionPerformed();
+    else if(source==PCAMenuItem)
+            PCAMenuItem_actionPerformed();
+    else if(source==averageDistanceTreeMenuItem)
+            averageDistanceTreeMenuItem_actionPerformed();
+    else if(source==neighbourTreeMenuItem)
+            neighbourTreeMenuItem_actionPerformed();
+    else if(source==njTreeBlosumMenuItem)
+            njTreeBlosumMenuItem_actionPerformed();
+    else if(source==avDistanceTreeBlosumMenuItem)
+            avTreeBlosumMenuItem_actionPerformed();
+    else if(source==documentation)
+            documentation_actionPerformed();
+    else if(source==about)
+            about_actionPerformed();
+
+ }
+
+  public void inputText_actionPerformed()
+  {
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
+    Frame frame = new Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame, "Cut & Paste Input", 500, 500);
+  }
+
+  protected void outputText_actionPerformed(ActionEvent e)
+  {
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
+    Frame frame = new Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame,
+                                     "Alignment output - " + e.getActionCommand(),
+                                     600, 500);
+    cap.setText(new AppletFormatAdapter().formatSequences(e.getActionCommand(),
+                                              viewport.getAlignment().getSequences(),
+                                                      viewport.showJVSuffix));
+  }
+
+  void launchFullApplication()
+  {
+    StringBuffer url = new StringBuffer(jalviewServletURL);
+
+    url.append("?open="+
+               appendProtocol( viewport.applet.getParameter("file") ) );
+
+    if(viewport.applet.getParameter("features")!=null)
+    {
+      url.append( "&features=" );
+      url.append( appendProtocol( viewport.applet.getParameter("features") ) );
+    }
+
+    if(viewport.applet.getParameter("annotations")!=null)
+    {
+      url.append( "&annotations=" );
+      url.append( appendProtocol( viewport.applet.getParameter("annotations") ) );
+    }
+
+    if(viewport.applet.getParameter("jnetfile")!=null)
+    {
+      url.append( "&annotations=" );
+      url.append( appendProtocol( viewport.applet.getParameter("jnetfile") ) );
+    }
+
+    if(viewport.applet.getParameter("defaultColour")!=null)
+    {
+      url.append("&colour=" +
+                 removeWhiteSpace(viewport.applet.getParameter("defaultColour"))
+          );
+    }
+
+    if(viewport.applet.getParameter("userDefinedColour")!=null)
+    {
+      url.append( "&colour=" +
+                 removeWhiteSpace( viewport.applet.getParameter("userDefinedColour") )
+         );
+    }
+
+    showURL(url.toString(), "FULL_APP");
+  }
+
+
+  String removeWhiteSpace(String colour)
+  {
+    StringBuffer sb = new StringBuffer();
+    for (int i = 0; i < colour.length(); i++)
+    {
+      if (Character.isWhitespace(colour.charAt(i)))
+        sb.append("%20");
+      else
+        sb.append(colour.charAt(i));
+    }
+
+    return sb.toString();
+  }
+
+
+  String appendProtocol(String url)
+  {
+    try{
+       new URL(url);
+    }catch(java.net.MalformedURLException ex)
+    {
+      url = viewport.applet.getCodeBase()+url;
+    }
+    return url;
+  }
+
+  public void closeMenuItem_actionPerformed()
+  {
+    PaintRefresher.components.remove(viewport.alignment);
+    if(PaintRefresher.components.size()==0 && viewport.applet==null)
+      System.exit(0);
+
+    this.dispose();
+  }
+
+  Stack historyList = new Stack();
+  Stack redoList = new Stack();
+
+  void updateEditMenuBar()
+  {
+    if (historyList.size() > 0)
+    {
+      undoMenuItem.setEnabled(true);
+      HistoryItem hi = (HistoryItem) historyList.peek();
+      undoMenuItem.setLabel("Undo " + hi.getDescription());
+    }
+    else
+    {
+      undoMenuItem.setEnabled(false);
+      undoMenuItem.setLabel("Undo");
+    }
+
+    if (redoList.size() > 0)
+    {
+      redoMenuItem.setEnabled(true);
+      HistoryItem hi = (HistoryItem) redoList.peek();
+      redoMenuItem.setLabel("Redo " + hi.getDescription());
+    }
+    else
+    {
+      redoMenuItem.setEnabled(false);
+      redoMenuItem.setLabel("Redo");
+    }
+  }
+
+  public void addHistoryItem(HistoryItem hi)
+  {
+    historyList.push(hi);
+    redoList.removeAllElements();
+    updateEditMenuBar();
+  }
+
+  protected void undoMenuItem_actionPerformed()
+  {
+    HistoryItem nh,hi = (HistoryItem) historyList.pop();
+    redoList.push(nh=new HistoryItem(hi.getDescription(), viewport.alignment,
+                                  HistoryItem.HIDE));
+    if (hi.alColumnChanges!=null)
+      nh.alColumnChanges=hi.alColumnChanges.getInverse();
+    restoreHistoryItem(hi);
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  protected void redoMenuItem_actionPerformed()
+  {
+    HistoryItem nh,hi = (HistoryItem) redoList.pop();
+    historyList.push(nh=new HistoryItem(hi.getDescription(), viewport.alignment,
+                                  HistoryItem.HIDE));
+    if (hi.alColumnChanges!=null)
+      nh.alColumnChanges=hi.alColumnChanges.getInverse();
+    restoreHistoryItem(hi);
+    updateEditMenuBar();
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  // used by undo and redo
+  void restoreHistoryItem(HistoryItem hi)
+  {
+    hi.restore(viewport.getColumnSelection());
+    updateEditMenuBar();
+
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  public void moveSelectedSequences(boolean up)
+  {
+    SequenceGroup sg = viewport.getSelectionGroup();
+    if (sg == null)
+    {
+      return;
+    }
+
+    if (up)
+    {
+      for (int i = 1; i < viewport.alignment.getHeight(); i++)
+      {
+        SequenceI seq = viewport.alignment.getSequenceAt(i);
+        if (!sg.getSequences(false).contains(seq))
+        {
+          continue;
+        }
+
+        SequenceI temp = viewport.alignment.getSequenceAt(i - 1);
+        if (sg.getSequences(false).contains(temp))
+        {
+          continue;
+        }
+
+        viewport.alignment.getSequences().setElementAt(temp, i);
+        viewport.alignment.getSequences().setElementAt(seq, i - 1);
+      }
+    }
+    else
+    {
+      for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)
+      {
+        SequenceI seq = viewport.alignment.getSequenceAt(i);
+        if (!sg.getSequences(true).contains(seq))
+        {
+          continue;
+        }
+
+        SequenceI temp = viewport.alignment.getSequenceAt(i + 1);
+        if (sg.getSequences(true).contains(temp))
+        {
+          continue;
+        }
+
+        viewport.alignment.getSequences().setElementAt(temp, i);
+        viewport.alignment.getSequences().setElementAt(seq, i + 1);
+      }
+    }
+
+    alignPanel.repaint();
+  }
+
+  static StringBuffer copiedSequences;
+  static Vector copiedHiddenColumns;
+  protected void copy_actionPerformed()
+  {
+    if (viewport.getSelectionGroup() == null)
+    {
+      return;
+    }
+
+    SequenceGroup sg = viewport.getSelectionGroup();
+    copiedSequences = new StringBuffer();
+    Hashtable orderedSeqs = new Hashtable();
+    for (int i = 0; i < sg.getSize(false); i++)
+    {
+      SequenceI seq = sg.getSequenceAt(i);
+      int index = viewport.alignment.findIndex(seq);
+      orderedSeqs.put(index + "", seq);
+    }
+
+    int index = 0, startRes, endRes;
+    char ch;
+
+    if (viewport.hasHiddenColumns && viewport.getSelectionGroup() != null)
+    {
+      copiedHiddenColumns = new Vector();
+      int hiddenOffset = viewport.getSelectionGroup().getStartRes();
+      for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns().size();
+           i++)
+      {
+        int[] region = (int[])
+            viewport.getColumnSelection().getHiddenColumns().elementAt(i);
+
+        copiedHiddenColumns.addElement(new int[]
+                                 {region[0] - hiddenOffset,
+                                 region[1] - hiddenOffset});
+      }
+    }
+    else
+      copiedHiddenColumns = null;
+
+
+    for (int i = 0; i < sg.getSize(false); i++)
+    {
+        SequenceI seq = null;
+
+        while (seq == null)
+        {
+            if (orderedSeqs.containsKey(index + ""))
+            {
+                seq = (SequenceI) orderedSeqs.get(index + "");
+                index++;
+
+                break;
+            }
+            else
+            {
+                index++;
+            }
+        }
+
+        //FIND START RES
+        //Returns residue following index if gap
+        startRes = seq.findPosition(sg.getStartRes());
+
+        //FIND END RES
+        //Need to find the residue preceeding index if gap
+        endRes = 0;
+
+        for (int j = 0; j < sg.getEndRes()+1 && j < seq.getLength(); j++)
+        {
+          ch = seq.getCharAt(j);
+          if (!jalview.util.Comparison.isGap( (ch)))
+          {
+            endRes++;
+          }
+        }
+
+        if(endRes>0)
+        {
+          endRes += seq.getStart() -1;
+        }
+
+        copiedSequences.append(seq.getName() + "\t" +
+            startRes + "\t" +
+            endRes + "\t" +
+            seq.getSequence(sg.getStartRes(),
+                sg.getEndRes() + 1) + "\n");
+    }
+
+  }
+
+  protected void pasteNew_actionPerformed()
+  {
+    paste(true);
+  }
+
+  protected void pasteThis_actionPerformed()
+  {
+    addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,
+                                   HistoryItem.PASTE));
+    paste(false);
+  }
+
+  void paste(boolean newAlignment)
+  {
+    try
+    {
+      if (copiedSequences == null)
+      {
+        return;
+      }
+
+      StringTokenizer st = new StringTokenizer(copiedSequences.toString());
+      Vector seqs = new Vector();
+      while (st.hasMoreElements())
+      {
+        String name = st.nextToken();
+        int start = Integer.parseInt(st.nextToken());
+        int end = Integer.parseInt(st.nextToken());
+        Sequence sequence = new Sequence(name, st.nextToken(), start, end);
+
+        if (!newAlignment)
+        {
+          viewport.alignment.addSequence(sequence);
+        }
+        else
+        {
+          seqs.addElement(sequence);
+        }
+      }
+
+      if (newAlignment)
+      {
+        SequenceI[] newSeqs = new SequenceI[seqs.size()];
+        for (int i = 0; i < seqs.size(); i++)
+        {
+          newSeqs[i] = (SequenceI) seqs.elementAt(i);
+        }
+
+        String newtitle = new String("Copied sequences");
+        if (getTitle().startsWith("Copied sequences"))
+        {
+          newtitle = getTitle();
+        }
+        else
+        {
+          newtitle = newtitle.concat("- from " + getTitle());
+        }
+        AlignFrame af = new AlignFrame(new Alignment(newSeqs),
+                                       viewport.applet,
+                                       newtitle,
+                                       false);
+        if (copiedHiddenColumns != null)
+        {
+          for (int i = 0; i < copiedHiddenColumns.size(); i++)
+          {
+            int[] region = (int[]) copiedHiddenColumns.elementAt(i);
+            af.viewport.hideColumns(region[0], region[1]);
+          }
+        }
+
+
+        jalview.bin.JalviewLite.addFrame(af, newtitle, NEW_WINDOW_WIDTH,
+                                         NEW_WINDOW_HEIGHT);
+      }
+      else
+      {
+        viewport.setEndSeq(viewport.alignment.getHeight());
+        viewport.alignment.getWidth();
+        viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+      }
+
+    }
+    catch (Exception ex)
+    {} // could be anything being pasted in here
+
+  }
+
+  protected void cut_actionPerformed()
+  {
+    copy_actionPerformed();
+    delete_actionPerformed();
+  }
+
+  protected void delete_actionPerformed()
+  {
+    addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,
+                                   HistoryItem.HIDE));
+    if (viewport.getSelectionGroup() == null)
+    {
+      return;
+    }
+
+
+    SequenceGroup sg = viewport.getSelectionGroup();
+    boolean allSequences = false;
+    if(sg.getSize(false)==viewport.alignment.getHeight())
+          allSequences = true;
+
+    for (int i = 0; i < sg.getSize(false); i++)
+    {
+      SequenceI seq = sg.getSequenceAt(i);
+      int index = viewport.getAlignment().findIndex(seq);
+      seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);
+
+      // If the cut affects all sequences, remove highlighted columns
+      if (allSequences)
+      {
+        viewport.getColumnSelection().removeElements(sg.getStartRes(),
+                                                     sg.getEndRes() + 1);
+      }
+
+
+      if (seq.getSequence().length() < 1)
+      {
+        viewport.getAlignment().deleteSequence(seq);
+      }
+      else
+      {
+        viewport.getAlignment().getSequences().setElementAt(seq, index);
+      }
+    }
+
+    viewport.setSelectionGroup(null);
+    viewport.alignment.deleteGroup(sg);
+    viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getSize().height);
+    if (viewport.getAlignment().getHeight() < 1)
+    {
+      try
+      {
+        this.setVisible(false);
+      }
+      catch (Exception ex)
+      {}
+    }
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+
+  }
+
+  protected void deleteGroups_actionPerformed()
+  {
+    viewport.alignment.deleteAllGroups();
+    viewport.setSelectionGroup(null);
+
+    alignPanel.repaint();
+  }
+
+  public void selectAllSequenceMenuItem_actionPerformed()
+  {
+    SequenceGroup sg = new SequenceGroup();
+    for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
+    {
+      sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
+    }
+    sg.setEndRes(viewport.alignment.getWidth()-1);
+    viewport.setSelectionGroup(sg);
+    alignPanel.repaint();
+    PaintRefresher.Refresh(null, viewport.alignment);
+  }
+
+  public void deselectAllSequenceMenuItem_actionPerformed()
+  {
+    if(viewport.cursorMode)
+    {
+      alignPanel.seqPanel.keyboardNo1=null;
+      alignPanel.seqPanel.keyboardNo2=null;
+    }
+    viewport.setSelectionGroup(null);
+    viewport.getColumnSelection().clear();
+    viewport.setSelectionGroup(null);
+    alignPanel.idPanel.idCanvas.searchResults = null;
+    alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
+    alignPanel.repaint();
+    PaintRefresher.Refresh(null, viewport.alignment);
+  }
+
+  public void invertSequenceMenuItem_actionPerformed()
+  {
+    SequenceGroup sg = viewport.getSelectionGroup();
+    for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
+    {
+      sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
+    }
+
+    PaintRefresher.Refresh(null, viewport.alignment);
+  }
+
+  public void remove2LeftMenuItem_actionPerformed()
+  {
+    ColumnSelection colSel = viewport.getColumnSelection();
+    if (colSel.size() > 0)
+    {
+      HistoryItem edit;
+      addHistoryItem(edit=new HistoryItem("Remove Left", viewport.alignment,
+                                     HistoryItem.HIDE));
+      int min = colSel.getMin();
+      viewport.getAlignment().trimLeft(min);
+      colSel.compensateForEdit(0, min);
+      edit.addShift(0, min);
+      if (viewport.getSelectionGroup() != null)
+      {
+        viewport.getSelectionGroup().adjustForRemoveLeft(min);
+      }
+
+      Vector groups = viewport.alignment.getGroups();
+      for (int i = 0; i < groups.size(); i++)
+      {
+        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+        if (!sg.adjustForRemoveLeft(min))
+        {
+          viewport.alignment.deleteGroup(sg);
+        }
+      }
+      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+    }
+  }
+
+  public void remove2RightMenuItem_actionPerformed()
+  {
+    ColumnSelection colSel = viewport.getColumnSelection();
+    if (colSel.size() > 0)
+    {
+      addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,
+                                     HistoryItem.HIDE));
+      int max = colSel.getMax();
+      viewport.getAlignment().trimRight(max);
+
+      if (viewport.getSelectionGroup() != null)
+      {
+        viewport.getSelectionGroup().adjustForRemoveRight(max);
+      }
+
+      Vector groups = viewport.alignment.getGroups();
+      for (int i = 0; i < groups.size(); i++)
+      {
+        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+        if (!sg.adjustForRemoveRight(max))
+        {
+          viewport.alignment.deleteGroup(sg);
+        }
+      }
+      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+    }
+
+  }
+
+  public void removeGappedColumnMenuItem_actionPerformed()
+  {
+    HistoryItem edit;
+    addHistoryItem(edit=new HistoryItem("Remove Gapped Columns",
+                                   viewport.alignment,
+                                   HistoryItem.HIDE));
+
+    //This is to maintain viewport position on first residue
+    //of first sequence
+    SequenceI seq = viewport.alignment.getSequenceAt(0);
+    int startRes = seq.findPosition(viewport.startRes);
+
+    viewport.getAlignment().removeGaps();
+
+    viewport.setStartRes(seq.findIndex(startRes)-1);
+
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  public void removeAllGapsMenuItem_actionPerformed()
+  {
+    // TODO: hidden regions should not be touched by removeAllGaps - a minimal number of gaps will remain in alignment segments containing uneven length subsequences
+    // TODO: columnSelection.compensateforedits should be called (and passed to history item)
+    HistoryItem editgaps;
+    addHistoryItem(editgaps=new HistoryItem("Remove Gaps", viewport.alignment,
+                                   HistoryItem.HIDE));
+
+    //This is to maintain viewport position on first residue
+    //of first sequence
+    SequenceI seq = viewport.alignment.getSequenceAt(0);
+    int startRes = seq.findPosition(viewport.startRes);
+
+    SequenceI current;
+    Vector seqs=null;
+
+    int start=0, end = viewport.alignment.getWidth();
+
+    if (viewport.getSelectionGroup() != null
+        && viewport.getSelectionGroup().getSequences(false) != null
+        && viewport.getSelectionGroup().getSize(false)>0)
+    {
+      seqs = viewport.getSelectionGroup().getSequences(true);
+      start = viewport.getSelectionGroup().getStartRes();
+      end = viewport.getSelectionGroup().getEndRes()+1;
+    }
+    else
+      seqs = viewport.alignment.getSequences();
+
+    /* Commented out regions below are partial implementation of todo above.
+     * divide start,end into visible chunks, and for each:
+     int diff=end-start+1;
+     int diffmax=0;
+     int dr[] = new int[seqs.size()];
+     */
+    for (int i = 0; i < seqs.size(); i++)
+    {
+      current = (SequenceI) seqs.elementAt(i);
+      //dr[i]=
+      current.removeGaps(start, end);
+      /*if (d<diff) // can only shift
+        diff=d;
+      if (diffmax<d)
+        diffmax=d;
+        */
+    }
+    /* // after the end of each chunk -
+     * if (diff>0) {
+     // record shift for history.
+      editgaps.addShift(start, diff);
+      if (viewport.hasHiddenColumns && diffmax>diff) {
+      // pad sequence
+       StringBuffer gaps=new StringBuffer(diffmax);
+       for (int i=0,j=diffmax-diff; i<j; i++)
+       gaps.append(viewport.getGapCharacter());
+       for (int i=0, j=seqs.size(); i<j; i++) {
+       current = (SequenceI) seqs.elementAt(i);
+       if (dr[i]-diff>0) {
+       String sq = current.getSequence();
+       current.setSequence(sq.substring(0, hcend-dr[i])+gaps.substring(0, dr[i]-diff)+sq.substring());
+       }
+       }
+      }
+      }*/
+
+    viewport.setStartRes(seq.findIndex(startRes)-1);
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  public void alignmentChanged()
+  {
+    viewport.alignment.padGaps();
+    if(viewport.autocalculateConsensus)
+    {
+      viewport.updateConsensus();
+      viewport.updateConservation();
+    }
+
+    resetAllColourSchemes();
+    if(alignPanel.overviewPanel!=null)
+      alignPanel.overviewPanel.updateOverviewImage();
+
+    viewport.alignment.adjustSequenceAnnotations();
+    alignPanel.repaint();
+  }
+
+  void resetAllColourSchemes()
+  {
+    ColourSchemeI cs = viewport.globalColourScheme;
+    if(cs!=null)
+    {
+      if (cs instanceof ClustalxColourScheme)
+      {
+        ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).
+            resetClustalX(viewport.alignment.getSequences(),
+                          viewport.alignment.getWidth());
+      }
+
+      cs.setConsensus(viewport.vconsensus);
+      if (cs.conservationApplied())
+      {
+        Alignment al = (Alignment) viewport.alignment;
+        Conservation c = new Conservation("All",
+                                          ResidueProperties.propHash, 3,
+                                          al.getSequences(), 0,
+                                          al.getWidth() - 1);
+        c.calculate();
+        c.verdict(false, viewport.ConsPercGaps);
+
+        cs.setConservation(c);
+      }
+    }
+
+    int s, sSize = viewport.alignment.getGroups().size();
+    for(s=0; s<sSize; s++)
+    {
+      SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);
+      if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)
+      {
+        ((ClustalxColourScheme)sg.cs).resetClustalX(
+            sg.getSequences(true), sg.getWidth());
+      }
+      sg.recalcConservation();
+    }
+  }
+
+
+
+  public void findMenuItem_actionPerformed()
+  {
+    new Finder(alignPanel);
+  }
+
+  public void font_actionPerformed()
+  {
+    new FontChooser(alignPanel);
+  }
+
+
+  public void seqLimits_itemStateChanged()
+  {
+    viewport.setShowJVSuffix(seqLimits.getState());
+    alignPanel.fontChanged();
+    alignPanel.repaint();
+  }
+
+
+  protected void colourTextMenuItem_actionPerformed()
+  {
+    viewport.setColourText(colourTextMenuItem.getState());
+    alignPanel.repaint();
+  }
+
+  protected void wrapMenuItem_actionPerformed()
+  {
+    viewport.setWrapAlignment(wrapMenuItem.getState());
+    alignPanel.setWrapAlignment(wrapMenuItem.getState());
+    scaleAbove.setEnabled(wrapMenuItem.getState());
+    scaleLeft.setEnabled(wrapMenuItem.getState());
+    scaleRight.setEnabled(wrapMenuItem.getState());
+    alignPanel.repaint();
+  }
+
+
+  protected void scaleAbove_actionPerformed()
+  {
+    viewport.setScaleAboveWrapped(scaleAbove.getState());
+    alignPanel.repaint();
+  }
+
+  protected void scaleLeft_actionPerformed()
+  {
+    viewport.setScaleLeftWrapped(scaleLeft.getState());
+    alignPanel.repaint();
+  }
+
+  protected void scaleRight_actionPerformed()
+  {
+    viewport.setScaleRightWrapped(scaleRight.getState());
+    alignPanel.repaint();
+  }
+
+  public void viewBoxesMenuItem_actionPerformed()
+  {
+    viewport.setShowBoxes(viewBoxesMenuItem.getState());
+    alignPanel.repaint();
+  }
+
+  public void viewTextMenuItem_actionPerformed()
+  {
+    viewport.setShowText(viewTextMenuItem.getState());
+    alignPanel.repaint();
+  }
+
+  protected void renderGapsMenuItem_actionPerformed()
+  {
+    viewport.setRenderGaps(renderGapsMenuItem.getState());
+    alignPanel.repaint();
+  }
+
+  public void annotationPanelMenuItem_actionPerformed()
+  {
+    viewport.setShowAnnotation(annotationPanelMenuItem.getState());
+    alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());
+  }
+
+  public void featureSettings_actionPerformed()
+  {
+    new FeatureSettings(viewport, alignPanel);
+  }
+
+  public void overviewMenuItem_actionPerformed()
+  {
+    if (alignPanel.overviewPanel != null)
+    {
+      return;
+    }
+
+    Frame frame = new Frame();
+    OverviewPanel overview = new OverviewPanel(alignPanel);
+    frame.add(overview);
+    // +50 must allow for applet frame window
+    jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),
+                                     overview.preferredSize().width,
+                                     overview.preferredSize().height + 50);
+
+    frame.pack();
+    frame.addWindowListener(new WindowAdapter()
+    {
+      public void windowClosing(WindowEvent e)
+      {
+        alignPanel.setOverviewPanel(null);
+      };
+    });
+
+    alignPanel.setOverviewPanel(overview);
+
+  }
+
+  protected void noColourmenuItem_actionPerformed()
+  {
+    changeColour(null);
+  }
+
+  public void clustalColour_actionPerformed()
+  {
+    abovePIDThreshold.setState(false);
+    changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(),
+                                          viewport.alignment.getWidth()));
+  }
+
+  public void zappoColour_actionPerformed()
+  {
+    changeColour(new ZappoColourScheme());
+  }
+
+  public void taylorColour_actionPerformed()
+  {
+    changeColour(new TaylorColourScheme());
+  }
+
+  public void hydrophobicityColour_actionPerformed()
+  {
+    changeColour(new HydrophobicColourScheme());
+  }
+
+  public void helixColour_actionPerformed()
+  {
+    changeColour(new HelixColourScheme());
+  }
+
+  public void strandColour_actionPerformed()
+  {
+    changeColour(new StrandColourScheme());
+  }
+
+  public void turnColour_actionPerformed()
+  {
+    changeColour(new TurnColourScheme());
+  }
+
+  public void buriedColour_actionPerformed()
+  {
+    changeColour(new BuriedColourScheme());
+  }
+
+  public void nucleotideColour_actionPerformed()
+  {
+    changeColour(new NucleotideColourScheme());
+  }
+
+  protected void applyToAllGroups_actionPerformed()
+  {
+    viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());
+  }
+
+  void changeColour(ColourSchemeI cs)
+  {
+    int threshold = 0;
+
+    if(cs!=null)
+    {
+      if (viewport.getAbovePIDThreshold())
+      {
+        threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");
+
+        cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
+
+        viewport.setGlobalColourScheme(cs);
+      }
+      else
+      {
+        cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
+      }
+
+      if (viewport.getConservationSelected())
+      {
+
+        Alignment al = (Alignment) viewport.alignment;
+        Conservation c = new Conservation("All",
+                                          ResidueProperties.propHash, 3,
+                                          al.getSequences(), 0,
+                                          al.getWidth() - 1);
+
+        c.calculate();
+        c.verdict(false, viewport.ConsPercGaps);
+
+        cs.setConservation(c);
+
+        cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,
+            "Background"));
+
+      }
+      else
+      {
+        cs.setConservation(null);
+      }
+
+      cs.setConsensus(viewport.vconsensus);
+
+    }
+    viewport.setGlobalColourScheme(cs);
+
+    if (viewport.getColourAppliesToAllGroups())
+    {
+      Vector groups = viewport.alignment.getGroups();
+      for (int i = 0; i < groups.size(); i++)
+      {
+        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+
+        if(cs==null)
+        {
+          sg.cs = null;
+          continue;
+        }
+        if (cs instanceof ClustalxColourScheme)
+        {
+          sg.cs = new ClustalxColourScheme(sg.getSequences(true), sg.getWidth());
+        }
+        else
+        {
+          try
+          {
+            sg.cs = (ColourSchemeI) cs.getClass().newInstance();
+          }
+          catch (Exception ex)
+          {
+            ex.printStackTrace();
+            sg.cs = cs;
+          }
+        }
+
+        if (viewport.getAbovePIDThreshold()
+            || cs instanceof PIDColourScheme
+            || cs instanceof Blosum62ColourScheme)
+        {
+          sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
+          sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0, sg.getWidth()));
+        }
+        else
+          sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
+
+        if (viewport.getConservationSelected())
+        {
+          Conservation c = new Conservation("Group",
+                                            ResidueProperties.propHash, 3,
+                                            sg.getSequences(true), 0,
+                                            viewport.alignment.getWidth() - 1);
+          c.calculate();
+          c.verdict(false, viewport.ConsPercGaps);
+          sg.cs.setConservation(c);
+        }
+        else
+        {
+          sg.cs.setConservation(null);
+          sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
+        }
+
+      }
+    }
+
+
+    if (alignPanel.getOverviewPanel() != null)
+    {
+      alignPanel.getOverviewPanel().updateOverviewImage();
+    }
+
+    alignPanel.repaint();
+  }
+
+
+
+  protected void modifyPID_actionPerformed()
+  {
+    if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)
+    {
+      SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),
+                                     "Background");
+      SliderPanel.showPIDSlider();
+    }
+  }
+
+  protected void modifyConservation_actionPerformed()
+  {
+    if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)
+    {
+      SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,
+                                        "Background");
+      SliderPanel.showConservationSlider();
+    }
+  }
+
+  protected void conservationMenuItem_actionPerformed()
+  {
+    viewport.setConservationSelected(conservationMenuItem.getState());
+
+    viewport.setAbovePIDThreshold(false);
+    abovePIDThreshold.setState(false);
+
+    changeColour(viewport.getGlobalColourScheme());
+
+    modifyConservation_actionPerformed();
+  }
+
+  public void abovePIDThreshold_actionPerformed()
+  {
+    viewport.setAbovePIDThreshold(abovePIDThreshold.getState());
+
+    conservationMenuItem.setState(false);
+    viewport.setConservationSelected(false);
+
+    changeColour(viewport.getGlobalColourScheme());
+
+    modifyPID_actionPerformed();
+  }
+
+  public void userDefinedColour_actionPerformed()
+  {
+    new UserDefinedColours(alignPanel, null);
+  }
+
+  public void PIDColour_actionPerformed()
+  {
+    changeColour(new PIDColourScheme());
+  }
+
+  public void BLOSUM62Colour_actionPerformed()
+  {
+    changeColour(new Blosum62ColourScheme());
+  }
+
+  public void sortPairwiseMenuItem_actionPerformed()
+  {
+    addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,
+                                   HistoryItem.SORT));
+    AlignmentSorter.sortByPID(viewport.getAlignment(),
+                              viewport.getAlignment().getSequenceAt(0));
+    alignPanel.repaint();
+  }
+
+  public void sortIDMenuItem_actionPerformed()
+  {
+    addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,
+                                   HistoryItem.SORT));
+    AlignmentSorter.sortByID(viewport.getAlignment());
+    alignPanel.repaint();
+  }
+
+  public void sortGroupMenuItem_actionPerformed()
+  {
+    addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,
+                                   HistoryItem.SORT));
+    AlignmentSorter.sortByGroup(viewport.getAlignment());
+    alignPanel.repaint();
+
+  }
+
+  public void removeRedundancyMenuItem_actionPerformed()
+  {
+     new RedundancyPanel(alignPanel);
+  }
+
+  public void pairwiseAlignmentMenuItem_actionPerformed()
+  {
+    if (viewport.getSelectionGroup()!=null
+        && viewport.getSelectionGroup().getSize(false) > 1)
+    {
+      Frame frame = new Frame();
+      frame.add(new PairwiseAlignPanel(alignPanel));
+      jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);
+    }
+  }
+
+  public void PCAMenuItem_actionPerformed()
+  {
+    //are the sequences aligned?
+    if (!viewport.alignment.isAligned())
+    {
+      SequenceI current;
+      int Width = viewport.getAlignment().getWidth();
+
+      for (int i = 0; i < viewport.getAlignment().getSequences().size();
+           i++)
+      {
+        current = viewport.getAlignment().getSequenceAt(i);
+
+        if (current.getLength() < Width)
+        {
+          current.insertCharAt(Width - 1, viewport.getGapCharacter());
+        }
+      }
+      alignPanel.repaint();
+    }
+
+    if ( (viewport.getSelectionGroup() != null &&
+          viewport.getSelectionGroup().getSize(false) < 4 &&
+          viewport.getSelectionGroup().getSize(false) > 0)
+        || viewport.getAlignment().getHeight() < 4)
+    {
+      return;
+    }
+
+    try
+    {
+      new PCAPanel(viewport);
+    }
+    catch (java.lang.OutOfMemoryError ex)
+    {
+    }
+
+  }
+
+  public void averageDistanceTreeMenuItem_actionPerformed()
+  {
+    NewTreePanel("AV", "PID", "Average distance tree using PID");
+  }
+
+  public void neighbourTreeMenuItem_actionPerformed()
+  {
+    NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
+  }
+
+  protected void njTreeBlosumMenuItem_actionPerformed()
+  {
+    NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
+  }
+
+  protected void avTreeBlosumMenuItem_actionPerformed()
+  {
+    NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");
+  }
+
+  void NewTreePanel(String type, String pwType, String title)
+  {
+    //are the sequences aligned?
+    if (!viewport.alignment.isAligned())
+    {
+      SequenceI current;
+      int Width = viewport.getAlignment().getWidth();
+
+      for (int i = 0; i < viewport.getAlignment().getSequences().size();
+           i++)
+      {
+        current = viewport.getAlignment().getSequenceAt(i);
+
+        if (current.getLength() < Width)
+        {
+          current.insertCharAt(Width - 1, viewport.getGapCharacter());
+        }
+      }
+      alignPanel.repaint();
+
+    }
+
+    if ( (viewport.getSelectionGroup() != null &&
+          viewport.getSelectionGroup().getSize(false) > 1)
+      || (viewport.getSelectionGroup() == null
+          && viewport.alignment.getHeight() > 1))
+    {
+      final TreePanel tp = new TreePanel(viewport,
+                                         type,
+                                         pwType);
+
+      addTreeMenuItem(tp, title);
+
+      jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);
+    }
+  }
+
+  void loadTree_actionPerformed()
+  {
+      CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
+      cap.setText("Paste your Newick tree file here.");
+      cap.treeImport = true;
+      Frame frame = new Frame();
+      frame.add(cap);
+      jalview.bin.JalviewLite.addFrame(frame, "Paste Newick file ", 400, 300);
+  }
+
+  public void loadTree(jalview.io.NewickFile tree, String treeFile)
+  {
+    TreePanel tp = new TreePanel(viewport,
+                                 treeFile,
+                                 "From File - ",
+                                 tree);
+    jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);
+    addTreeMenuItem(tp, treeFile);
+  }
+
+  void addTreeMenuItem(final TreePanel treePanel, String title)
+  {
+    final MenuItem item = new MenuItem(title);
+    sortByTreeMenu.add(item);
+    item.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent evt)
+      {
+        addHistoryItem(new HistoryItem("Sort", viewport.alignment,
+                                       HistoryItem.SORT));
+        AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());
+        alignPanel.repaint();
+      }
+    });
+
+    treePanel.addWindowListener(new WindowAdapter()
+    {
+      public void windowClosing(WindowEvent e)
+      {
+        sortByTreeMenu.remove(item);
+      };
+    });
+  }
+
+  protected void documentation_actionPerformed()
+  {
+    showURL("http://www.jalview.org/help.html", "HELP");
+  }
+
+  protected void about_actionPerformed()
+  {
+
+    class AboutPanel extends Canvas
+    {
+      String version;
+      public AboutPanel(String version)
+      { this.version = version; }
+
+      public void paint(Graphics g)
+      {
+        g.setColor(Color.white);
+        g.fillRect(0, 0, getSize().width, getSize().height);
+        g.setFont(new Font("Helvetica", Font.PLAIN, 12));
+        FontMetrics fm = g.getFontMetrics();
+        int fh = fm.getHeight();
+        int y = 5, x = 7;
+        g.setColor(Color.black);
+        g.setFont(new Font("Helvetica", Font.BOLD, 14));
+        g.drawString("Jalview - Release "+version, 200, y += fh);
+        g.setFont(new Font("Helvetica", Font.PLAIN, 12));
+        g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",
+                     x, y += fh * 2);
+        g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",
+                     x, y += fh);
+        g.drawString(
+            "For any issues relating to Jalview, email help@jalview.org", x,
+            y += fh);
+        g.drawString("If  you use JalView, please cite:", x, y += fh + 8);
+        g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",
+                     x, y += fh);
+        g.drawString("Bioinformatics,  2004 20;426-7.", x, y += fh);
+      }
+    }
+
+    String version = "test";
+    java.net.URL url = getClass().getResource("/.build_properties");
+    if (url != null)
+    {
+      try
+      {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            url.openStream()));
+        String line;
+        while ( (line = reader.readLine()) != null)
+        {
+          if (line.indexOf("VERSION") > -1)
+          {
+            version = line.substring(line.indexOf("=") + 1);
+          }
+        }
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+
+
+    Frame frame = new Frame();
+    frame.add(new AboutPanel(version));
+    jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);
+
+  }
+
+  public void showURL(String url, String target)
+  {
+    if (viewport.applet == null)
+    {
+      System.out.println("Not running as applet - no browser available.");
+    }
+    else
+    {
+      try
+      {
+        System.out.println("Show url: "+url);
+        viewport.applet.getAppletContext().showDocument(new java.net.URL(url),
+                                               target);
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+  }
+
+
+  //////////////////////////////////////////////////////////////////////////////////
+  //JBuilder Graphics here
+
+    protected MenuBar alignFrameMenuBar = new MenuBar();
+    protected Menu fileMenu = new Menu("File");
+    protected MenuItem loadApplication = new MenuItem("View in Full Application");
+    protected MenuItem loadTree = new MenuItem("Load Associated Tree");
+    protected MenuItem closeMenuItem = new MenuItem("Close");
+    protected Menu editMenu = new Menu("Edit");
+    protected Menu viewMenu = new Menu("View");
+    protected Menu colourMenu = new Menu("Colour");
+    protected Menu calculateMenu = new Menu("Calculate");
+    protected MenuItem selectAllSequenceMenuItem = new MenuItem("Select all");
+    protected MenuItem deselectAllSequenceMenuItem = new MenuItem("Deselect All");
+    protected MenuItem invertSequenceMenuItem = new MenuItem("Invert Selection");
+    protected MenuItem remove2LeftMenuItem = new MenuItem();
+    protected MenuItem remove2RightMenuItem = new MenuItem();
+    protected MenuItem removeGappedColumnMenuItem = new MenuItem();
+    protected MenuItem removeAllGapsMenuItem = new MenuItem();
+    protected CheckboxMenuItem viewBoxesMenuItem = new CheckboxMenuItem();
+    protected CheckboxMenuItem viewTextMenuItem = new CheckboxMenuItem();
+    protected MenuItem sortPairwiseMenuItem = new MenuItem();
+    protected MenuItem sortIDMenuItem = new MenuItem();
+    protected MenuItem sortGroupMenuItem = new MenuItem();
+    protected MenuItem removeRedundancyMenuItem = new MenuItem();
+    protected MenuItem pairwiseAlignmentMenuItem = new MenuItem();
+    protected MenuItem PCAMenuItem = new MenuItem();
+    protected MenuItem averageDistanceTreeMenuItem = new MenuItem();
+    protected MenuItem neighbourTreeMenuItem = new MenuItem();
+    BorderLayout borderLayout1 = new BorderLayout();
+    public Label statusBar = new Label();
+    protected Menu outputTextboxMenu = new Menu();
+    protected MenuItem clustalColour = new MenuItem();
+    protected MenuItem zappoColour = new MenuItem();
+    protected MenuItem taylorColour = new MenuItem();
+    protected MenuItem hydrophobicityColour = new MenuItem();
+    protected MenuItem helixColour = new MenuItem();
+    protected MenuItem strandColour = new MenuItem();
+    protected MenuItem turnColour = new MenuItem();
+    protected MenuItem buriedColour = new MenuItem();
+    protected MenuItem userDefinedColour = new MenuItem();
+    protected MenuItem PIDColour = new MenuItem();
+    protected MenuItem BLOSUM62Colour = new MenuItem();
+    MenuItem njTreeBlosumMenuItem = new MenuItem();
+    MenuItem avDistanceTreeBlosumMenuItem = new MenuItem();
+    protected CheckboxMenuItem annotationPanelMenuItem = new CheckboxMenuItem();
+    protected CheckboxMenuItem colourTextMenuItem = new CheckboxMenuItem();
+    MenuItem overviewMenuItem = new MenuItem();
+    protected MenuItem undoMenuItem = new MenuItem();
+    protected MenuItem redoMenuItem = new MenuItem();
+    protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
+    MenuItem noColourmenuItem = new MenuItem();
+    protected CheckboxMenuItem wrapMenuItem = new CheckboxMenuItem();
+    protected CheckboxMenuItem renderGapsMenuItem = new CheckboxMenuItem();
+    MenuItem findMenuItem = new MenuItem();
+    Menu searchMenu = new Menu();
+    protected CheckboxMenuItem abovePIDThreshold = new CheckboxMenuItem();
+    protected MenuItem nucleotideColour = new MenuItem();
+    MenuItem deleteGroups = new MenuItem();
+    MenuItem delete = new MenuItem();
+    MenuItem copy = new MenuItem();
+    MenuItem cut = new MenuItem();
+    Menu pasteMenu = new Menu();
+    MenuItem pasteNew = new MenuItem();
+    MenuItem pasteThis = new MenuItem();
+    protected CheckboxMenuItem applyToAllGroups = new CheckboxMenuItem();
+    protected MenuItem font = new MenuItem();
+    protected CheckboxMenuItem scaleAbove = new CheckboxMenuItem();
+    protected CheckboxMenuItem scaleLeft = new CheckboxMenuItem();
+    protected CheckboxMenuItem scaleRight = new CheckboxMenuItem();
+    MenuItem modifyPID = new MenuItem();
+    MenuItem modifyConservation = new MenuItem();
+    protected CheckboxMenuItem autoCalculate
+        = new CheckboxMenuItem("Autocalculate Consensus", true);
+    protected Menu sortByTreeMenu = new Menu();
+    Menu sort = new Menu();
+    Menu calculate = new Menu();
+    MenuItem inputText = new MenuItem();
+    Menu helpMenu = new Menu();
+    MenuItem documentation = new MenuItem();
+    MenuItem about = new MenuItem();
+    protected CheckboxMenuItem seqLimits = new CheckboxMenuItem();
+  Panel embeddedMenu;
+  Label embeddedEdit;
+  Label embeddedSearch;
+  Label embeddedView;
+  Label embeddedColour;
+  Label embeddedFile;
+  Label embeddedHelp;
+  Label embeddedCalculate;
+  FlowLayout flowLayout1;
+
+  private void jbInit() throws Exception {
+
+      setMenuBar(alignFrameMenuBar);
+
+      MenuItem item;
+
+      // dynamically fill save as menu with available formats
+      for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++)
+      {
+
+        item = new MenuItem( jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
+
+        item.addActionListener(new java.awt.event.ActionListener()
+        {
+          public void actionPerformed(ActionEvent e)
+          {
+            outputText_actionPerformed(e);
+          }
+        });
+
+        outputTextboxMenu.add(item);
+      }
+        closeMenuItem.addActionListener(this);
+        loadApplication.addActionListener(this);
+
+        loadTree.addActionListener(this);
+        selectAllSequenceMenuItem.addActionListener(this);
+        deselectAllSequenceMenuItem.addActionListener(this);
+        invertSequenceMenuItem.addActionListener(this);
+        remove2LeftMenuItem.setLabel("Remove Left");
+        remove2LeftMenuItem.addActionListener(this);
+        remove2RightMenuItem.setLabel("Remove Right");
+        remove2RightMenuItem.addActionListener(this);
+        removeGappedColumnMenuItem.setLabel("Remove Empty Columns");
+        removeGappedColumnMenuItem.addActionListener(this);
+        removeAllGapsMenuItem.setLabel("Remove All Gaps");
+        removeAllGapsMenuItem.addActionListener(this);
+        viewBoxesMenuItem.setLabel("Boxes");
+        viewBoxesMenuItem.setState(true);
+        viewBoxesMenuItem.addItemListener(this);
+        viewTextMenuItem.setLabel("Text");
+        viewTextMenuItem.setState(true);
+        viewTextMenuItem.addItemListener(this);
+        sortPairwiseMenuItem.setLabel("by Pairwise Identity");
+        sortPairwiseMenuItem.addActionListener(this);
+        sortIDMenuItem.setLabel("by ID");
+        sortIDMenuItem.addActionListener(this);
+        sortGroupMenuItem.setLabel("by Group");
+        sortGroupMenuItem.addActionListener(this);
+        removeRedundancyMenuItem.setLabel("Remove Redundancy...");
+        removeRedundancyMenuItem.addActionListener(this);
+        pairwiseAlignmentMenuItem.setLabel("Pairwise Alignments...");
+        pairwiseAlignmentMenuItem.addActionListener(this);
+        PCAMenuItem.setLabel("Principal Component Analysis");
+        PCAMenuItem.addActionListener(this);
+        averageDistanceTreeMenuItem.setLabel(
+            "Average Distance Using % Identity");
+        averageDistanceTreeMenuItem.addActionListener(this);
+        neighbourTreeMenuItem.setLabel("Neighbour Joining Using % Identity");
+        neighbourTreeMenuItem.addActionListener(this);
+        alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));
+        statusBar.setBackground(Color.white);
+        statusBar.setFont(new java.awt.Font("Verdana", 0, 11));
+        statusBar.setText("Status bar");
+        outputTextboxMenu.setLabel("Output to Textbox");
+        clustalColour.setLabel("Clustalx");
+
+        clustalColour.addActionListener(this);
+        zappoColour.setLabel("Zappo");
+        zappoColour.addActionListener(this);
+        taylorColour.setLabel("Taylor");
+        taylorColour.addActionListener(this);
+        hydrophobicityColour.setLabel("Hydrophobicity");
+        hydrophobicityColour.addActionListener(this);
+        helixColour.setLabel("Helix Propensity");
+        helixColour.addActionListener(this);
+        strandColour.setLabel("Strand Propensity");
+        strandColour.addActionListener(this);
+        turnColour.setLabel("Turn Propensity");
+        turnColour.addActionListener(this);
+        buriedColour.setLabel("Buried Index");
+        buriedColour.addActionListener(this);
+        userDefinedColour.setLabel("User Defined...");
+        userDefinedColour.addActionListener(this);
+        PIDColour.setLabel("Percentage Identity");
+        PIDColour.addActionListener(this);
+        BLOSUM62Colour.setLabel("BLOSUM62 Score");
+        BLOSUM62Colour.addActionListener(this);
+        avDistanceTreeBlosumMenuItem.setLabel(
+            "Average Distance Using BLOSUM62");
+        avDistanceTreeBlosumMenuItem.addActionListener(this);
+        njTreeBlosumMenuItem.setLabel("Neighbour Joining Using BLOSUM62");
+        njTreeBlosumMenuItem.addActionListener(this);
+        annotationPanelMenuItem.setLabel("Show Annotations");
+        annotationPanelMenuItem.addItemListener(this);
+        colourTextMenuItem.setLabel("Colour Text");
+        colourTextMenuItem.addItemListener(this);
+        overviewMenuItem.setLabel("Overview Window");
+        overviewMenuItem.addActionListener(this);
+        undoMenuItem.setEnabled(false);
+        undoMenuItem.setLabel("Undo");
+        undoMenuItem.addActionListener(this);
+        redoMenuItem.setEnabled(false);
+        redoMenuItem.setLabel("Redo");
+        redoMenuItem.addActionListener(this);
+        conservationMenuItem.setLabel("by Conservation");
+        conservationMenuItem.addItemListener(this);
+        noColourmenuItem.setLabel("None");
+        noColourmenuItem.addActionListener(this);
+        wrapMenuItem.setLabel("Wrap");
+        wrapMenuItem.addItemListener(this);
+        renderGapsMenuItem.setLabel("Show Gaps");
+        renderGapsMenuItem.setState(true);
+        renderGapsMenuItem.addItemListener(this);
+        findMenuItem.setLabel("Find...");
+        findMenuItem.addActionListener(this);
+        searchMenu.setLabel("Search");
+
+        abovePIDThreshold.setLabel("Above Identity Threshold");
+        abovePIDThreshold.addItemListener(this);
+        nucleotideColour.setLabel("Nucleotide");
+        nucleotideColour.addActionListener(this);
+        deleteGroups.setLabel("Undefine Groups");
+        deleteGroups.addActionListener(this);
+        copy.setLabel("Copy");
+        copy.addActionListener(this);
+        cut.setLabel("Cut");
+        cut.addActionListener(this);
+        delete.setLabel("Delete");
+        delete.addActionListener(this);
+        pasteMenu.setLabel("Paste");
+        pasteNew.setLabel("To New Alignment");
+        pasteNew.addActionListener(this);
+        pasteThis.setLabel("Add To This Alignment");
+        pasteThis.addActionListener(this);
+        applyToAllGroups.setLabel("Apply Colour To All Groups");
+        applyToAllGroups.setState(true);
+        applyToAllGroups.addItemListener(this);
+        font.setLabel("Font...");
+        font.addActionListener(this);
+        scaleAbove.setLabel("Scale Above");
+        scaleAbove.setState(true);
+        scaleAbove.setEnabled(false);
+        scaleAbove.addItemListener(this);
+        scaleLeft.setEnabled(false);
+        scaleLeft.setState(true);
+        scaleLeft.setLabel("Scale Left");
+        scaleLeft.addItemListener(this);
+        scaleRight.setEnabled(false);
+        scaleRight.setState(true);
+        scaleRight.setLabel("Scale Right");
+        scaleRight.addItemListener(this);
+        modifyPID.setLabel("Modify Identity Threshold...");
+        modifyPID.addActionListener(this);
+        modifyConservation.setLabel("Modify Conservation Threshold...");
+        modifyConservation.addActionListener(this);
+        sortByTreeMenu.setLabel("By Tree Order");
+        sort.setLabel("Sort");
+        calculate.setLabel("Calculate Tree");
+        autoCalculate.addItemListener(this);
+        inputText.setLabel("Input from textbox");
+        inputText.addActionListener(this);
+
+        helpMenu.setLabel("Help");
+        documentation.setLabel("Documentation");
+        documentation.addActionListener(this);
+
+        about.setLabel("About...");
+        about.addActionListener(this);
+          seqLimits.setState(true);
+    seqLimits.setLabel("Show Sequence Limits");
+    seqLimits.addItemListener(this);
+    featureSettings.setLabel("Feature Settings...");
+    featureSettings.addActionListener(this);
+    sequenceFeatures.setLabel("Sequence Features");
+    sequenceFeatures.addItemListener(this);
+    sequenceFeatures.setState(false);
+    annotationColour.setLabel("by Annotation...");
+    annotationColour.addActionListener(this);
+    invertSequenceMenuItem.setLabel("Invert Sequence Selection");
+    invertColSel.setLabel("Invert Column Selection");
+    menu1.setLabel("Show");
+    showColumns.setLabel("All Columns ");
+    showSeqs.setLabel("All Sequences");
+    menu2.setLabel("Hide");
+    hideColumns.setLabel("Selected Columns");
+    hideSequences.setLabel("Selected Sequences");
+    invertColSel.addActionListener(this);
+    showColumns.addActionListener(this);
+    showSeqs.addActionListener(this);
+    hideColumns.addActionListener(this);
+    hideSequences.addActionListener(this);
+
+
+    alignFrameMenuBar.add(fileMenu);
+        alignFrameMenuBar.add(editMenu);
+        alignFrameMenuBar.add(searchMenu);
+        alignFrameMenuBar.add(viewMenu);
+        alignFrameMenuBar.add(colourMenu);
+        alignFrameMenuBar.add(calculateMenu);
+        alignFrameMenuBar.add(helpMenu);
+        fileMenu.add(inputText);
+        fileMenu.add(outputTextboxMenu);
+        if(jalviewServletURL!=null)
+          fileMenu.add(loadApplication);
+        fileMenu.addSeparator();
+        fileMenu.add(loadTree);
+        fileMenu.add(closeMenuItem);
+        editMenu.add(undoMenuItem);
+        editMenu.add(redoMenuItem);
+        editMenu.add(cut);
+        editMenu.add(copy);
+        editMenu.add(pasteMenu);
+        editMenu.add(delete);
+        editMenu.addSeparator();
+        editMenu.add(selectAllSequenceMenuItem);
+        editMenu.add(deselectAllSequenceMenuItem);
+        editMenu.add(invertSequenceMenuItem);
+    editMenu.add(invertColSel);
+    editMenu.add(deleteGroups);
+        editMenu.addSeparator();
+        editMenu.add(remove2LeftMenuItem);
+        editMenu.add(remove2RightMenuItem);
+        editMenu.add(removeGappedColumnMenuItem);
+        editMenu.add(removeAllGapsMenuItem);
+        editMenu.add(removeRedundancyMenuItem);
+        searchMenu.add(findMenuItem);
+        viewMenu.add(font);
+        viewMenu.addSeparator();
+    viewMenu.add(menu1);
+    viewMenu.add(menu2);
+    viewMenu.addSeparator();
+    viewMenu.add(wrapMenuItem);
+        viewMenu.add(scaleAbove);
+        viewMenu.add(scaleLeft);
+        viewMenu.add(scaleRight);
+        viewMenu.addSeparator();
+    viewMenu.add(seqLimits);
+    viewMenu.add(viewBoxesMenuItem);
+        viewMenu.add(viewTextMenuItem);
+        viewMenu.add(colourTextMenuItem);
+        viewMenu.add(renderGapsMenuItem);
+        viewMenu.add(annotationPanelMenuItem);
+    viewMenu.addSeparator();
+        viewMenu.add(sequenceFeatures);
+        viewMenu.add(featureSettings);
+    viewMenu.addSeparator();
+        viewMenu.add(overviewMenuItem);
+        colourMenu.add(applyToAllGroups);
+        colourMenu.addSeparator();
+        colourMenu.add(noColourmenuItem);
+        colourMenu.add(clustalColour);
+        colourMenu.add(BLOSUM62Colour);
+        colourMenu.add(PIDColour);
+        colourMenu.add(zappoColour);
+        colourMenu.add(taylorColour);
+        colourMenu.add(hydrophobicityColour);
+        colourMenu.add(helixColour);
+        colourMenu.add(strandColour);
+        colourMenu.add(turnColour);
+        colourMenu.add(buriedColour);
+        colourMenu.add(nucleotideColour);
+        colourMenu.add(userDefinedColour);
+        colourMenu.addSeparator();
+        colourMenu.add(conservationMenuItem);
+        colourMenu.add(modifyConservation);
+        colourMenu.add(abovePIDThreshold);
+        colourMenu.add(modifyPID);
+    colourMenu.add(annotationColour);
+    calculateMenu.add(sort);
+        calculateMenu.add(calculate);
+        calculateMenu.addSeparator();
+        calculateMenu.add(pairwiseAlignmentMenuItem);
+        calculateMenu.add(PCAMenuItem);
+        calculateMenu.add(autoCalculate);
+        this.add(statusBar, BorderLayout.SOUTH);
+        pasteMenu.add(pasteNew);
+        pasteMenu.add(pasteThis);
+        sort.add(sortIDMenuItem);
+        sort.add(sortByTreeMenu);
+        sort.add(sortGroupMenuItem);
+        sort.add(sortPairwiseMenuItem);
+        calculate.add(averageDistanceTreeMenuItem);
+        calculate.add(neighbourTreeMenuItem);
+        calculate.add(avDistanceTreeBlosumMenuItem);
+        calculate.add(njTreeBlosumMenuItem);
+        helpMenu.add(documentation);
+        helpMenu.add(about);
+    menu1.add(showColumns);
+    menu1.add(showSeqs);
+    menu2.add(hideColumns);
+    menu2.add(hideSequences);
+  }
+
+  public void setEmbedded()
+  {
+
+    embeddedMenu = new Panel();
+    embeddedEdit = new Label();
+    embeddedSearch = new Label();
+    embeddedView = new Label();
+    embeddedColour = new Label();
+    embeddedFile = new Label();
+    embeddedHelp = new Label();
+    embeddedCalculate = new Label();
+    flowLayout1 = new FlowLayout();
+    embeddedMenu.setBackground(Color.lightGray);
+    embeddedMenu.setLayout(flowLayout1);
+    embeddedEdit.setText("Edit");
+    embeddedEdit.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedSearch.setText("Search");
+    embeddedSearch.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedView.setText("View");
+    embeddedView.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedColour.setText("Colour");
+    embeddedColour.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedFile.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedFile.setText("File");
+    embeddedHelp.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedHelp.setText("Help");
+    embeddedCalculate.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
+    embeddedCalculate.setText("Calculate");
+    embeddedMenu.add(embeddedFile);
+    embeddedMenu.add(embeddedEdit);
+    embeddedMenu.add(embeddedSearch);
+    embeddedMenu.add(embeddedView);
+    embeddedMenu.add(embeddedColour);
+    embeddedMenu.add(embeddedCalculate);
+    embeddedMenu.add(embeddedHelp);
+    flowLayout1.setAlignment(FlowLayout.LEFT);
+    flowLayout1.setHgap(2);
+    flowLayout1.setVgap(0);
+    embeddedFile.addMouseListener(this);
+    embeddedEdit.addMouseListener(this);
+    embeddedSearch.addMouseListener(this);
+    embeddedView.addMouseListener(this);
+    embeddedColour.addMouseListener(this);
+    embeddedCalculate.addMouseListener(this);
+    embeddedHelp.addMouseListener(this);
+
+   // setVisible(false);
+    fileMenu.remove(closeMenuItem);
+    fileMenu.remove(3); // Seperator
+
+    viewport.applet.setLayout(new BorderLayout());
+    viewport.applet.add(embeddedMenu, BorderLayout.NORTH);
+    viewport.applet.add(statusBar, BorderLayout.SOUTH);
+   // viewport.applet.validate();
+
+    alignPanel.setSize(viewport.applet.size().width, viewport.applet.size().height
+                       - embeddedMenu.HEIGHT - statusBar.HEIGHT);
+
+     viewport.applet.add(alignPanel, BorderLayout.CENTER);
+     viewport.applet.validate();
+
+  }
+
+
+
+  PopupMenu filePopup, editPopup, searchPopup,
+      viewPopup, colourPopup, calculatePopup, helpPopup;
+  MenuItem featureSettings = new MenuItem();
+  CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();
+  MenuItem annotationColour = new MenuItem();
+  MenuItem invertColSel = new MenuItem();
+  Menu menu1 = new Menu();
+  MenuItem showColumns = new MenuItem();
+  MenuItem showSeqs = new MenuItem();
+  Menu menu2 = new Menu();
+  MenuItem hideColumns = new MenuItem();
+  MenuItem hideSequences = new MenuItem();
+
+  public void mousePressed(MouseEvent evt)
+  {
+    PopupMenu popup = null;
+    Label source = (Label)evt.getSource();
+    if(source==embeddedFile)
+    {
+      popup = filePopup = genPopupMenu(filePopup, fileMenu);
+    }
+    else if(source==embeddedEdit)
+    {
+      popup = editPopup = genPopupMenu(editPopup, editMenu);
+    }
+    else if(source==embeddedSearch)
+    {
+      popup = searchPopup = genPopupMenu(searchPopup, searchMenu);
+    }
+    else if(source==embeddedView)
+    {
+      popup = viewPopup = genPopupMenu(viewPopup, viewMenu);
+    }
+    else if(source==embeddedColour)
+    {
+      popup = colourPopup = genPopupMenu(colourPopup, colourMenu);
+    }
+    else if(source==embeddedCalculate)
+    {
+      popup = calculatePopup = genPopupMenu(calculatePopup, calculateMenu);
+    }
+    else if(source==embeddedHelp)
+    {
+      popup = helpPopup = genPopupMenu(helpPopup, helpMenu);
+    }
+
+    embeddedMenu.add(popup);
+    popup.show(embeddedMenu,
+               source.getBounds().x,
+               source.getBounds().y + source.getBounds().getSize().height);
+  }
+
+  PopupMenu genPopupMenu(PopupMenu popup, Menu original)
+  {
+    if(popup!=null)
+    {
+      return popup;
+    }
+    popup = new PopupMenu();
+    int m, mSize = original.getItemCount();
+    for(m=0; m<mSize; m++)
+    {
+      popup.add(original.getItem(m));
+      mSize--;
+      m--;
+    }
+
+    return popup;
+  }
+  public void mouseClicked(MouseEvent evt)
+  {}
+  public void mouseReleased(MouseEvent evt)
+  {}
+  public void mouseEntered(MouseEvent evt)
+  {}
+  public void mouseExited(MouseEvent evt)
+  {}
+
+}
+
index bef5e1a..eb832f2 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.bin.*;\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-\r
-public class AlignViewport\r
-{\r
-  int startRes;\r
-  int endRes;\r
-\r
-  int startSeq;\r
-  int endSeq;\r
-\r
-  boolean showJVSuffix = true;\r
-  boolean showText = true;\r
-  boolean showColourText = false;\r
-  boolean showBoxes = true;\r
-  boolean wrapAlignment = false;\r
-  boolean renderGaps = true;\r
-  boolean showSequenceFeatures = false;\r
-  boolean showAnnotation = true;\r
-  boolean showConservation = true;\r
-  boolean showQuality = true;\r
-  boolean showConsensus = true;\r
-\r
-  boolean colourAppliesToAllGroups = true;\r
-  ColourSchemeI globalColourScheme = null;\r
-  boolean conservationColourSelected = false;\r
-  boolean abovePIDThreshold = false;\r
-\r
-  SequenceGroup selectionGroup = new SequenceGroup();\r
-\r
-  int charHeight;\r
-  int charWidth;\r
-  int wrappedWidth;\r
-\r
-  Font font = new Font("SansSerif", Font.PLAIN, 10);\r
-  AlignmentI alignment;\r
-\r
-  ColumnSelection colSel = new ColumnSelection();\r
-\r
-  int threshold;\r
-  int increment;\r
-\r
-  NJTree currentTree = null;\r
-\r
-  boolean scaleAboveWrapped = true;\r
-  boolean scaleLeftWrapped = true;\r
-  boolean scaleRightWrapped = true;\r
-\r
-  // The following vector holds the features which are\r
- // currently visible, in the correct order or rendering\r
-  Hashtable featuresDisplayed = null;\r
-\r
-\r
-  public Vector vconsensus;\r
-  AlignmentAnnotation consensus;\r
-  AlignmentAnnotation conservation;\r
-  AlignmentAnnotation quality;\r
-\r
-  public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
-\r
-  private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);\r
-\r
-  boolean ignoreGapsInConsensusCalculation = false;\r
-\r
-  public AlignViewport(AlignmentI al, JalviewLite applet)\r
-  {\r
-    setAlignment(al);\r
-    this.startRes = 0;\r
-    this.endRes = al.getWidth() - 1;\r
-    this.startSeq = 0;\r
-    this.endSeq = al.getHeight() - 1;\r
-    setFont(font);\r
-\r
-    if (applet != null)\r
-    {\r
-      String param = applet.getParameter("showFullId");\r
-      if (param != null)\r
-      {\r
-        showJVSuffix = Boolean.valueOf(param).booleanValue();\r
-      }\r
-\r
-      param = applet.getParameter("showAnnotation");\r
-      if (param != null)\r
-      {\r
-        showAnnotation = Boolean.valueOf(param).booleanValue();\r
-      }\r
-\r
-      param = applet.getParameter("showConservation");\r
-      if (param != null)\r
-      {\r
-        showConservation = Boolean.valueOf(param).booleanValue();\r
-      }\r
-\r
-      param = applet.getParameter("showQuality");\r
-      if (param != null)\r
-      {\r
-        showQuality = Boolean.valueOf(param).booleanValue();\r
-      }\r
-\r
-      param = applet.getParameter("showConsensus");\r
-      if (param != null)\r
-      {\r
-        showConsensus = Boolean.valueOf(param).booleanValue();\r
-      }\r
-    }\r
-    // We must set conservation and consensus before setting colour,\r
-    // as Blosum and Clustal require this to be done\r
-    updateConservation();\r
-    updateConsensus();\r
-\r
-    if (applet != null && applet.getParameter("defaultColour") != null)\r
-    {\r
-      globalColourScheme = ColourSchemeProperty.getColour(alignment,\r
-          applet.getParameter("defaultColour"));\r
-      if (globalColourScheme != null)\r
-      {\r
-        globalColourScheme.setConsensus(vconsensus);\r
-      }\r
-    }\r
-  }\r
-\r
-  public void showSequenceFeatures(boolean b)\r
-  {\r
-    showSequenceFeatures = b;\r
-  }\r
-\r
-  public boolean getShowSequenceFeatures()\r
-  {\r
-    return showSequenceFeatures;\r
-  }\r
-\r
-\r
-  public void updateConservation()\r
-  {\r
-    if(alignment.isNucleotide())\r
-          return;\r
-\r
-    Conservation cons = new jalview.analysis.Conservation("All",\r
-        jalview.schemes.ResidueProperties.propHash, 3,\r
-        alignment.getSequences(), 0,\r
-        alignment.getWidth() - 1);\r
-    cons.calculate();\r
-    cons.verdict(false, ConsPercGaps);\r
-    cons.findQuality();\r
-    int alWidth = alignment.getWidth();\r
-    Annotation[] annotations = new Annotation[alWidth];\r
-    Annotation[] qannotations = new Annotation[alWidth];\r
-    String sequence = cons.getConsSequence().getSequence();\r
-    float minR, minG, minB, maxR, maxG, maxB;\r
-    minR = 0.3f;\r
-    minG = 0.0f;\r
-    minB = 0f;\r
-    maxR = 1.0f - minR;\r
-    maxG = 0.9f - minG;\r
-    maxB = 0f - minB; // scalable range for colouring both Conservation and Quality\r
-    float min = 0f;\r
-    float max = 11f;\r
-    float qmin = cons.qualityRange[0].floatValue();\r
-    float qmax = cons.qualityRange[1].floatValue();\r
-\r
-    for (int i = 0; i < alWidth; i++)\r
-    {\r
-      float value = 0;\r
-      try\r
-      {\r
-        value = Integer.parseInt(sequence.charAt(i) + "");\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        if (sequence.charAt(i) == '*')\r
-        {\r
-          value = 11;\r
-        }\r
-        if (sequence.charAt(i) == '+')\r
-        {\r
-          value = 10;\r
-        }\r
-      }\r
-      float vprop = value - min;\r
-      vprop /= max;\r
-\r
-      annotations[i] = new Annotation(sequence.charAt(i) + "",\r
-                                      "", ' ', value,\r
-                                      new Color(minR + maxR * vprop,\r
-                                                minG + maxG * vprop,\r
-                                                minB + maxB * vprop));\r
-      // Quality calc\r
-      value = ( (Double) cons.quality.elementAt(i)).floatValue();\r
-      vprop = value - qmin;\r
-      vprop /= qmax;\r
-      qannotations[i] = new Annotation(" ",\r
-                                       String.valueOf(value), ' ', value,\r
-                                       new\r
-                                       Color(minR + maxR * vprop,\r
-                                             minG + maxG * vprop,\r
-                                             minB + maxB * vprop));\r
-    }\r
-\r
-    if (conservation == null)\r
-    {\r
-      conservation = new AlignmentAnnotation("Conservation",\r
-                                             "Conservation of total alignment less than " +\r
-                                             ConsPercGaps + "% gaps",\r
-                                             annotations,\r
-                                             0f, // cons.qualityRange[0].floatValue(),\r
-                                             11f, // cons.qualityRange[1].floatValue()\r
-                                             AlignmentAnnotation.BAR_GRAPH);\r
-      if (showConservation)\r
-      {\r
-        alignment.addAnnotation(conservation);\r
-      }\r
-      quality = new AlignmentAnnotation("Quality",\r
-                                        "Alignment Quality based on Blosum62 scores",\r
-                                        qannotations,\r
-                                        cons.qualityRange[0].floatValue(),\r
-                                        cons.qualityRange[1].floatValue(),\r
-                                        AlignmentAnnotation.BAR_GRAPH);\r
-      if (showQuality)\r
-      {\r
-        alignment.addAnnotation(quality);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      conservation.annotations = annotations;\r
-      quality.annotations = qannotations;\r
-      quality.graphMax = cons.qualityRange[1].floatValue();\r
-    }\r
-\r
-  }\r
-\r
-  public void updateConsensus()\r
-  {\r
-    Annotation[] annotations = new Annotation[alignment.getWidth()];\r
-\r
-    // this routine prevents vconsensus becoming a new object each time\r
-    // consenus is calculated. Important for speed of Blosum62\r
-    // and PID colouring of alignment\r
-    if (vconsensus == null)\r
-    {\r
-      vconsensus = alignment.getAAFrequency();\r
-    }\r
-    else\r
-    {\r
-      Vector temp = alignment.getAAFrequency();\r
-      vconsensus.removeAllElements();\r
-      Enumeration e = temp.elements();\r
-      while (e.hasMoreElements())\r
-      {\r
-        vconsensus.addElement(e.nextElement());\r
-      }\r
-    }\r
-    Hashtable hash = null;\r
-    for (int i = 0; i < alignment.getWidth(); i++)\r
-    {\r
-      hash = (Hashtable) vconsensus.elementAt(i);\r
-      float value = 0;\r
-      if(ignoreGapsInConsensusCalculation)\r
-        value = ((Float)hash.get("pid_nogaps")).floatValue();\r
-      else\r
-        value = ((Float)hash.get("pid_gaps")).floatValue();\r
-\r
-      String maxRes = hash.get("maxResidue").toString();\r
-      String mouseOver = hash.get("maxResidue") + " ";\r
-      if (maxRes.length() > 1)\r
-      {\r
-        mouseOver = "[" + maxRes + "] ";\r
-        maxRes = "+";\r
-      }\r
-\r
-\r
-      mouseOver += (int) value + "%";\r
-      annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);\r
-\r
-    }\r
-\r
-    if (consensus == null)\r
-    {\r
-      consensus = new AlignmentAnnotation("Consensus",\r
-                                          "PID", annotations, 0f, 100f, AlignmentAnnotation.BAR_GRAPH);\r
-      if (showConsensus)\r
-      {\r
-        alignment.addAnnotation(consensus);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      consensus.annotations = annotations;\r
-    }\r
-\r
-    if(globalColourScheme!=null)\r
-          globalColourScheme.setConsensus(vconsensus);\r
-\r
-  }\r
-\r
-  public SequenceGroup getSelectionGroup()\r
-  {\r
-    return selectionGroup;\r
-  }\r
-\r
-  public void setSelectionGroup(SequenceGroup sg)\r
-  {\r
-    selectionGroup = sg;\r
-  }\r
-\r
-  public boolean getConservationSelected()\r
-  {\r
-    return conservationColourSelected;\r
-  }\r
-\r
-  public void setConservationSelected(boolean b)\r
-  {\r
-    conservationColourSelected = b;\r
-  }\r
-\r
-  public boolean getAbovePIDThreshold()\r
-  {\r
-    return abovePIDThreshold;\r
-  }\r
-\r
-  public void setAbovePIDThreshold(boolean b)\r
-  {\r
-    abovePIDThreshold = b;\r
-  }\r
-\r
-  public int getStartRes()\r
-  {\r
-    return startRes;\r
-  }\r
-\r
-  public int getEndRes()\r
-  {\r
-    return endRes;\r
-  }\r
-\r
-  public int getStartSeq()\r
-  {\r
-    return startSeq;\r
-  }\r
-\r
-  public void setGlobalColourScheme(ColourSchemeI cs)\r
-  {\r
-    globalColourScheme = cs;\r
-  }\r
-\r
-  public ColourSchemeI getGlobalColourScheme()\r
-  {\r
-    return globalColourScheme;\r
-  }\r
-\r
-  public void setStartRes(int res)\r
-  {\r
-    this.startRes = res;\r
-  }\r
-\r
-  public void setStartSeq(int seq)\r
-  {\r
-    this.startSeq = seq;\r
-  }\r
-\r
-  public void setEndRes(int res)\r
-  {\r
-    if (res > alignment.getWidth() - 1)\r
-    {\r
-      // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));\r
-      res = alignment.getWidth() - 1;\r
-    }\r
-    if (res < 0)\r
-    {\r
-      res = 0;\r
-    }\r
-    this.endRes = res;\r
-  }\r
-\r
-  public void setEndSeq(int seq)\r
-  {\r
-    if (seq > alignment.getHeight())\r
-    {\r
-      seq = alignment.getHeight();\r
-    }\r
-    if (seq < 0)\r
-    {\r
-      seq = 0;\r
-    }\r
-    this.endSeq = seq;\r
-  }\r
-\r
-  public int getEndSeq()\r
-  {\r
-    return endSeq;\r
-  }\r
-\r
-  public void setFont(Font f)\r
-  {\r
-    font = f;\r
-    java.awt.Frame temp = new java.awt.Frame();\r
-    temp.addNotify();\r
-    java.awt.FontMetrics fm = temp.getGraphics().getFontMetrics(font);\r
-    setCharHeight(fm.getHeight());\r
-    setCharWidth(fm.charWidth('M'));\r
-  }\r
-\r
-  public Font getFont()\r
-  {\r
-    return font;\r
-  }\r
-\r
-  public void setCharWidth(int w)\r
-  {\r
-    this.charWidth = w;\r
-  }\r
-\r
-  public int getCharWidth()\r
-  {\r
-    return charWidth;\r
-  }\r
-\r
-  public void setCharHeight(int h)\r
-  {\r
-    this.charHeight = h;\r
-  }\r
-\r
-  public int getCharHeight()\r
-  {\r
-    return charHeight;\r
-  }\r
-\r
-  public void setWrappedWidth(int w)\r
-  {\r
-    this.wrappedWidth = w;\r
-  }\r
-\r
-  public int getwrappedWidth()\r
-  {\r
-    return wrappedWidth;\r
-  }\r
-\r
-  public AlignmentI getAlignment()\r
-  {\r
-    return alignment;\r
-  }\r
-\r
-  public void setAlignment(AlignmentI align)\r
-  {\r
-    this.alignment = align;\r
-  }\r
-\r
-  public void setWrapAlignment(boolean state)\r
-  {\r
-    wrapAlignment = state;\r
-  }\r
-\r
-  public void setShowText(boolean state)\r
-  {\r
-    showText = state;\r
-  }\r
-\r
-  public void setRenderGaps(boolean state)\r
-  {\r
-    renderGaps = state;\r
-  }\r
-\r
-  public boolean getColourText()\r
-  {\r
-    return showColourText;\r
-  }\r
-\r
-  public void setColourText(boolean state)\r
-  {\r
-    showColourText = state;\r
-  }\r
-\r
-  public void setShowBoxes(boolean state)\r
-  {\r
-    showBoxes = state;\r
-  }\r
-\r
-  public boolean getWrapAlignment()\r
-  {\r
-    return wrapAlignment;\r
-  }\r
-\r
-  public boolean getShowText()\r
-  {\r
-    return showText;\r
-  }\r
-\r
-  public boolean getShowBoxes()\r
-  {\r
-    return showBoxes;\r
-  }\r
-\r
-  public char getGapCharacter()\r
-  {\r
-    return getAlignment().getGapCharacter();\r
-  }\r
-\r
-  public void setGapCharacter(char gap)\r
-  {\r
-    if (getAlignment() != null)\r
-    {\r
-      getAlignment().setGapCharacter(gap);\r
-    }\r
-  }\r
-\r
-  public void setThreshold(int thresh)\r
-  {\r
-    threshold = thresh;\r
-  }\r
-\r
-  public int getThreshold()\r
-  {\r
-    return threshold;\r
-  }\r
-\r
-  public void setIncrement(int inc)\r
-  {\r
-    increment = inc;\r
-  }\r
-\r
-  public int getIncrement()\r
-  {\r
-    return increment;\r
-  }\r
-\r
-  public int getIndex(int y)\r
-  {\r
-    int y1 = 0;\r
-    int starty = getStartSeq();\r
-    int endy = getEndSeq();\r
-\r
-    for (int i = starty; i <= endy; i++)\r
-    {\r
-      if (i < alignment.getHeight() && alignment.getSequenceAt(i) != null)\r
-      {\r
-        int y2 = y1 + getCharHeight();\r
-\r
-        if (y >= y1 && y <= y2)\r
-        {\r
-          return i;\r
-        }\r
-        y1 = y2;\r
-      }\r
-      else\r
-      {\r
-        return -1;\r
-      }\r
-    }\r
-    return -1;\r
-  }\r
-\r
-  public ColumnSelection getColumnSelection()\r
-  {\r
-    return colSel;\r
-  }\r
-\r
-  public void resetSeqLimits(int height)\r
-  {\r
-    setEndSeq(height / getCharHeight());\r
-  }\r
-\r
-  public void setCurrentTree(NJTree tree)\r
-  {\r
-    currentTree = tree;\r
-  }\r
-\r
-  public NJTree getCurrentTree()\r
-  {\r
-    return currentTree;\r
-  }\r
-\r
-  public void setColourAppliesToAllGroups(boolean b)\r
-  {\r
-    colourAppliesToAllGroups = b;\r
-  }\r
-\r
-  public boolean getColourAppliesToAllGroups()\r
-  {\r
-    return colourAppliesToAllGroups;\r
-  }\r
-\r
-  public boolean getShowJVSuffix()\r
-  {\r
-    return showJVSuffix;\r
-  }\r
-\r
-  public void setShowJVSuffix(boolean b)\r
-  {\r
-    showJVSuffix = b;\r
-  }\r
-\r
-  public boolean getShowAnnotation()\r
-  {\r
-    return showAnnotation;\r
-  }\r
-\r
-  public void setShowAnnotation(boolean b)\r
-  {\r
-    showAnnotation = b;\r
-  }\r
-\r
-  public boolean getScaleAboveWrapped()\r
-  {\r
-    return scaleAboveWrapped;\r
-  }\r
-\r
-  public boolean getScaleLeftWrapped()\r
-  {\r
-    return scaleLeftWrapped;\r
-  }\r
-\r
-  public boolean getScaleRightWrapped()\r
-  {\r
-    return scaleRightWrapped;\r
-  }\r
-\r
-  public void setScaleAboveWrapped(boolean b)\r
-  {\r
-    scaleAboveWrapped = b;\r
-  }\r
-\r
-  public void setScaleLeftWrapped(boolean b)\r
-  {\r
-    scaleLeftWrapped = b;\r
-  }\r
-\r
-  public void setScaleRightWrapped(boolean b)\r
-  {\r
-    scaleRightWrapped = b;\r
-  }\r
-\r
-  public void setIgnoreGapsConsensus(boolean b)\r
-  {\r
-    ignoreGapsInConsensusCalculation = b;\r
-    updateConsensus();\r
-    if (globalColourScheme!=null)\r
-    {\r
-      globalColourScheme.setThreshold(globalColourScheme.getThreshold(),\r
-          ignoreGapsInConsensusCalculation);\r
-\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Property change listener for changes in alignment\r
-   *\r
-   * @param listener DOCUMENT ME!\r
-   */\r
-  public void addPropertyChangeListener(\r
-      java.beans.PropertyChangeListener listener)\r
-  {\r
-      changeSupport.addPropertyChangeListener(listener);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param listener DOCUMENT ME!\r
-   */\r
-  public void removePropertyChangeListener(\r
-      java.beans.PropertyChangeListener listener)\r
-  {\r
-      changeSupport.removePropertyChangeListener(listener);\r
-  }\r
-\r
-  /**\r
-   * Property change listener for changes in alignment\r
-   *\r
-   * @param prop DOCUMENT ME!\r
-   * @param oldvalue DOCUMENT ME!\r
-   * @param newvalue DOCUMENT ME!\r
-   */\r
-  public void firePropertyChange(String prop, Object oldvalue, Object newvalue)\r
-  {\r
-      changeSupport.firePropertyChange(prop, oldvalue, newvalue);\r
-  }\r
-\r
-\r
-\r
-  public boolean getIgnoreGapsConsensus()\r
-  {\r
-    return ignoreGapsInConsensusCalculation;\r
-  }\r
-\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+
+import jalview.analysis.*;
+import jalview.bin.*;
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+public class AlignViewport
+{
+  int startRes;
+  int endRes;
+
+  int startSeq;
+  int endSeq;
+
+
+  boolean cursorMode = false;
+
+  boolean showJVSuffix = true;
+  boolean showText = true;
+  boolean showColourText = false;
+  boolean showBoxes = true;
+  boolean wrapAlignment = false;
+  boolean renderGaps = true;
+  boolean showSequenceFeatures = false;
+  boolean showAnnotation = true;
+  boolean showConservation = true;
+  boolean showQuality = true;
+  boolean showConsensus = true;
+
+  boolean colourAppliesToAllGroups = true;
+  ColourSchemeI globalColourScheme = null;
+  boolean conservationColourSelected = false;
+  boolean abovePIDThreshold = false;
+
+  SequenceGroup selectionGroup;
+
+  int charHeight;
+  int charWidth;
+  int wrappedWidth;
+
+  Font font = new Font("SansSerif", Font.PLAIN, 10);
+  boolean validCharWidth = true;
+  AlignmentI alignment;
+
+  ColumnSelection colSel = new ColumnSelection();
+
+  int threshold;
+  int increment;
+
+  NJTree currentTree = null;
+
+  boolean scaleAboveWrapped = true;
+  boolean scaleLeftWrapped = true;
+  boolean scaleRightWrapped = true;
+
+  // The following vector holds the features which are
+ // currently visible, in the correct order or rendering
+  Hashtable featuresDisplayed;
+
+  boolean hasHiddenColumns = false;
+  boolean hasHiddenRows = false;
+  boolean showHiddenMarkers = true;
+
+
+  public Vector vconsensus;
+  AlignmentAnnotation consensus;
+  AlignmentAnnotation conservation;
+  AlignmentAnnotation quality;
+
+  boolean autocalculateConsensus = true;
+
+  public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
+
+  private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);
+
+  boolean ignoreGapsInConsensusCalculation = false;
+
+  jalview.bin.JalviewLite applet;
+
+  boolean MAC = false;
+
+  public AlignViewport(AlignmentI al, JalviewLite applet)
+  {
+    this.applet = applet;
+    setAlignment(al);
+    this.startRes = 0;
+    this.endRes = al.getWidth() - 1;
+    this.startSeq = 0;
+    this.endSeq = al.getHeight() - 1;
+    setFont(font);
+
+    if(System.getProperty("os.name").startsWith("Mac"))
+      MAC = true;
+
+    if (applet != null)
+    {
+      String param = applet.getParameter("showFullId");
+      if (param != null)
+      {
+        showJVSuffix = Boolean.valueOf(param).booleanValue();
+      }
+
+      param = applet.getParameter("showAnnotation");
+      if (param != null)
+      {
+        showAnnotation = Boolean.valueOf(param).booleanValue();
+      }
+
+      param = applet.getParameter("showConservation");
+      if (param != null)
+      {
+        showConservation = Boolean.valueOf(param).booleanValue();
+      }
+
+      param = applet.getParameter("showQuality");
+      if (param != null)
+      {
+        showQuality = Boolean.valueOf(param).booleanValue();
+      }
+
+      param = applet.getParameter("showConsensus");
+      if (param != null)
+      {
+        showConsensus = Boolean.valueOf(param).booleanValue();
+      }
+    }
+    // We must set conservation and consensus before setting colour,
+    // as Blosum and Clustal require this to be done
+    updateConservation();
+    updateConsensus();
+
+
+    if (applet != null)
+    {
+      String colour = applet.getParameter("defaultColour");
+
+      if(colour == null)
+      {
+        colour = applet.getParameter("userDefinedColour");
+        if(colour !=null)
+          colour = "User Defined";
+      }
+
+      if(colour != null)
+      {
+        globalColourScheme = ColourSchemeProperty.getColour(alignment, colour);
+        if (globalColourScheme != null)
+        {
+          globalColourScheme.setConsensus(vconsensus);
+        }
+      }
+
+      if(applet.getParameter("userDefinedColour")!=null)
+      {
+        ((UserColourScheme)globalColourScheme).parseAppletParameter(
+            applet.getParameter("userDefinedColour"));
+      }
+
+
+    }
+  }
+
+  public void showSequenceFeatures(boolean b)
+  {
+    showSequenceFeatures = b;
+  }
+
+  public boolean getShowSequenceFeatures()
+  {
+    return showSequenceFeatures;
+  }
+
+
+  public void updateConservation()
+  {
+    if(alignment.isNucleotide())
+          return;
+
+    Conservation cons = new jalview.analysis.Conservation("All",
+        jalview.schemes.ResidueProperties.propHash, 3,
+        alignment.getSequences(), 0,
+        alignment.getWidth() - 1);
+    cons.calculate();
+    cons.verdict(false, ConsPercGaps);
+    cons.findQuality();
+    int alWidth = alignment.getWidth();
+    Annotation[] annotations = new Annotation[alWidth];
+    Annotation[] qannotations = new Annotation[alWidth];
+    String sequence = cons.getConsSequence().getSequence();
+    float minR, minG, minB, maxR, maxG, maxB;
+    minR = 0.3f;
+    minG = 0.0f;
+    minB = 0f;
+    maxR = 1.0f - minR;
+    maxG = 0.9f - minG;
+    maxB = 0f - minB; // scalable range for colouring both Conservation and Quality
+    float min = 0f;
+    float max = 11f;
+    float qmin = cons.qualityRange[0].floatValue();
+    float qmax = cons.qualityRange[1].floatValue();
+
+    for (int i = 0; i < alWidth; i++)
+    {
+      float value = 0;
+      try
+      {
+        value = Integer.parseInt(sequence.charAt(i) + "");
+      }
+      catch (Exception ex)
+      {
+        if (sequence.charAt(i) == '*')
+        {
+          value = 11;
+        }
+        if (sequence.charAt(i) == '+')
+        {
+          value = 10;
+        }
+      }
+      float vprop = value - min;
+      vprop /= max;
+
+      annotations[i] = new Annotation(sequence.charAt(i) + "",
+                                      "", ' ', value,
+                                      new Color(minR + maxR * vprop,
+                                                minG + maxG * vprop,
+                                                minB + maxB * vprop));
+      // Quality calc
+      value = ( (Double) cons.quality.elementAt(i)).floatValue();
+      vprop = value - qmin;
+      vprop /= qmax;
+      qannotations[i] = new Annotation(" ",
+                                       String.valueOf(value), ' ', value,
+                                       new
+                                       Color(minR + maxR * vprop,
+                                             minG + maxG * vprop,
+                                             minB + maxB * vprop));
+    }
+
+    if (conservation == null)
+    {
+      conservation = new AlignmentAnnotation("Conservation",
+                                             "Conservation of total alignment less than " +
+                                             ConsPercGaps + "% gaps",
+                                             annotations,
+                                             0f, // cons.qualityRange[0].floatValue(),
+                                             11f, // cons.qualityRange[1].floatValue()
+                                             AlignmentAnnotation.BAR_GRAPH);
+      if (showConservation)
+      {
+        alignment.addAnnotation(conservation);
+      }
+      quality = new AlignmentAnnotation("Quality",
+                                        "Alignment Quality based on Blosum62 scores",
+                                        qannotations,
+                                        cons.qualityRange[0].floatValue(),
+                                        cons.qualityRange[1].floatValue(),
+                                        AlignmentAnnotation.BAR_GRAPH);
+      if (showQuality)
+      {
+        alignment.addAnnotation(quality);
+      }
+    }
+    else
+    {
+      conservation.annotations = annotations;
+      quality.annotations = qannotations;
+      quality.graphMax = cons.qualityRange[1].floatValue();
+    }
+
+  }
+
+  public void updateConsensus()
+  {
+    Annotation[] annotations = new Annotation[alignment.getWidth()];
+
+    // this routine prevents vconsensus becoming a new object each time
+    // consenus is calculated. Important for speed of Blosum62
+    // and PID colouring of alignment
+    if (vconsensus == null)
+    {
+      vconsensus = alignment.getAAFrequency();
+    }
+    else
+    {
+      Vector temp = alignment.getAAFrequency();
+      vconsensus.removeAllElements();
+      Enumeration e = temp.elements();
+      while (e.hasMoreElements())
+      {
+        vconsensus.addElement(e.nextElement());
+      }
+    }
+    Hashtable hash = null;
+    for (int i = 0; i < alignment.getWidth(); i++)
+    {
+      hash = (Hashtable) vconsensus.elementAt(i);
+      float value = 0;
+      if(ignoreGapsInConsensusCalculation)
+        value = ((Float)hash.get("pid_nogaps")).floatValue();
+      else
+        value = ((Float)hash.get("pid_gaps")).floatValue();
+
+      String maxRes = hash.get("maxResidue").toString();
+      String mouseOver = hash.get("maxResidue") + " ";
+      if (maxRes.length() > 1)
+      {
+        mouseOver = "[" + maxRes + "] ";
+        maxRes = "+";
+      }
+
+
+      mouseOver += (int) value + "%";
+      annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);
+
+    }
+
+    if (consensus == null)
+    {
+      consensus = new AlignmentAnnotation("Consensus",
+                                          "PID", annotations, 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+      if (showConsensus)
+      {
+        alignment.addAnnotation(consensus);
+      }
+    }
+    else
+    {
+      consensus.annotations = annotations;
+    }
+
+    if(globalColourScheme!=null)
+          globalColourScheme.setConsensus(vconsensus);
+
+  }
+  /**
+   * get the consensus sequence as displayed under the PID consensus annotation row.
+   * @return consensus sequence as a new sequence object
+   */
+  /**
+   * get the consensus sequence as displayed under the PID consensus annotation row.
+   * @return consensus sequence as a new sequence object
+   */
+  public SequenceI getConsensusSeq() {
+    if (consensus==null)
+      updateConsensus();
+    if (consensus==null)
+      return null;
+    StringBuffer seqs=new StringBuffer();
+    for (int i=0; i<consensus.annotations.length; i++) {
+      if (consensus.annotations[i]!=null) {
+        if (consensus.annotations[i].description.charAt(0) == '[')
+          seqs.append(consensus.annotations[i].description.charAt(1));          
+        else
+          seqs.append(consensus.annotations[i].displayCharacter);          
+      }
+    }
+    SequenceI sq = new Sequence("Consensus", seqs.toString());
+    sq.setDescription("Percentage Identity Consensus "+((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
+    return sq;
+  }
+  public SequenceGroup getSelectionGroup()
+  {
+    return selectionGroup;
+  }
+
+  public void setSelectionGroup(SequenceGroup sg)
+  {
+    selectionGroup = sg;
+  }
+
+  public boolean getConservationSelected()
+  {
+    return conservationColourSelected;
+  }
+
+  public void setConservationSelected(boolean b)
+  {
+    conservationColourSelected = b;
+  }
+
+  public boolean getAbovePIDThreshold()
+  {
+    return abovePIDThreshold;
+  }
+
+  public void setAbovePIDThreshold(boolean b)
+  {
+    abovePIDThreshold = b;
+  }
+
+  public int getStartRes()
+  {
+    return startRes;
+  }
+
+  public int getEndRes()
+  {
+    return endRes;
+  }
+
+  public int getStartSeq()
+  {
+    return startSeq;
+  }
+
+  public void setGlobalColourScheme(ColourSchemeI cs)
+  {
+    globalColourScheme = cs;
+  }
+
+  public ColourSchemeI getGlobalColourScheme()
+  {
+    return globalColourScheme;
+  }
+
+  public void setStartRes(int res)
+  {
+    this.startRes = res;
+  }
+
+  public void setStartSeq(int seq)
+  {
+    this.startSeq = seq;
+  }
+
+  public void setEndRes(int res)
+  {
+    if (res > alignment.getWidth() - 1)
+    {
+      // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));
+      res = alignment.getWidth() - 1;
+    }
+    if (res < 0)
+    {
+      res = 0;
+    }
+    this.endRes = res;
+  }
+
+  public void setEndSeq(int seq)
+  {
+    if (seq > alignment.getHeight())
+    {
+      seq = alignment.getHeight();
+    }
+    if (seq < 0)
+    {
+      seq = 0;
+    }
+    this.endSeq = seq;
+  }
+
+  public int getEndSeq()
+  {
+    return endSeq;
+  }
+
+  java.awt.Frame nullFrame;
+  public void setFont(Font f)
+  {
+    font = f;
+    if(nullFrame == null)
+    {
+      nullFrame = new java.awt.Frame();
+      nullFrame.addNotify();
+    }
+
+    java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);
+    setCharHeight(fm.getHeight());
+    charWidth = fm.charWidth('M');
+  }
+
+  public Font getFont()
+  {
+    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 setThreshold(int thresh)
+  {
+    threshold = thresh;
+  }
+
+  public int getThreshold()
+  {
+    return threshold;
+  }
+
+  public void setIncrement(int inc)
+  {
+    increment = inc;
+  }
+
+  public int getIncrement()
+  {
+    return increment;
+  }
+
+  public void setHiddenColumns(ColumnSelection colsel)
+  {
+    this.colSel = colsel;
+    if(colSel.getHiddenColumns()!=null)
+      hasHiddenColumns = true;
+  }
+
+  public ColumnSelection getColumnSelection()
+  {
+    return colSel;
+  }
+
+  public void resetSeqLimits(int height)
+  {
+    setEndSeq(height / getCharHeight());
+  }
+
+  public void setCurrentTree(NJTree tree)
+  {
+    currentTree = tree;
+  }
+
+  public NJTree getCurrentTree()
+  {
+    return currentTree;
+  }
+
+  public void setColourAppliesToAllGroups(boolean b)
+  {
+    colourAppliesToAllGroups = b;
+  }
+
+  public boolean getColourAppliesToAllGroups()
+  {
+    return colourAppliesToAllGroups;
+  }
+
+  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();
+    if (globalColourScheme!=null)
+    {
+      globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
+          ignoreGapsInConsensusCalculation);
+
+    }
+  }
+
+  /**
+   * Property change listener for changes in alignment
+   *
+   * @param listener DOCUMENT ME!
+   */
+  public void addPropertyChangeListener(
+      java.beans.PropertyChangeListener listener)
+  {
+      changeSupport.addPropertyChangeListener(listener);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param listener DOCUMENT ME!
+   */
+  public void removePropertyChangeListener(
+      java.beans.PropertyChangeListener listener)
+  {
+      changeSupport.removePropertyChangeListener(listener);
+  }
+
+  /**
+   * Property change listener for changes in alignment
+   *
+   * @param prop DOCUMENT ME!
+   * @param oldvalue DOCUMENT ME!
+   * @param newvalue DOCUMENT ME!
+   */
+  public void firePropertyChange(String prop, Object oldvalue, Object newvalue)
+  {
+      changeSupport.firePropertyChange(prop, oldvalue, newvalue);
+  }
+
+
+
+  public boolean getIgnoreGapsConsensus()
+  {
+    return ignoreGapsInConsensusCalculation;
+  }
+  public void hideSelectedColumns()
+  {
+    if (colSel.size() < 1)
+      return;
+
+    colSel.hideSelectedColumns();
+    setSelectionGroup(null);
+
+    hasHiddenColumns = true;
+  }
+
+  public void invertColumnSelection()
+  {
+    int column;
+    for (int i = 0; i < alignment.getWidth(); i++)
+    {
+      column = i;
+
+      if (colSel.contains(column))
+        colSel.removeElement(column);
+      else
+        colSel.addElement(column);
+
+    }
+  }
+
+
+  public void hideColumns(int start, int end)
+  {
+    if(start==end)
+      colSel.hideColumns(start);
+    else
+      colSel.hideColumns(start, end);
+
+    hasHiddenColumns = true;
+  }
+
+  public void hideSequence(SequenceI seq)
+  {
+    if(seq!=null)
+    {
+      alignment.getHiddenSequences().hideSequence(seq);
+      hasHiddenRows = true;
+      firePropertyChange("alignment", null, alignment.getSequences());
+    }
+  }
+
+  public void hideAllSelectedSeqs()
+  {
+    if (selectionGroup == null)
+      return;
+
+    SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
+
+    for (int i = 0; i < seqs.length; i++)
+    {
+      alignment.getHiddenSequences().hideSequence(seqs[i]);
+    }
+    firePropertyChange("alignment", null, alignment.getSequences());
+    hasHiddenRows = true;
+    setSelectionGroup(null);
+  }
+
+  public void showColumn(int col)
+  {
+    colSel.revealHiddenColumns(col);
+    if(colSel.getHiddenColumns()==null)
+      hasHiddenColumns = false;
+  }
+
+  public void showAllHiddenColumns()
+  {
+    colSel.revealAllHiddenColumns();
+    hasHiddenColumns = false;
+  }
+
+  public void showAllHiddenSeqs()
+  {
+    if(alignment.getHiddenSequences().getSize()>0)
+    {
+      if(selectionGroup==null)
+      {
+        selectionGroup = new SequenceGroup();
+        selectionGroup.setEndRes(alignment.getWidth()-1);
+      }
+      Vector tmp = alignment.getHiddenSequences().showAll();
+      for(int t=0; t<tmp.size(); t++)
+      {
+        selectionGroup.addSequence(
+            (SequenceI)tmp.elementAt(t), false
+            );
+      }
+      firePropertyChange("alignment", null, alignment.getSequences());
+      hasHiddenRows = false;
+    }
+  }
+
+  public int adjustForHiddenSeqs(int alignmentIndex)
+  {
+    return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);
+  }
+
+  /**
+   * This method returns the a new SequenceI [] with
+   * the selection sequence and start and end points adjusted
+   * @return String[]
+   */
+  public SequenceI[] getSelectionAsNewSequence()
+  {
+    SequenceI[] sequences;
+
+    if (selectionGroup == null)
+      sequences = alignment.getSequencesArray();
+    else
+      sequences = selectionGroup.getSelectionAsNewSequences(alignment);
+
+    return sequences;
+  }
+
+  /**
+   * This method returns the visible alignment as text, as
+   * seen on the GUI, ie if columns are hidden they will not
+   * be returned in the result.
+   * Use this for calculating trees, PCA, redundancy etc on views
+   * which contain hidden columns.
+   * @return String[]
+   */
+  public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)
+  {
+    CigarArray selection=null;
+    SequenceI [] seqs= null;
+    int i, iSize;
+    int start = 0, end = 0;
+    if(selectedRegionOnly && selectionGroup!=null)
+    {
+      iSize = selectionGroup.getSize(false);
+      seqs = selectionGroup.getSequencesInOrder(alignment);
+      start = selectionGroup.getStartRes();
+      end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor
+    }
+    else
+    {
+      iSize = alignment.getHeight();
+      seqs = alignment.getSequencesArray();
+      end = alignment.getWidth()-1;
+    }
+    SeqCigar[] selseqs = new SeqCigar[iSize];
+    for(i=0; i<iSize; i++)
+    {
+      selseqs[i] = new SeqCigar(seqs[i], start, end);
+    }
+    selection=new CigarArray(selseqs);
+    // now construct the CigarArray operations
+    if (hasHiddenColumns) {
+      Vector regions = colSel.getHiddenColumns();
+      int [] region;
+      int hideStart, hideEnd;
+      int last=start;
+      for (int j = 0; last<end & j < regions.size(); j++)
+      {
+        region = (int[]) regions.elementAt(j);
+        hideStart = region[0];
+        hideEnd = region[1];
+        // edit hidden regions to selection range
+        if(hideStart<last) {
+          if (hideEnd > last)
+          {
+            hideStart = last;
+          } else
+            continue;
+        }
+
+        if (hideStart>end)
+          break;
+
+        if (hideEnd>end)
+          hideEnd=end;
+
+        if (hideStart>hideEnd)
+          break;
+        /**
+         * form operations...
+         */
+        if (last<hideStart)
+          selection.addOperation(CigarArray.M, hideStart-last);
+        selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);
+        last = hideEnd+1;
+      }
+      // Final match if necessary.
+      if (last<end)
+        selection.addOperation(CigarArray.M, end-last);
+    } else {
+      selection.addOperation(CigarArray.M, end-start);
+    }
+    return selection;
+  }
+  /**
+   * return a compact representation of the current alignment selection to
+   * pass to an analysis function
+   * @param selectedOnly boolean true to just return the selected view
+   * @return AlignmentView
+   */
+  jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {
+    // JBPNote:
+    // this is here because the AlignmentView constructor modifies the CigarArray
+    // object. Refactoring of Cigar and alignment view representation should
+    // be done to remove redundancy.
+    CigarArray aligview = getViewAsCigars(selectedOnly);
+    if (aligview!=null)
+      return new AlignmentView(aligview);
+    return null;
+  }
+  /**
+   * This method returns the visible alignment as text, as
+   * seen on the GUI, ie if columns are hidden they will not
+   * be returned in the result.
+   * Use this for calculating trees, PCA, redundancy etc on views
+   * which contain hidden columns.
+   * @return String[]
+   */
+  public String [] getViewAsString(boolean selectedRegionOnly)
+  {
+    String [] selection = null;
+    SequenceI [] seqs= null;
+    int i, iSize;
+    int start = 0, end = 0;
+    if(selectedRegionOnly && selectionGroup!=null)
+    {
+      iSize = selectionGroup.getSize(false);
+      seqs = selectionGroup.getSequencesInOrder(alignment);
+      start = selectionGroup.getStartRes();
+      end = selectionGroup.getEndRes()+1;
+    }
+    else
+    {
+      iSize = alignment.getHeight();
+      seqs = alignment.getSequencesArray();
+      end = alignment.getWidth();
+    }
+
+    selection = new String[iSize];
+
+
+    for(i=0; i<iSize; i++)
+    {
+      if (hasHiddenColumns)
+      {
+           StringBuffer visibleSeq = new StringBuffer();
+           Vector regions = colSel.getHiddenColumns();
+
+           int blockStart = start, blockEnd=end;
+           int [] region;
+           int hideStart, hideEnd;
+
+           for (int j = 0; j < regions.size(); j++)
+           {
+             region = (int[]) regions.elementAt(j);
+             hideStart = region[0];
+             hideEnd = region[1];
+
+             if(hideStart < start)
+             {
+               continue;
+             }
+
+             blockStart = Math.min(blockStart, hideEnd+1);
+             blockEnd = Math.min(blockEnd, hideStart);
+
+             if(blockStart>blockEnd)
+             {
+                break;
+             }
+
+
+             visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
+
+             blockStart = hideEnd+1;
+             blockEnd = end;
+           }
+
+           if(end>blockStart)
+             visibleSeq.append(seqs[i].getSequence(blockStart, end));
+
+           selection[i] = visibleSeq.toString();
+      }
+      else
+      {
+        selection[i] = seqs[i].getSequence(start, end);
+      }
+    }
+
+    return selection;
+  }
+
+  public boolean getShowHiddenMarkers()
+  {
+    return showHiddenMarkers;
+  }
+
+  public void setShowHiddenMarkers(boolean show)
+  {
+    showHiddenMarkers = show;
+  }
+
+
+}
index e0c327f..ae97aaa 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class AlignmentPanel extends Panel implements AdjustmentListener\r
-{\r
-\r
-  AlignViewport av;\r
-  OverviewPanel overviewPanel;\r
-  SeqPanel seqPanel;\r
-  IdPanel idPanel;\r
-  IdwidthAdjuster idwidthAdjuster;\r
-  public AlignFrame alignFrame;\r
-  ScalePanel scalePanel;\r
-  AnnotationPanel annotationPanel;\r
-  AnnotationLabels alabels;\r
-\r
-  // this value is set false when selection area being dragged\r
-  boolean fastPaint = true;\r
-\r
-  boolean MAC = false;\r
-\r
-  public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    if(System.getProperty("os.name").startsWith("Mac"))\r
-      MAC = true;\r
-\r
-    alignFrame = af;\r
-    this.av = av;\r
-    seqPanel = new SeqPanel(av, this);\r
-    idPanel = new IdPanel(av, this);\r
-    scalePanel = new ScalePanel(av, this);\r
-    idwidthAdjuster = new IdwidthAdjuster(this);\r
-    annotationPanel = new AnnotationPanel(this);\r
-    alabels = new AnnotationLabels(this);\r
-\r
-    setAnnotationVisible(av.showAnnotation);\r
-\r
-    idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
-    idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
-    annotationScroller.add(annotationPanel);\r
-    annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
-    scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
-    seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
-\r
-    fontChanged();\r
-    setScrollValues(0, 0);\r
-\r
-    hscroll.addAdjustmentListener(this);\r
-    vscroll.addAdjustmentListener(this);\r
-\r
-    addComponentListener(new ComponentAdapter()\r
-    {\r
-      public void componentResized(ComponentEvent evt)\r
-      {\r
-        setScrollValues(av.getStartRes(), av.getStartSeq());\r
-        repaint();\r
-      }\r
-    });\r
-\r
-    Dimension d = calculateIdWidth();\r
-    idPanel.idCanvas.setSize(d);\r
-\r
-    hscrollFillerPanel.setSize(d.width, annotationPanel.getSize().height);\r
-    annotationScroller.setSize(annotationPanel.getSize());\r
-\r
-    idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);\r
-    annotationSpaceFillerHolder.setSize(d.width,\r
-                                        annotationPanel.getSize().height);\r
-    alabels.setSize(d.width, annotationPanel.getSize().height);\r
-\r
-  }\r
-\r
-\r
-  public void fontChanged()\r
-  {\r
-    // set idCanvas bufferedImage to null\r
-    // to prevent drawing old image\r
-    idPanel.idCanvas.image =null;\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-\r
-    scalePanel.setSize(new Dimension(10, av.charHeight + fm.getDescent()));\r
-    idwidthAdjuster.setSize(new Dimension(10, av.charHeight + fm.getDescent()));\r
-\r
-    int ap = annotationPanel.adjustPanelHeight();\r
-    annotationPanel.repaint();\r
-    Dimension d = calculateIdWidth();\r
-    d.setSize(d.width + 4, seqPanel.seqCanvas.getSize().height);\r
-    alabels.setSize(d.width+4, ap );\r
-    idPanel.idCanvas.setSize(d);\r
-    hscrollFillerPanel.setSize(d);\r
-\r
-    validate();\r
-    repaint();\r
-\r
-    if(overviewPanel!=null)\r
-          overviewPanel.updateOverviewImage();\r
-  }\r
-\r
-  public void setIdWidth(int w, int h)\r
-  {\r
-    idPanel.idCanvas.setSize(w, h);\r
-    idPanelHolder.setSize(w, idPanelHolder.getSize().height);\r
-    alabels.setSize(w, alabels.getSize().height);\r
-    validate();\r
-  }\r
-\r
-  Dimension calculateIdWidth()\r
-  {\r
-    Frame frame = new Frame();\r
-    frame.addNotify();\r
-    Graphics g = frame.getGraphics();\r
-    if (g == null)\r
-    {\r
-      Frame f = new Frame();\r
-      f.addNotify();\r
-      g = f.getGraphics();\r
-    }\r
-\r
-    FontMetrics fm = g.getFontMetrics(av.font);\r
-    AlignmentI al = av.getAlignment();\r
-\r
-    int i = 0;\r
-    int idWidth = 0;\r
-    String id;\r
-    while (i < al.getHeight() && al.getSequenceAt(i) != null)\r
-    {\r
-      SequenceI s = al.getSequenceAt(i);\r
-      id = s.getDisplayId(av.getShowJVSuffix());\r
-\r
-      if (fm.stringWidth(id) > idWidth)\r
-      {\r
-        idWidth = fm.stringWidth(id);\r
-      }\r
-      i++;\r
-    }\r
-\r
-    // Also check annotation label widths\r
-    i = 0;\r
-    if (al.getAlignmentAnnotation() != null)\r
-    {\r
-      fm = g.getFontMetrics(frame.getFont());\r
-      while (i < al.getAlignmentAnnotation().length)\r
-      {\r
-        String label = al.getAlignmentAnnotation()[i].label;\r
-        if (fm.stringWidth(label) > idWidth)\r
-        {\r
-          idWidth = fm.stringWidth(label);\r
-        }\r
-        i++;\r
-      }\r
-    }\r
-\r
-    return new Dimension(idWidth, idPanel.idCanvas.getSize().height);\r
-  }\r
-\r
-  public void highlightSearchResults(SearchResults results)\r
-  {\r
-    seqPanel.seqCanvas.highlightSearchResults(results);\r
-\r
-   // do we need to scroll the panel?\r
-    if (results != null)\r
-    {\r
-      SequenceI seq = results.getResultSequence(0);\r
-      int seqIndex = av.alignment.findIndex(seq);\r
-      int start = seq.findIndex(results.getResultStart(0)) - 1;\r
-      int end = seq.findIndex(results.getResultEnd(0)) - 1;\r
-\r
-        if(!av.wrapAlignment)\r
-        {\r
-          if ( (av.getStartRes() > end)  || (av.getEndRes() < start) ||\r
-             ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))\r
-          {\r
-            if (start > av.alignment.getWidth() - hextent)\r
-            {\r
-              start = av.alignment.getWidth() - hextent;\r
-              if (start < 0)\r
-                start = 0;\r
-            }\r
-            if (seqIndex > av.alignment.getHeight() - vextent)\r
-            {\r
-              seqIndex = av.alignment.getHeight() - vextent;\r
-              if (seqIndex < 0)\r
-                seqIndex = 0;\r
-            }\r
-            setScrollValues(start, seqIndex);\r
-          }\r
-        }\r
-        else\r
-        {\r
-          int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.\r
-              seqCanvas.getSize().width);\r
-          if (start < av.getStartRes() || start > (av.getStartRes() + cwidth))\r
-          {\r
-            vscroll.setValue(start / cwidth);\r
-            av.startRes = vscroll.getValue() * cwidth;\r
-          }\r
-        }\r
-    }\r
-\r
-    repaint();\r
-  }\r
-\r
-  public OverviewPanel getOverviewPanel()\r
-  {\r
-    return overviewPanel;\r
-  }\r
-\r
-  public void setOverviewPanel(OverviewPanel op)\r
-  {\r
-    overviewPanel = op;\r
-  }\r
-\r
-  public void setAnnotationVisible(boolean b)\r
-  {\r
-    if (!av.wrapAlignment)\r
-    {\r
-      annotationSpaceFillerHolder.setVisible(b);\r
-      annotationScroller.setVisible(b);\r
-    }\r
-    validate();\r
-    repaint();\r
-  }\r
-\r
-  public void setWrapAlignment(boolean wrap)\r
-  {\r
-    av.startSeq = 0;\r
-    scalePanelHolder.setVisible(!wrap);\r
-\r
-\r
-    hscroll.setVisible(!wrap);\r
-    idwidthAdjuster.setVisible(!wrap);\r
-\r
-    if (wrap)\r
-    {\r
-      annotationScroller.setVisible(false);\r
-      annotationSpaceFillerHolder.setVisible(false);\r
-    }\r
-    else if (av.showAnnotation)\r
-    {\r
-      annotationScroller.setVisible(true);\r
-      annotationSpaceFillerHolder.setVisible(true);\r
-    }\r
-\r
-\r
-    idSpaceFillerPanel1.setVisible(!wrap);\r
-\r
-    fontChanged();//This is so that the scalePanel is resized correctly\r
-\r
-    validate();\r
-    repaint();\r
-\r
-  }\r
-\r
-\r
-  int hextent = 0;\r
-  int vextent = 0;\r
-\r
-  // return value is true if the scroll is valid\r
-  public boolean scrollUp(boolean up)\r
-  {\r
-    if (up)\r
-    {\r
-      if (vscroll.getValue() < 1)\r
-      {\r
-        return false;\r
-      }\r
-      setScrollValues(hscroll.getValue(), vscroll.getValue()-1);\r
-    }\r
-    else\r
-    {\r
-      if (vextent + vscroll.getValue() >= av.getAlignment().getHeight())\r
-      {\r
-        return false;\r
-      }\r
-      setScrollValues(hscroll.getValue(), vscroll.getValue()+1);\r
-    }\r
-    repaint();\r
-    return true;\r
-  }\r
-\r
-  public boolean scrollRight(boolean right)\r
-  {\r
-\r
-    if (right)\r
-    {\r
-      if (hscroll.getValue() < 1)\r
-      {\r
-        return false;\r
-      }\r
-      setScrollValues(hscroll.getValue()-1, vscroll.getValue());\r
-    }\r
-    else\r
-    {\r
-      if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())\r
-      {\r
-        return false;\r
-      }\r
-      setScrollValues(hscroll.getValue()+1, vscroll.getValue());\r
-    }\r
-\r
-    repaint();\r
-    return true;\r
-  }\r
-\r
-  public void setScrollValues(int x, int y)\r
-  {\r
-    av.setStartRes(x);\r
-    av.setStartSeq(y);\r
-    av.setEndRes(x + seqPanel.seqCanvas.getSize().width / av.getCharWidth() - 1);\r
-\r
-    hextent = seqPanel.seqCanvas.getSize().width / av.charWidth;\r
-    vextent = seqPanel.seqCanvas.getSize().height / av.charHeight;\r
-\r
-    if (hextent > av.alignment.getWidth())\r
-    {\r
-      hextent = av.alignment.getWidth();\r
-    }\r
-    if (vextent > av.alignment.getHeight())\r
-    {\r
-      vextent = av.alignment.getHeight();\r
-    }\r
-\r
-    if (hextent + x > av.getAlignment().getWidth())\r
-    {\r
-      x = av.getAlignment().getWidth() - hextent;\r
-    }\r
-\r
-    if (vextent + y > av.getAlignment().getHeight())\r
-    {\r
-      y = av.getAlignment().getHeight() - vextent;\r
-    }\r
-\r
-    if (y < 0)\r
-    {\r
-      y = 0;\r
-    }\r
-\r
-    if (x < 0)\r
-    {\r
-      x = 0;\r
-    }\r
-\r
-    int endSeq = y + vextent;\r
-    if (endSeq > av.alignment.getHeight())\r
-    {\r
-      endSeq = av.alignment.getHeight();\r
-    }\r
-\r
-    av.setEndSeq(endSeq);\r
-    hscroll.setValues(x, hextent, 0, av.getAlignment().getWidth());\r
-    vscroll.setValues(y, vextent, 0, av.getAlignment().getHeight());\r
-  }\r
-\r
-  public void adjustmentValueChanged(AdjustmentEvent evt)\r
-  {\r
-    int oldX = av.getStartRes();\r
-    int oldY = av.getStartSeq();\r
-\r
-\r
-    if (evt==null || evt.getSource() == hscroll)\r
-    {\r
-      int x = hscroll.getValue();\r
-      av.setStartRes(x);\r
-      av.setEndRes(x + seqPanel.seqCanvas.getSize().width / av.getCharWidth() -\r
-                   1);\r
-    }\r
-\r
-\r
-    if (evt==null || evt.getSource() == vscroll)\r
-    {\r
-      int offy = vscroll.getValue();\r
-      if (av.getWrapAlignment())\r
-      {\r
-        int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.\r
-            seqCanvas.getSize().width);\r
-        av.setStartRes(vscroll.getValue() * rowSize);\r
-        av.setEndRes( (vscroll.getValue() + 1) * rowSize);\r
-      }\r
-      else\r
-      {\r
-        av.setStartSeq(offy);\r
-        av.setEndSeq(offy +\r
-                     seqPanel.seqCanvas.getSize().height / av.getCharHeight());\r
-      }\r
-    }\r
-\r
-    if (overviewPanel != null)\r
-    {\r
-      overviewPanel.setBoxPosition();\r
-    }\r
-\r
-    int scrollX = av.startRes - oldX;\r
-    int scrollY = av.startSeq - oldY;\r
-\r
-    if (av.getWrapAlignment() || !fastPaint || MAC)\r
-    {\r
-      repaint();\r
-    }\r
-    else\r
-    {\r
-      // Make sure we're not trying to draw a panel\r
-      // larger than the visible window\r
-      if(scrollX>av.endRes-av.startRes)\r
-      {\r
-        scrollX = av.endRes - av.startRes;\r
-      }\r
-      else if(scrollX<av.startRes-av.endRes)\r
-        scrollX = av.startRes - av.endRes;\r
-\r
-      idPanel.idCanvas.fastPaint(scrollY);\r
-      seqPanel.seqCanvas.fastPaint(scrollX,\r
-                                   scrollY);\r
-\r
-      scalePanel.repaint();\r
-      if (av.getShowAnnotation())\r
-      {\r
-        annotationPanel.fastPaint(av.getStartRes() - oldX);\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    invalidate();\r
-    Dimension d = idPanel.idCanvas.getSize();\r
-    idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);\r
-    annotationSpaceFillerHolder.setSize(d.width,\r
-                                        annotationPanel.getSize().height);\r
-\r
-    alabels.setSize(d.width, annotationPanel.getSize().height);\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      int max = av.alignment.getWidth() /\r
-          seqPanel.seqCanvas.\r
-          getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width) +1;\r
-      vscroll.setMaximum(max);\r
-      vscroll.setUnitIncrement(1);\r
-      vscroll.setVisibleAmount(1);\r
-    }\r
-    else\r
-    {\r
-      setScrollValues(av.getStartRes(), av.getStartSeq());\r
-    }\r
-\r
-    alabels.repaint();\r
-\r
-    seqPanel.seqCanvas.repaint();\r
-    scalePanel.repaint();\r
-    annotationPanel.repaint();\r
-    idPanel.idCanvas.repaint();\r
-\r
-    if (getBounds() == g.getClipBounds())\r
-    {\r
-      if (overviewPanel != null)\r
-        overviewPanel.updateOverviewImage();\r
-    }\r
-\r
-  }\r
-\r
-  protected Panel sequenceHolderPanel = new Panel();\r
-  protected Scrollbar vscroll = new Scrollbar();\r
-  protected Scrollbar hscroll = new Scrollbar();\r
-  protected Panel seqPanelHolder = new Panel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  BorderLayout borderLayout3 = new BorderLayout();\r
-  protected Panel scalePanelHolder = new Panel();\r
-  protected Panel idPanelHolder = new Panel();\r
-  BorderLayout borderLayout5 = new BorderLayout();\r
-  protected Panel idSpaceFillerPanel1 = new Panel();\r
-  public Panel annotationSpaceFillerHolder = new Panel();\r
-  BorderLayout borderLayout6 = new BorderLayout();\r
-  BorderLayout borderLayout7 = new BorderLayout();\r
-  Panel hscrollHolder = new Panel();\r
-  BorderLayout borderLayout10 = new BorderLayout();\r
-  protected Panel hscrollFillerPanel = new Panel();\r
-  BorderLayout borderLayout11 = new BorderLayout();\r
-  public Panel annotationScroller = new Panel();\r
-  BorderLayout borderLayout4 = new BorderLayout();\r
-  BorderLayout borderLayout2 = new BorderLayout();\r
-\r
-  private void jbInit() throws Exception {\r
-      //  idPanelHolder.setPreferredSize(new Dimension(70, 10));\r
-      this.setLayout(borderLayout7);\r
-\r
-      //   sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));\r
-      sequenceHolderPanel.setLayout(borderLayout3);\r
-      seqPanelHolder.setLayout(borderLayout1);\r
-      scalePanelHolder.setBackground(Color.white);\r
-\r
-      // scalePanelHolder.setPreferredSize(new Dimension(10, 30));\r
-      scalePanelHolder.setLayout(borderLayout6);\r
-      idPanelHolder.setLayout(borderLayout5);\r
-      idSpaceFillerPanel1.setBackground(Color.white);\r
-\r
-      //  idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));\r
-      idSpaceFillerPanel1.setLayout(borderLayout11);\r
-      annotationSpaceFillerHolder.setBackground(Color.white);\r
-\r
-      //  annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));\r
-      annotationSpaceFillerHolder.setLayout(borderLayout4);\r
-      hscroll.setOrientation(Scrollbar.HORIZONTAL);\r
-      hscrollHolder.setLayout(borderLayout10);\r
-      hscrollFillerPanel.setBackground(Color.white);\r
-\r
-      //  hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));\r
-      hscrollHolder.setBackground(Color.white);\r
-\r
-      //    annotationScroller.setPreferredSize(new Dimension(10, 80));\r
-      //  this.setPreferredSize(new Dimension(220, 166));\r
-      seqPanelHolder.setBackground(Color.white);\r
-      idPanelHolder.setBackground(Color.white);\r
-      annotationScroller.setLayout(borderLayout2);\r
-      sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);\r
-      sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);\r
-      seqPanelHolder.add(vscroll, BorderLayout.EAST);\r
-      sequenceHolderPanel.add(annotationScroller, BorderLayout.SOUTH);\r
-\r
-      //  Panel3.add(secondaryPanelHolder,  BorderLayout.SOUTH);\r
-      this.add(idPanelHolder, BorderLayout.WEST);\r
-      idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);\r
-      idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);\r
-      this.add(hscrollHolder, BorderLayout.SOUTH);\r
-      hscrollHolder.add(hscroll, BorderLayout.CENTER);\r
-      hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);\r
-      this.add(sequenceHolderPanel, BorderLayout.CENTER);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+
+public class AlignmentPanel extends Panel implements AdjustmentListener
+{
+
+  AlignViewport av;
+  OverviewPanel overviewPanel;
+  SeqPanel seqPanel;
+  IdPanel idPanel;
+  IdwidthAdjuster idwidthAdjuster;
+  public AlignFrame alignFrame;
+  ScalePanel scalePanel;
+  AnnotationPanel annotationPanel;
+  AnnotationLabels alabels;
+
+  // this value is set false when selection area being dragged
+  boolean fastPaint = true;
+
+
+
+  public AlignmentPanel(AlignFrame af, final AlignViewport av)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+
+    alignFrame = af;
+    this.av = av;
+    seqPanel = new SeqPanel(av, this);
+    idPanel = new IdPanel(av, this);
+    scalePanel = new ScalePanel(av, this);
+    idwidthAdjuster = new IdwidthAdjuster(this);
+    annotationPanel = new AnnotationPanel(this);
+
+    sequenceHolderPanel.add(annotationPanel, BorderLayout.SOUTH);
+
+    alabels = new AnnotationLabels(this);
+
+    setAnnotationVisible(av.showAnnotation);
+
+    idPanelHolder.add(idPanel, BorderLayout.CENTER);
+    idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);
+    annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);
+    scalePanelHolder.add(scalePanel, BorderLayout.CENTER);
+    seqPanelHolder.add(seqPanel, BorderLayout.CENTER);
+
+    fontChanged();
+    setScrollValues(0, 0);
+
+    hscroll.addAdjustmentListener(this);
+    vscroll.addAdjustmentListener(this);
+
+    addComponentListener(new ComponentAdapter()
+    {
+      public void componentResized(ComponentEvent evt)
+      {
+        setScrollValues(av.getStartRes(), av.getStartSeq());
+        repaint();
+      }
+    });
+
+    Dimension d = calculateIdWidth();
+    idPanel.idCanvas.setSize(d);
+
+    hscrollFillerPanel.setSize(d.width, annotationPanel.getSize().height);
+
+    idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
+    annotationSpaceFillerHolder.setSize(d.width,
+                                        annotationPanel.getSize().height);
+    alabels.setSize(d.width, annotationPanel.getSize().height);
+
+  }
+
+
+  public void fontChanged()
+  {
+    // set idCanvas bufferedImage to null
+    // to prevent drawing old image
+    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 + fm.getDescent()));
+
+    annotationPanel.image = null;
+    int ap = annotationPanel.adjustPanelHeight();
+    annotationPanel.repaint();
+    Dimension d = calculateIdWidth();
+    d.setSize(d.width + 4, seqPanel.seqCanvas.getSize().height);
+    alabels.setSize(d.width+4, ap );
+    idPanel.idCanvas.setSize(d);
+    hscrollFillerPanel.setSize(d);
+
+    validate();
+    repaint();
+
+    if(overviewPanel!=null)
+          overviewPanel.updateOverviewImage();
+  }
+
+  public void setIdWidth(int w, int h)
+  {
+    idPanel.idCanvas.setSize(w, h);
+    idPanelHolder.setSize(w, idPanelHolder.getSize().height);
+    alabels.setSize(w, alabels.getSize().height);
+    validate();
+  }
+
+  Dimension calculateIdWidth()
+  {
+    if (av.nullFrame == null)
+    {
+      av.nullFrame = new Frame();
+      av.nullFrame.addNotify();
+    }
+
+    Graphics g = av.nullFrame.getGraphics();
+
+    FontMetrics fm = g.getFontMetrics(av.font);
+    AlignmentI al = av.getAlignment();
+
+    int i = 0;
+    int idWidth = 0;
+    String id;
+    while (i < al.getHeight() && al.getSequenceAt(i) != null)
+    {
+      SequenceI s = al.getSequenceAt(i);
+      id = s.getDisplayId(av.getShowJVSuffix());
+
+      if (fm.stringWidth(id) > idWidth)
+      {
+        idWidth = fm.stringWidth(id);
+      }
+      i++;
+    }
+
+    // Also check annotation label widths
+    i = 0;
+    if (al.getAlignmentAnnotation() != null)
+    {
+      fm = g.getFontMetrics(av.nullFrame.getFont());
+      while (i < al.getAlignmentAnnotation().length)
+      {
+        String label = al.getAlignmentAnnotation()[i].label;
+        if (fm.stringWidth(label) > idWidth)
+        {
+          idWidth = fm.stringWidth(label);
+        }
+        i++;
+      }
+    }
+
+    return new Dimension(idWidth, idPanel.idCanvas.getSize().height);
+  }
+
+  public void highlightSearchResults(SearchResults results)
+  {
+    seqPanel.seqCanvas.highlightSearchResults(results);
+
+   // do we need to scroll the panel?
+    if (results != null)
+    {
+      SequenceI seq = results.getResultSequence(0);
+      int seqIndex = av.alignment.findIndex(seq);
+      int start = seq.findIndex(results.getResultStart(0)) - 1;
+      int end = seq.findIndex(results.getResultEnd(0)) - 1;
+
+        if(!av.wrapAlignment)
+        {
+          if ( (av.getStartRes() > end)  || (av.getEndRes() < start) ||
+             ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
+          {
+            if (start > av.alignment.getWidth() - hextent)
+            {
+              start = av.alignment.getWidth() - hextent;
+              if (start < 0)
+                start = 0;
+            }
+            if (seqIndex > av.alignment.getHeight() - vextent)
+            {
+              seqIndex = av.alignment.getHeight() - vextent;
+              if (seqIndex < 0)
+                seqIndex = 0;
+            }
+            setScrollValues(start, seqIndex);
+          }
+        }
+        else
+        {
+          scrollToWrappedVisible(start);
+        }
+    }
+
+    repaint();
+  }
+
+  void scrollToWrappedVisible(int res)
+  {
+    int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
+    if (res <= av.getStartRes() || res >= (av.getStartRes() + cwidth))
+    {
+      vscroll.setValue(res / cwidth);
+      av.startRes = vscroll.getValue() * cwidth;
+    }
+  }
+
+
+  public OverviewPanel getOverviewPanel()
+  {
+    return overviewPanel;
+  }
+
+  public void setOverviewPanel(OverviewPanel op)
+  {
+    overviewPanel = op;
+  }
+
+  public void setAnnotationVisible(boolean b)
+  {
+    if (!av.wrapAlignment)
+    {
+      annotationSpaceFillerHolder.setVisible(b);
+      annotationPanel.setVisible(b);
+    }
+    validate();
+    repaint();
+  }
+
+  public void setWrapAlignment(boolean wrap)
+  {
+    av.startSeq = 0;
+    scalePanelHolder.setVisible(!wrap);
+
+
+    hscroll.setVisible(!wrap);
+    idwidthAdjuster.setVisible(!wrap);
+
+    if (wrap)
+    {
+      annotationPanel.setVisible(false);
+      annotationSpaceFillerHolder.setVisible(false);
+    }
+    else if (av.showAnnotation)
+    {
+      annotationPanel.setVisible(true);
+      annotationSpaceFillerHolder.setVisible(true);
+    }
+
+
+    idSpaceFillerPanel1.setVisible(!wrap);
+
+    fontChanged();//This is so that the scalePanel is resized correctly
+
+    validate();
+    repaint();
+
+  }
+
+
+  int hextent = 0;
+  int vextent = 0;
+
+  // return value is true if the scroll is valid
+  public boolean scrollUp(boolean up)
+  {
+    if (up)
+    {
+      if (vscroll.getValue() < 1)
+      {
+        return false;
+      }
+      setScrollValues(hscroll.getValue(), vscroll.getValue()-1);
+    }
+    else
+    {
+      if (vextent + vscroll.getValue() >= av.getAlignment().getHeight())
+      {
+        return false;
+      }
+      setScrollValues(hscroll.getValue(), vscroll.getValue()+1);
+    }
+
+    repaint();
+    return true;
+  }
+
+  public boolean scrollRight(boolean right)
+  {
+    if (!right)
+    {
+      if (hscroll.getValue() < 1)
+      {
+        return false;
+      }
+      setScrollValues(hscroll.getValue()-1, vscroll.getValue());
+    }
+    else
+    {
+      if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())
+      {
+        return false;
+      }
+      setScrollValues(hscroll.getValue()+1, vscroll.getValue());
+    }
+
+    repaint();
+    return true;
+  }
+
+  public void setScrollValues(int x, int y)
+  {
+    int width = av.alignment.getWidth();
+    int height = av.alignment.getHeight();
+
+    if(av.hasHiddenColumns)
+     width = av.getColumnSelection().findColumnPosition(width);
+
+    av.setStartRes(x);
+    av.setStartSeq(y);
+
+    av.setEndRes( (x + (seqPanel.seqCanvas.getSize().width / av.charWidth)) -1);
+
+    hextent = seqPanel.seqCanvas.getSize().width / av.charWidth;
+    vextent = seqPanel.seqCanvas.getSize().height / av.charHeight;
+
+    if (hextent > width)
+    {
+      hextent = width;
+    }
+
+    if (vextent > height)
+    {
+      vextent = height;
+    }
+
+    if ( (hextent + x) > width)
+    {
+      x = width - hextent;
+    }
+
+    if ( (vextent + y) > height)
+    {
+      y = height - vextent;
+    }
+
+    if (y < 0)
+    {
+      y = 0;
+    }
+
+    if (x < 0)
+    {
+      x = 0;
+    }
+
+    int endSeq = y + vextent;
+    if (endSeq > av.alignment.getHeight())
+    {
+      endSeq = av.alignment.getHeight();
+    }
+
+    av.setEndSeq(endSeq);
+    hscroll.setValues(x, hextent, 0, av.getAlignment().getWidth());
+    vscroll.setValues(y, vextent, 0, av.getAlignment().getHeight());
+
+    if(overviewPanel!=null)
+          overviewPanel.setBoxPosition();
+
+  }
+
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+    int oldX = av.getStartRes();
+    int oldY = av.getStartSeq();
+
+
+    if (evt==null || evt.getSource() == hscroll)
+    {
+      int x = hscroll.getValue();
+      av.setStartRes(x);
+      av.setEndRes(x + seqPanel.seqCanvas.getSize().width / av.getCharWidth() -
+                   1);
+    }
+
+
+    if (evt==null || evt.getSource() == vscroll)
+    {
+      int offy = vscroll.getValue();
+      if (av.getWrapAlignment())
+      {
+        int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.
+            seqCanvas.getSize().width);
+        av.setStartRes(vscroll.getValue() * rowSize);
+        av.setEndRes( (vscroll.getValue() + 1) * rowSize);
+      }
+      else
+      {
+        av.setStartSeq(offy);
+        av.setEndSeq(offy +
+                     seqPanel.seqCanvas.getSize().height / av.getCharHeight());
+      }
+    }
+
+    if (overviewPanel != null)
+    {
+      overviewPanel.setBoxPosition();
+    }
+
+    int scrollX = av.startRes - oldX;
+    int scrollY = av.startSeq - oldY;
+
+    if (av.getWrapAlignment() || !fastPaint || av.MAC)
+    {
+      repaint();
+    }
+    else
+    {
+      // Make sure we're not trying to draw a panel
+      // larger than the visible window
+      if(scrollX>av.endRes-av.startRes)
+      {
+        scrollX = av.endRes - av.startRes;
+      }
+      else if(scrollX<av.startRes-av.endRes)
+        scrollX = av.startRes - av.endRes;
+
+      idPanel.idCanvas.fastPaint(scrollY);
+      seqPanel.seqCanvas.fastPaint(scrollX,
+                                   scrollY);
+
+      scalePanel.repaint();
+      if (av.getShowAnnotation())
+      {
+        annotationPanel.fastPaint(av.getStartRes() - oldX);
+      }
+    }
+
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  public void paint(Graphics g)
+  {
+    invalidate();
+    Dimension d = idPanel.idCanvas.getSize();
+    idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
+    annotationSpaceFillerHolder.setSize(d.width,
+                                        annotationPanel.getSize().height);
+
+    alabels.setSize(d.width, annotationPanel.getSize().height);
+
+    if (av.getWrapAlignment())
+    {
+      int maxwidth = av.alignment.getWidth();
+
+      if (av.hasHiddenColumns)
+        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+      int max = maxwidth /
+          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width) +
+          1;
+
+      vscroll.setMaximum(max);
+      vscroll.setUnitIncrement(1);
+      vscroll.setVisibleAmount(1);
+    }
+    else
+    {
+      setScrollValues(av.getStartRes(), av.getStartSeq());
+    }
+
+    alabels.repaint();
+
+    seqPanel.seqCanvas.repaint();
+    scalePanel.repaint();
+    annotationPanel.repaint();
+    idPanel.idCanvas.repaint();
+
+    if (getBounds() == g.getClipBounds())
+    {
+      if (overviewPanel != null)
+        overviewPanel.updateOverviewImage();
+    }
+
+  }
+
+  protected Panel sequenceHolderPanel = new Panel();
+  protected Scrollbar vscroll = new Scrollbar();
+  protected Scrollbar hscroll = new Scrollbar();
+  protected Panel seqPanelHolder = new Panel();
+  BorderLayout borderLayout1 = new BorderLayout();
+  BorderLayout borderLayout3 = new BorderLayout();
+  protected Panel scalePanelHolder = new Panel();
+  protected Panel idPanelHolder = new Panel();
+  BorderLayout borderLayout5 = new BorderLayout();
+  protected Panel idSpaceFillerPanel1 = new Panel();
+  public Panel annotationSpaceFillerHolder = new Panel();
+  BorderLayout borderLayout6 = new BorderLayout();
+  BorderLayout borderLayout7 = new BorderLayout();
+  Panel hscrollHolder = new Panel();
+  BorderLayout borderLayout10 = new BorderLayout();
+  protected Panel hscrollFillerPanel = new Panel();
+  BorderLayout borderLayout11 = new BorderLayout();
+  BorderLayout borderLayout4 = new BorderLayout();
+  BorderLayout borderLayout2 = new BorderLayout();
+
+  private void jbInit() throws Exception {
+      //  idPanelHolder.setPreferredSize(new Dimension(70, 10));
+      this.setLayout(borderLayout7);
+
+      //   sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
+      sequenceHolderPanel.setLayout(borderLayout3);
+      seqPanelHolder.setLayout(borderLayout1);
+      scalePanelHolder.setBackground(Color.white);
+
+      // scalePanelHolder.setPreferredSize(new Dimension(10, 30));
+      scalePanelHolder.setLayout(borderLayout6);
+      idPanelHolder.setLayout(borderLayout5);
+      idSpaceFillerPanel1.setBackground(Color.white);
+
+      //  idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
+      idSpaceFillerPanel1.setLayout(borderLayout11);
+      annotationSpaceFillerHolder.setBackground(Color.white);
+
+      //  annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
+      annotationSpaceFillerHolder.setLayout(borderLayout4);
+      hscroll.setOrientation(Scrollbar.HORIZONTAL);
+      hscrollHolder.setLayout(borderLayout10);
+      hscrollFillerPanel.setBackground(Color.white);
+
+      //  hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
+      hscrollHolder.setBackground(Color.white);
+
+      //    annotationScroller.setPreferredSize(new Dimension(10, 80));
+      //  this.setPreferredSize(new Dimension(220, 166));
+      seqPanelHolder.setBackground(Color.white);
+      idPanelHolder.setBackground(Color.white);
+      sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
+      sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
+      seqPanelHolder.add(vscroll, BorderLayout.EAST);
+
+      //  Panel3.add(secondaryPanelHolder,  BorderLayout.SOUTH);
+      this.add(idPanelHolder, BorderLayout.WEST);
+      idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
+      idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
+      this.add(hscrollHolder, BorderLayout.SOUTH);
+      hscrollHolder.add(hscroll, BorderLayout.CENTER);
+      hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
+      this.add(sequenceHolderPanel, BorderLayout.CENTER);
+  }
+
+}
index 1c73f7b..9751702 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.appletgui;\r
-\r
-import java.awt.event.*;\r
-import java.awt.*;\r
-\r
-import jalview.schemes.*;\r
-import java.util.*;\r
-import jalview.datamodel.SequenceGroup;\r
-\r
-public class AnnotationColourChooser extends Panel implements ActionListener,\r
-    AdjustmentListener, ItemListener\r
-{\r
-  Frame frame;\r
-  AlignViewport av;\r
-  AlignmentPanel ap;\r
-  ColourSchemeI oldcs;\r
-  Hashtable oldgroupColours;\r
-  jalview.datamodel.AlignmentAnnotation currentAnnotation;\r
-  boolean adjusting = false;\r
-\r
-  public AnnotationColourChooser(AlignViewport av, AlignmentPanel ap)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-\r
-    oldcs = av.getGlobalColourScheme();\r
-    if (av.alignment.getGroups() != null)\r
-    {\r
-      oldgroupColours = new Hashtable();\r
-      Vector allGroups = ap.av.alignment.getGroups();\r
-      SequenceGroup sg;\r
-      for (int g = 0; g < allGroups.size(); g++)\r
-      {\r
-        sg = (SequenceGroup) allGroups.elementAt(g);\r
-        oldgroupColours.put(sg, sg.cs);\r
-      }\r
-    }\r
-    this.av = av;\r
-    this.ap = ap;\r
-\r
-    slider.addAdjustmentListener(this);\r
-\r
-    if (av.alignment.getAlignmentAnnotation() == null)\r
-      return;\r
-\r
-    if (oldcs instanceof AnnotationColourGradient)\r
-    {\r
-      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;\r
-      minColour.setBackground(acg.getMinColour());\r
-      maxColour.setBackground(acg.getMaxColour());\r
-    }\r
-    else\r
-    {\r
-      minColour.setBackground(Color.orange);\r
-      maxColour.setBackground(Color.red);\r
-    }\r
-\r
-    adjusting = true;\r
-    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if (av.alignment.getAlignmentAnnotation()[i].graph > 0)\r
-        annotations.addItem(av.alignment.getAlignmentAnnotation()[i].label);\r
-    }\r
-\r
-    threshold.addItem("No Threshold");\r
-    threshold.addItem("Above Threshold");\r
-    threshold.addItem("Below Threshold");\r
-\r
-    adjusting = false;\r
-\r
-    changeColour();\r
-\r
-    frame = new Frame();\r
-    frame.add(this);\r
-    jalview.bin.JalviewLite.addFrame(frame, "Colour by Annotation", 480, 145);\r
-    validate();\r
-  }\r
-\r
-  public AnnotationColourChooser()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    minColour.setLabel("Min Colour");\r
-    minColour.addActionListener(this);\r
-\r
-    maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    maxColour.setLabel("Max Colour");\r
-    maxColour.addActionListener(this);\r
-\r
-    ok.setLabel("OK");\r
-    ok.addActionListener(this);\r
-\r
-    cancel.setLabel("Cancel");\r
-    cancel.addActionListener(this);\r
-\r
-    this.setLayout(borderLayout1);\r
-    jPanel2.setLayout(flowLayout1);\r
-    annotations.addItemListener(this);\r
-\r
-    jPanel1.setBackground(Color.white);\r
-    jPanel2.setBackground(Color.white);\r
-    threshold.addItemListener(this);\r
-    jPanel3.setLayout(null);\r
-    thresholdValue.addActionListener(this);\r
-\r
-    slider.setBackground(Color.white);\r
-    slider.setEnabled(false);\r
-    slider.setBounds(new Rectangle(172, 7, 120, 16));\r
-    thresholdValue.setEnabled(false);\r
-    thresholdValue.setBounds(new Rectangle(295, 4, 83, 22));\r
-    thresholdValue.setColumns(10);\r
-    jPanel3.setBackground(Color.white);\r
-    currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    currentColours.setLabel("Use Original Colours");\r
-    currentColours.addItemListener(this);\r
-\r
-    threshold.setBounds(new Rectangle(19, 4, 141, 22));\r
-    jPanel1.add(ok);\r
-    jPanel1.add(cancel);\r
-    jPanel2.add(annotations);\r
-    jPanel2.add(currentColours);\r
-    jPanel2.add(minColour);\r
-    jPanel2.add(maxColour);\r
-    jPanel3.add(threshold);\r
-    jPanel3.add(slider);\r
-    jPanel3.add(thresholdValue);\r
-    this.add(jPanel2, java.awt.BorderLayout.NORTH);\r
-    this.add(jPanel3, java.awt.BorderLayout.CENTER);\r
-    this.add(jPanel1, java.awt.BorderLayout.SOUTH);\r
-  }\r
-\r
-  Choice annotations = new Choice();\r
-  Button minColour = new Button();\r
-  Button maxColour = new Button();\r
-  Button ok = new Button();\r
-  Button cancel = new Button();\r
-  Panel jPanel1 = new Panel();\r
-  Panel jPanel2 = new Panel();\r
-  Choice threshold = new Choice();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  Panel jPanel3 = new Panel();\r
-  Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);\r
-  TextField thresholdValue = new TextField(20);\r
-  Checkbox currentColours = new Checkbox();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource() == thresholdValue)\r
-    {\r
-      try\r
-      {\r
-        float f = new Float(thresholdValue.getText()).floatValue();\r
-        slider.setValue( (int) (f * 1000));\r
-        adjustmentValueChanged(null);\r
-      }\r
-      catch (NumberFormatException ex)\r
-      {}\r
-    }\r
-    else if (evt.getSource() == minColour)\r
-      minColour_actionPerformed(null);\r
-    else if (evt.getSource() == maxColour)\r
-      maxColour_actionPerformed(null);\r
-\r
-    else if (evt.getSource() == ok)\r
-    {\r
-      changeColour();\r
-      frame.setVisible(false);\r
-    }\r
-    else if (evt.getSource() == cancel)\r
-    {\r
-      reset();\r
-      ap.repaint();\r
-      frame.setVisible(false);\r
-    }\r
-\r
-    else\r
-      changeColour();\r
-  }\r
-\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if (evt.getSource() == currentColours)\r
-    {\r
-      if (currentColours.getState())\r
-      {\r
-        reset();\r
-      }\r
-\r
-      maxColour.setEnabled(!currentColours.getState());\r
-      minColour.setEnabled(!currentColours.getState());\r
-\r
-    }\r
-\r
-    changeColour();\r
-  }\r
-\r
-  public void adjustmentValueChanged(AdjustmentEvent evt)\r
-  {\r
-    if (!adjusting)\r
-    {\r
-      thresholdValue.setText( ( (float) slider.getValue() / 1000f) + "");\r
-      if (currentColours.getState()\r
-          && ! (av.getGlobalColourScheme() instanceof AnnotationColourGradient))\r
-      {\r
-        changeColour();\r
-      }\r
-\r
-      currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;\r
-      ap.repaint();\r
-    }\r
-  }\r
-\r
-  public void minColour_actionPerformed(Color newCol)\r
-  {\r
-    if (newCol != null)\r
-    {\r
-      minColour.setBackground(newCol);\r
-      minColour.repaint();\r
-      changeColour();\r
-    }\r
-    else\r
-      new UserDefinedColours(this, "Min Colour",\r
-                              minColour.getBackground());\r
-\r
-  }\r
-\r
-  public void maxColour_actionPerformed(Color newCol)\r
-  {\r
-    if (newCol != null)\r
-    {\r
-      maxColour.setBackground(newCol);\r
-      maxColour.repaint();\r
-      changeColour();\r
-    }\r
-    else\r
-      new UserDefinedColours(this, "Max Colour",\r
-                              maxColour.getBackground());\r
-  }\r
-\r
-\r
-  void changeColour()\r
-  {\r
-    // Check if combobox is still adjusting\r
-    if (adjusting)\r
-      return;\r
-\r
-    // We removed the non-graph annotations when filling the combobox\r
-    // so allow for them again here\r
-    int nograph = 0, graph = -1;\r
-    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if (av.alignment.getAlignmentAnnotation()[i].graph == 0)\r
-        nograph++;\r
-      else\r
-        graph++;\r
-\r
-      if (graph == annotations.getSelectedIndex())\r
-        break;\r
-    }\r
-\r
-    currentAnnotation = av.alignment.getAlignmentAnnotation()[graph + nograph];\r
-\r
-    int aboveThreshold = -1;\r
-    if (threshold.getSelectedItem().equals("Above Threshold"))\r
-      aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;\r
-    else if (threshold.getSelectedItem().equals("Below Threshold"))\r
-      aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;\r
-\r
-    slider.setEnabled(true);\r
-    thresholdValue.setEnabled(true);\r
-\r
-    if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)\r
-    {\r
-      slider.setEnabled(false);\r
-      thresholdValue.setEnabled(false);\r
-      thresholdValue.setText("");\r
-    }\r
-    else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD &&\r
-             currentAnnotation.threshold == null)\r
-    {\r
-      currentAnnotation.setThreshold(new jalview.datamodel.GraphLine\r
-                                     ( (currentAnnotation.graphMax -\r
-                                        currentAnnotation.graphMin) / 2f,\r
-                                      "Threshold",\r
-                                      Color.black));\r
-    }\r
-\r
-    if(aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)\r
-    {\r
-      adjusting = true;\r
-\r
-      slider.setMinimum( (int) (currentAnnotation.graphMin * 1000));\r
-      slider.setMaximum( (int) (currentAnnotation.graphMax * 1000));\r
-      slider.setValue( (int) (currentAnnotation.threshold.value * 1000));\r
-      thresholdValue.setText(currentAnnotation.threshold.value + "");\r
-      slider.setEnabled(true);\r
-      thresholdValue.setEnabled(true);\r
-      adjusting = false;\r
-    }\r
-\r
-    AnnotationColourGradient acg = null;\r
-    if (currentColours.getState())\r
-      acg = new AnnotationColourGradient(\r
-          currentAnnotation,\r
-          av.getGlobalColourScheme(), aboveThreshold);\r
-    else\r
-      acg =\r
-          new AnnotationColourGradient(\r
-              currentAnnotation,\r
-              minColour.getBackground(),\r
-              maxColour.getBackground(),\r
-              aboveThreshold);\r
-\r
-    av.setGlobalColourScheme(acg);\r
-\r
-    if (av.alignment.getGroups() != null)\r
-    {\r
-      Vector allGroups = ap.av.alignment.getGroups();\r
-      SequenceGroup sg;\r
-      for (int g = 0; g < allGroups.size(); g++)\r
-      {\r
-        sg = (SequenceGroup) allGroups.elementAt(g);\r
-\r
-        if (sg.cs == null)\r
-        {\r
-          continue;\r
-        }\r
-\r
-        if (currentColours.getState())\r
-          sg.cs = new AnnotationColourGradient(\r
-              currentAnnotation,\r
-              sg.cs, aboveThreshold);\r
-        else\r
-          sg.cs = new AnnotationColourGradient(\r
-              currentAnnotation,\r
-              minColour.getBackground(),\r
-              maxColour.getBackground(),\r
-              aboveThreshold);\r
-\r
-      }\r
-    }\r
-\r
-    ap.repaint();\r
-  }\r
-\r
-\r
-  void reset()\r
-  {\r
-    av.setGlobalColourScheme(oldcs);\r
-    if (av.alignment.getGroups() != null)\r
-    {\r
-      Vector allGroups = ap.av.alignment.getGroups();\r
-      SequenceGroup sg;\r
-      for (int g = 0; g < allGroups.size(); g++)\r
-      {\r
-        sg = (SequenceGroup) allGroups.elementAt(g);\r
-        sg.cs = (ColourSchemeI)oldgroupColours.get(sg);\r
-      }\r
-    }\r
-    ap.repaint();\r
-\r
-  }\r
-\r
-\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.appletgui;
+
+import java.awt.event.*;
+import java.awt.*;
+
+import jalview.schemes.*;
+import java.util.*;
+import jalview.datamodel.SequenceGroup;
+
+public class AnnotationColourChooser extends Panel implements ActionListener,
+    AdjustmentListener, ItemListener
+{
+  Frame frame;
+  AlignViewport av;
+  AlignmentPanel ap;
+  ColourSchemeI oldcs;
+  Hashtable oldgroupColours;
+  jalview.datamodel.AlignmentAnnotation currentAnnotation;
+  boolean adjusting = false;
+
+  public AnnotationColourChooser(AlignViewport av, AlignmentPanel ap)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {}
+
+    oldcs = av.getGlobalColourScheme();
+    if (av.alignment.getGroups() != null)
+    {
+      oldgroupColours = new Hashtable();
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.elementAt(g);
+        oldgroupColours.put(sg, sg.cs);
+      }
+    }
+    this.av = av;
+    this.ap = ap;
+
+    slider.addAdjustmentListener(this);
+
+    if (av.alignment.getAlignmentAnnotation() == null)
+      return;
+
+    if (oldcs instanceof AnnotationColourGradient)
+    {
+      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
+      minColour.setBackground(acg.getMinColour());
+      maxColour.setBackground(acg.getMaxColour());
+    }
+    else
+    {
+      minColour.setBackground(Color.orange);
+      maxColour.setBackground(Color.red);
+    }
+
+    adjusting = true;
+    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
+    {
+      if (av.alignment.getAlignmentAnnotation()[i].graph > 0)
+        annotations.addItem(av.alignment.getAlignmentAnnotation()[i].label);
+    }
+
+    threshold.addItem("No Threshold");
+    threshold.addItem("Above Threshold");
+    threshold.addItem("Below Threshold");
+
+    adjusting = false;
+
+    changeColour();
+
+    frame = new Frame();
+    frame.add(this);
+    jalview.bin.JalviewLite.addFrame(frame, "Colour by Annotation", 480, 145);
+    validate();
+  }
+
+  public AnnotationColourChooser()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    minColour.setLabel("Min Colour");
+    minColour.addActionListener(this);
+
+    maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    maxColour.setLabel("Max Colour");
+    maxColour.addActionListener(this);
+
+    ok.setLabel("OK");
+    ok.addActionListener(this);
+
+    cancel.setLabel("Cancel");
+    cancel.addActionListener(this);
+
+    this.setLayout(borderLayout1);
+    jPanel2.setLayout(flowLayout1);
+    annotations.addItemListener(this);
+
+    jPanel1.setBackground(Color.white);
+    jPanel2.setBackground(Color.white);
+    threshold.addItemListener(this);
+    jPanel3.setLayout(null);
+    thresholdValue.addActionListener(this);
+
+    slider.setBackground(Color.white);
+    slider.setEnabled(false);
+    slider.setBounds(new Rectangle(172, 7, 120, 16));
+    thresholdValue.setEnabled(false);
+    thresholdValue.setBounds(new Rectangle(295, 4, 83, 22));
+    thresholdValue.setColumns(10);
+    jPanel3.setBackground(Color.white);
+    currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    currentColours.setLabel("Use Original Colours");
+    currentColours.addItemListener(this);
+
+    threshold.setBounds(new Rectangle(19, 4, 141, 22));
+    jPanel1.add(ok);
+    jPanel1.add(cancel);
+    jPanel2.add(annotations);
+    jPanel2.add(currentColours);
+    jPanel2.add(minColour);
+    jPanel2.add(maxColour);
+    jPanel3.add(threshold);
+    jPanel3.add(slider);
+    jPanel3.add(thresholdValue);
+    this.add(jPanel2, java.awt.BorderLayout.NORTH);
+    this.add(jPanel3, java.awt.BorderLayout.CENTER);
+    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+  }
+
+  Choice annotations = new Choice();
+  Button minColour = new Button();
+  Button maxColour = new Button();
+  Button ok = new Button();
+  Button cancel = new Button();
+  Panel jPanel1 = new Panel();
+  Panel jPanel2 = new Panel();
+  Choice threshold = new Choice();
+  FlowLayout flowLayout1 = new FlowLayout();
+  Panel jPanel3 = new Panel();
+  Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
+  TextField thresholdValue = new TextField(20);
+  Checkbox currentColours = new Checkbox();
+  BorderLayout borderLayout1 = new BorderLayout();
+
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource() == thresholdValue)
+    {
+      try
+      {
+        float f = new Float(thresholdValue.getText()).floatValue();
+        slider.setValue( (int) (f * 1000));
+        adjustmentValueChanged(null);
+      }
+      catch (NumberFormatException ex)
+      {}
+    }
+    else if (evt.getSource() == minColour)
+      minColour_actionPerformed(null);
+    else if (evt.getSource() == maxColour)
+      maxColour_actionPerformed(null);
+
+    else if (evt.getSource() == ok)
+    {
+      changeColour();
+      frame.setVisible(false);
+    }
+    else if (evt.getSource() == cancel)
+    {
+      reset();
+      ap.repaint();
+      frame.setVisible(false);
+    }
+
+    else
+      changeColour();
+  }
+
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if (evt.getSource() == currentColours)
+    {
+      if (currentColours.getState())
+      {
+        reset();
+      }
+
+      maxColour.setEnabled(!currentColours.getState());
+      minColour.setEnabled(!currentColours.getState());
+
+    }
+
+    changeColour();
+  }
+
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+    if (!adjusting)
+    {
+      thresholdValue.setText( ( (float) slider.getValue() / 1000f) + "");
+      if (currentColours.getState()
+          && ! (av.getGlobalColourScheme() instanceof AnnotationColourGradient))
+      {
+        changeColour();
+      }
+
+      currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;
+      ap.repaint();
+    }
+  }
+
+  public void minColour_actionPerformed(Color newCol)
+  {
+    if (newCol != null)
+    {
+      minColour.setBackground(newCol);
+      minColour.repaint();
+      changeColour();
+    }
+    else
+      new UserDefinedColours(this, "Min Colour",
+                              minColour.getBackground());
+
+  }
+
+  public void maxColour_actionPerformed(Color newCol)
+  {
+    if (newCol != null)
+    {
+      maxColour.setBackground(newCol);
+      maxColour.repaint();
+      changeColour();
+    }
+    else
+      new UserDefinedColours(this, "Max Colour",
+                              maxColour.getBackground());
+  }
+
+
+  void changeColour()
+  {
+    // Check if combobox is still adjusting
+    if (adjusting)
+      return;
+
+    // We removed the non-graph annotations when filling the combobox
+    // so allow for them again here
+    int nograph = 0, graph = -1;
+    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
+    {
+      if (av.alignment.getAlignmentAnnotation()[i].graph == 0)
+        nograph++;
+      else
+        graph++;
+
+      if (graph == annotations.getSelectedIndex())
+        break;
+    }
+
+    currentAnnotation = av.alignment.getAlignmentAnnotation()[graph + nograph];
+
+    int aboveThreshold = -1;
+    if (threshold.getSelectedItem().equals("Above Threshold"))
+      aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+    else if (threshold.getSelectedItem().equals("Below Threshold"))
+      aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+
+    slider.setEnabled(true);
+    thresholdValue.setEnabled(true);
+
+    if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+    {
+      slider.setEnabled(false);
+      thresholdValue.setEnabled(false);
+      thresholdValue.setText("");
+    }
+    else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD &&
+             currentAnnotation.threshold == null)
+    {
+      currentAnnotation.setThreshold(new jalview.datamodel.GraphLine
+                                     ( (currentAnnotation.graphMax -
+                                        currentAnnotation.graphMin) / 2f,
+                                      "Threshold",
+                                      Color.black));
+    }
+
+    if(aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+    {
+      adjusting = true;
+
+      slider.setMinimum( (int) (currentAnnotation.graphMin * 1000));
+      slider.setMaximum( (int) (currentAnnotation.graphMax * 1000));
+      slider.setValue( (int) (currentAnnotation.threshold.value * 1000));
+      thresholdValue.setText(currentAnnotation.threshold.value + "");
+      slider.setEnabled(true);
+      thresholdValue.setEnabled(true);
+      adjusting = false;
+    }
+
+    AnnotationColourGradient acg = null;
+    if (currentColours.getState())
+      acg = new AnnotationColourGradient(
+          currentAnnotation,
+          av.getGlobalColourScheme(), aboveThreshold);
+    else
+      acg =
+          new AnnotationColourGradient(
+              currentAnnotation,
+              minColour.getBackground(),
+              maxColour.getBackground(),
+              aboveThreshold);
+
+    av.setGlobalColourScheme(acg);
+
+    if (av.alignment.getGroups() != null)
+    {
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.elementAt(g);
+
+        if (sg.cs == null)
+        {
+          continue;
+        }
+
+        if (currentColours.getState())
+          sg.cs = new AnnotationColourGradient(
+              currentAnnotation,
+              sg.cs, aboveThreshold);
+        else
+          sg.cs = new AnnotationColourGradient(
+              currentAnnotation,
+              minColour.getBackground(),
+              maxColour.getBackground(),
+              aboveThreshold);
+
+      }
+    }
+
+    ap.repaint();
+  }
+
+
+  void reset()
+  {
+    av.setGlobalColourScheme(oldcs);
+    if (av.alignment.getGroups() != null)
+    {
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.elementAt(g);
+        sg.cs = (ColourSchemeI)oldgroupColours.get(sg);
+      }
+    }
+    ap.repaint();
+
+  }
+
+
+
+}
index ae47b72..ae6ef37 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class AnnotationLabels\r
-    extends Panel implements ActionListener\r
-{\r
-  boolean active = false;\r
-  AlignmentPanel ap;\r
-  AlignViewport av;\r
-  boolean resizing = false;\r
-  int oldY, mouseX;\r
-  static String ADDNEW = "Add new row";\r
-  static String HIDE = "Hide this row";\r
-  static String DELETE = "Delete this row";\r
-  static String SHOWALL = "Show all hidden rows";\r
-  static String OUTPUT_TEXT = "Show Values In Textbox";\r
-  int selectedRow = 0;\r
-  int scrollOffset = 0;\r
-\r
-  public AnnotationLabels(AlignmentPanel ap)\r
-  {\r
-    this.ap = ap;\r
-    this.av = ap.av;\r
-    setLayout(null);\r
-    addMouseListener(new MouseAdapter()\r
-    {\r
-      public void mousePressed(MouseEvent evt)\r
-      {\r
-        doMousePressed(evt);\r
-      }\r
-    });\r
-  }\r
-\r
-  public AnnotationLabels(AlignViewport av)\r
-{\r
-  this.av = av;\r
-}\r
-\r
-\r
-  public void setScrollOffset(int y)\r
-  {\r
-    scrollOffset = y;\r
-    repaint();\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-\r
-    if (evt.getActionCommand().equals(HIDE))\r
-    {\r
-      aa[selectedRow].visible = false;\r
-    }\r
-    else if (evt.getActionCommand().equals(SHOWALL))\r
-    {\r
-      for (int i = 0; i < aa.length; i++)\r
-      {\r
-        aa[i].visible = true;\r
-      }\r
-    }\r
-    else if (evt.getActionCommand().equals(OUTPUT_TEXT))\r
-    {\r
-      CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);\r
-      Frame frame = new Frame();\r
-      frame.add(cap);\r
-      jalview.bin.JalviewLite.addFrame(frame,\r
-                                       ap.alignFrame.getTitle() + " - " +\r
-                                       aa[selectedRow].label, 500, 100);\r
-      cap.setText(aa[selectedRow].toString());\r
-    }\r
-\r
-    ap.annotationPanel.adjustPanelHeight();\r
-    setSize(getSize().width, ap.annotationPanel.getSize().height);\r
-    ap.validate();\r
-    ap.repaint();\r
-  }\r
-\r
-  public void doMousePressed(MouseEvent evt)\r
-  {\r
-    int y = evt.getY() - scrollOffset;\r
-    AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
-    int height = 0;\r
-    for (int i = 0; i < aa.length; i++)\r
-    {\r
-      if (!aa[i].visible)\r
-      {\r
-        continue;\r
-      }\r
-\r
-      height += aa[i].height;\r
-      if (y < height)\r
-      {\r
-        selectedRow = i;\r
-        break;\r
-      }\r
-    }\r
-\r
-    PopupMenu pop = new PopupMenu("Annotations");\r
-    MenuItem item = new MenuItem(HIDE);\r
-    item.addActionListener(this);\r
-    pop.add(item);\r
-    item = new MenuItem(SHOWALL);\r
-    item.addActionListener(this);\r
-    pop.add(item);\r
-    this.add(pop);\r
-    item = new MenuItem(OUTPUT_TEXT);\r
-    item.addActionListener(this);\r
-    pop.add(item);\r
-\r
-    if (aa[selectedRow].label.equals("Consensus"))\r
-    {\r
-      pop.addSeparator();\r
-      final CheckboxMenuItem cbmi = new CheckboxMenuItem(\r
-          "Ignore Gaps In Consensus",\r
-          ap.av.getIgnoreGapsConsensus());\r
-\r
-      cbmi.addItemListener(new ItemListener()\r
-      {\r
-        public void itemStateChanged(ItemEvent e)\r
-        {\r
-          ap.av.setIgnoreGapsConsensus(cbmi.getState());\r
-          ap.repaint();\r
-        }\r
-      });\r
-      pop.add(cbmi);\r
-    }\r
-\r
-     pop.show(this, evt.getX(), evt.getY());\r
-\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    drawComponent(g, getSize().width);\r
-  }\r
-\r
-  public void drawComponent(Graphics g, int width)\r
-  {\r
-    FontMetrics fm = g.getFontMetrics(g.getFont());\r
-    g.setColor(Color.white);\r
-    g.fillRect(0, 0, getSize().width, getSize().height);\r
-\r
-    g.translate(0, scrollOffset);\r
-    g.setColor(Color.black);\r
-\r
-    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-    int y = g.getFont().getSize();\r
-    int x = 0;\r
-\r
-    if (aa != null)\r
-    {\r
-      for (int i = 0; i < aa.length; i++)\r
-      {\r
-        if (!aa[i].visible)\r
-        {\r
-          continue;\r
-        }\r
-\r
-        x = width - fm.stringWidth(aa[i].label) - 3;\r
-\r
-        if (aa[i].graph>0)\r
-        {\r
-          y += (aa[i].height / 3);\r
-        }\r
-\r
-        g.drawString(aa[i].label, x, y);\r
-\r
-        if (aa[i].graph>0)\r
-        {\r
-          y += (2 * aa[i].height / 3);\r
-        }\r
-        else\r
-        {\r
-          y += aa[i].height;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Vector;
+
+import jalview.datamodel.*;
+
+public class AnnotationLabels
+    extends Panel implements ActionListener
+{
+  boolean active = false;
+  AlignmentPanel ap;
+  AlignViewport av;
+  boolean resizing = false;
+  int oldY, mouseX;
+  static String ADDNEW = "Add new row";
+  static String HIDE = "Hide this row";
+  static String DELETE = "Delete this row";
+  static String SHOWALL = "Show all hidden rows";
+  static String OUTPUT_TEXT = "Show Values In Textbox";
+  static String COPYCONS_SEQ = "Copy Consensus Sequence";
+  
+  int selectedRow = 0;
+  int scrollOffset = 0;
+
+  public AnnotationLabels(AlignmentPanel ap)
+  {
+    this.ap = ap;
+    this.av = ap.av;
+    setLayout(null);
+    addMouseListener(new MouseAdapter()
+    {
+      public void mousePressed(MouseEvent evt)
+      {
+        doMousePressed(evt);
+      }
+    });
+  }
+
+  public AnnotationLabels(AlignViewport av)
+{
+  this.av = av;
+}
+
+
+  public void setScrollOffset(int y)
+  {
+    scrollOffset = y;
+    repaint();
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+
+    if (evt.getActionCommand().equals(HIDE))
+    {
+      aa[selectedRow].visible = false;
+    }
+    else if (evt.getActionCommand().equals(SHOWALL))
+    {
+      for (int i = 0; i < aa.length; i++)
+      {
+        aa[i].visible = true;
+      }
+    }
+    else if (evt.getActionCommand().equals(OUTPUT_TEXT))
+    {
+      CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);
+      Frame frame = new Frame();
+      frame.add(cap);
+      jalview.bin.JalviewLite.addFrame(frame,
+                                       ap.alignFrame.getTitle() + " - " +
+                                       aa[selectedRow].label, 500, 100);
+      cap.setText(aa[selectedRow].toString());
+    }
+    else if (evt.getActionCommand().equals(COPYCONS_SEQ))
+    {
+      SequenceI cons=av.getConsensusSeq();
+      if (cons!=null)
+        copy_annotseqtoclipboard(cons);
+      
+    }
+    ap.annotationPanel.adjustPanelHeight();
+    setSize(getSize().width, ap.annotationPanel.getSize().height);
+    ap.validate();
+    ap.repaint();
+  }
+
+  public void doMousePressed(MouseEvent evt)
+  {
+    int y = evt.getY() - scrollOffset;
+    AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();
+    int height = 0;
+    for (int i = 0; i < aa.length; i++)
+    {
+      if (!aa[i].visible)
+      {
+        continue;
+      }
+
+      height += aa[i].height;
+      if (y < height)
+      {
+        selectedRow = i;
+        break;
+      }
+    }
+
+    PopupMenu pop = new PopupMenu("Annotations");
+    MenuItem item = new MenuItem(HIDE);
+    item.addActionListener(this);
+    pop.add(item);
+    item = new MenuItem(SHOWALL);
+    item.addActionListener(this);
+    pop.add(item);
+    this.add(pop);
+    item = new MenuItem(OUTPUT_TEXT);
+    item.addActionListener(this);
+    pop.add(item);
+
+    if (aa[selectedRow].label.equals("Consensus"))
+    {
+      pop.addSeparator();
+      final CheckboxMenuItem cbmi = new CheckboxMenuItem(
+          "Ignore Gaps In Consensus",
+          ap.av.getIgnoreGapsConsensus());
+
+      cbmi.addItemListener(new ItemListener()
+      {
+        public void itemStateChanged(ItemEvent e)
+        {
+          ap.av.setIgnoreGapsConsensus(cbmi.getState());
+          ap.repaint();
+        }
+      });
+      pop.add(cbmi);
+      final MenuItem cpcons=new MenuItem(COPYCONS_SEQ);
+      cpcons.addActionListener(this);
+      pop.add(cpcons);
+    }
+
+     pop.show(this, evt.getX(), evt.getY());
+
+  }
+/**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void copy_annotseqtoclipboard(SequenceI sq)
+    {
+      if (sq==null || sq.getLength()<1)
+        return;
+      jalview.appletgui.AlignFrame.copiedSequences = new StringBuffer();
+      jalview.appletgui.AlignFrame.copiedSequences.append(sq.getName() + "\t" +
+          sq.getStart() + "\t" +
+          sq.getEnd() + "\t" +
+          sq.getSequence() + "\n");
+      if (av.hasHiddenColumns)
+      {
+        jalview.appletgui.AlignFrame.copiedHiddenColumns=new Vector();
+        for(int i=0; i<av.getColumnSelection().getHiddenColumns().size(); i++)
+        {
+          int[] region = (int[])
+              av.getColumnSelection().getHiddenColumns().elementAt(i);
+
+          jalview.appletgui.AlignFrame.copiedHiddenColumns.addElement(new int[]{region[0],
+                            region[1]});
+        }
+      }
+    }
+
+  public void paint(Graphics g)
+  {
+    drawComponent(g, getSize().width);
+  }
+
+  public void drawComponent(Graphics g, int width)
+  {
+    g.setFont(av.getFont());
+    FontMetrics fm = g.getFontMetrics(av.getFont());
+    g.setColor(Color.white);
+    g.fillRect(0, 0, getSize().width, getSize().height);
+
+    g.translate(0, scrollOffset);
+    g.setColor(Color.black);
+
+    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+    int y = g.getFont().getSize();
+    int x = 0;
+
+    if (aa != null)
+    {
+      for (int i = 0; i < aa.length; i++)
+      {
+        if (!aa[i].visible)
+        {
+          continue;
+        }
+
+        x = width - fm.stringWidth(aa[i].label) - 3;
+
+        if (aa[i].graph>0)
+        {
+          y += (aa[i].height / 3);
+        }
+
+        g.drawString(aa[i].label, x, y);
+
+        if (aa[i].graph>0)
+        {
+          y += (2 * aa[i].height / 3);
+        }
+        else
+        {
+          y += aa[i].height;
+        }
+      }
+    }
+  }
+
+}
index cb638dd..9a029a7 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class AnnotationPanel\r
-    extends Panel implements AdjustmentListener\r
-{\r
-  AlignViewport av;\r
-  AlignmentPanel ap;\r
-  int activeRow = -1;\r
-\r
-  Vector activeRes;\r
-  static String HELIX = "Helix";\r
-  static String SHEET = "Sheet";\r
-  static String LABEL = "Label";\r
-  static String REMOVE = "Remove Annotation";\r
-  static String COLOUR = "Colour";\r
-  static Color HELIX_COLOUR = Color.red.darker();\r
-  static Color SHEET_COLOUR = Color.green.darker().darker();\r
-\r
-  Image image;\r
-  Graphics gg;\r
-  FontMetrics fm;\r
-  int imgWidth = 0;\r
-\r
-  boolean fastPaint = false;\r
-\r
-  public static int GRAPH_HEIGHT = 40;\r
-\r
-  public AnnotationPanel(AlignmentPanel ap)\r
-  {\r
-    this.ap = ap;\r
-    av = ap.av;\r
-    this.setLayout(null);\r
-    adjustPanelHeight();\r
-\r
-    addMouseMotionListener(new MouseMotionAdapter()\r
-    {\r
-      public void mouseMoved(MouseEvent evt)\r
-      {\r
-        doMouseMoved(evt);\r
-      }\r
-    });\r
-\r
-    // ap.annotationScroller.getVAdjustable().addAdjustmentListener( this );\r
-  }\r
-\r
-\r
-  public AnnotationPanel(AlignViewport av)\r
-  {\r
-    this.av = av;\r
-  }\r
-\r
-\r
-  public void adjustmentValueChanged(AdjustmentEvent evt)\r
-  {\r
-    ap.alabels.setScrollOffset( -evt.getValue());\r
-  }\r
-\r
-  public int adjustPanelHeight()\r
-  {\r
-    // setHeight of panels\r
-    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-\r
-\r
-    int height = 0;\r
-    if (aa != null)\r
-    {\r
-      for (int i = 0; i < aa.length; i++)\r
-      {\r
-        if (!aa[i].visible)\r
-        {\r
-          continue;\r
-        }\r
-\r
-        aa[i].height = 0;\r
-\r
-        if (aa[i].hasText)\r
-        {\r
-          aa[i].height += av.charHeight;\r
-        }\r
-        if (aa[i].hasIcons)\r
-        {\r
-          aa[i].height += 16;\r
-        }\r
-\r
-        if (aa[i].graph>0)\r
-        {\r
-          aa[i].height += GRAPH_HEIGHT;\r
-        }\r
-\r
-        if (aa[i].height == 0)\r
-        {\r
-          aa[i].height = 20;\r
-        }\r
-        height += aa[i].height;\r
-      }\r
-    }\r
-    else\r
-    {\r
-      height = 20;\r
-    }\r
-\r
-    this.setSize(getSize().width, height);\r
-    if(ap!=null)\r
-       ap.annotationScroller.setSize(getSize().width, height);\r
-\r
-\r
-    repaint();\r
-\r
-    return height;\r
-\r
-  }\r
-\r
-  public void addEditableColumn(int i)\r
-  {\r
-    if (activeRow == -1)\r
-    {\r
-      AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-      if(aa ==null)\r
-        return;\r
-\r
-      for (int j = 0; j < aa.length; j++)\r
-      {\r
-        if (aa[j].editable)\r
-        {\r
-          activeRow = j;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-\r
-    if (activeRes == null)\r
-    {\r
-      activeRes = new Vector();\r
-      activeRes.addElement(String.valueOf(i));\r
-      return;\r
-    }\r
-\r
-    activeRes.addElement(String.valueOf(i));\r
-  }\r
-\r
-  public void doMouseMoved(MouseEvent evt)\r
-  {\r
-    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-    if (aa == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    int row = -1;\r
-    int height = 0;\r
-    for (int i = 0; i < aa.length; i++)\r
-    {\r
-\r
-      if (aa[i].visible)\r
-      {\r
-        height += aa[i].height;\r
-      }\r
-\r
-      if (evt.getY() < height)\r
-      {\r
-        row = i;\r
-        break;\r
-      }\r
-    }\r
-\r
-    int res = evt.getX() / av.getCharWidth() + av.getStartRes();\r
-    if (row > -1 && res < aa[row].annotations.length && aa[row].annotations[res] != null)\r
-    {\r
-      StringBuffer text = new StringBuffer("Sequence position " + (res + 1) +\r
-                                           "  " +\r
-                                           aa[row].annotations[res].description);\r
-      ap.alignFrame.statusBar.setText(text.toString());\r
-    }\r
-  }\r
-\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;\r
-\r
-    if (image == null || imgWidth != image.getWidth(this))\r
-    {\r
-      image = createImage(imgWidth, ap.annotationPanel.getSize().height);\r
-      gg = image.getGraphics();\r
-      gg.setFont(av.getFont());\r
-      fm = gg.getFontMetrics();\r
-      fastPaint = false;\r
-    }\r
-\r
-    if (fastPaint)\r
-    {\r
-      g.drawImage(image, 0, 0, this);\r
-      fastPaint = false;\r
-      return;\r
-    }\r
-\r
-    drawComponent(gg, av.startRes, av.endRes + 1);\r
-    g.drawImage(image, 0, 0, this);\r
-  }\r
-\r
-  public void fastPaint(int horizontal)\r
-  {\r
-    if (horizontal == 0\r
-        || av.alignment.getAlignmentAnnotation() == null\r
-        || av.alignment.getAlignmentAnnotation().length < 1\r
-        )\r
-    {\r
-      repaint();\r
-      return;\r
-    }\r
-\r
-    gg.copyArea(0, 0, imgWidth, getSize().height, -horizontal * av.charWidth, 0);\r
-    int sr = av.startRes, er = av.endRes + 1, transX = 0;\r
-\r
-    if (horizontal > 0) // scrollbar pulled right, image to the left\r
-    {\r
-      transX = (er - sr - horizontal) * av.charWidth;\r
-      sr = er - horizontal;\r
-    }\r
-    else if (horizontal < 0)\r
-    {\r
-      er = sr - horizontal;\r
-    }\r
-\r
-    gg.translate(transX, 0);\r
-\r
-    drawComponent(gg, sr, er);\r
-\r
-    gg.translate( -transX, 0);\r
-\r
-    fastPaint = true;\r
-    repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param g DOCUMENT ME!\r
-   * @param startRes DOCUMENT ME!\r
-   * @param endRes DOCUMENT ME!\r
-   */\r
-  public void drawComponent(Graphics g, int startRes, int endRes)\r
-  {\r
-    g.setFont(av.getFont());\r
-\r
-    if (fm == null)\r
-      fm = g.getFontMetrics();\r
-\r
-\r
-      g.setColor(Color.white);\r
-      g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getSize().height);\r
-\r
-      if ((av.alignment.getAlignmentAnnotation() == null) ||\r
-              (av.alignment.getAlignmentAnnotation().length < 1))\r
-      {\r
-          g.setColor(Color.white);\r
-          g.fillRect(0, 0, getSize().width, getSize().height);\r
-          g.setColor(Color.black);\r
-          g.drawString("Alignment has no annotations", 20, 15);\r
-\r
-          return;\r
-      }\r
-\r
-      AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-\r
-      int j;\r
-      int x = 0;\r
-      int y = 0;\r
-      char[] lastSS = new char[aa.length];\r
-      int[] lastSSX = new int[aa.length];\r
-      int iconOffset = av.charHeight / 2;\r
-      boolean validRes = false;\r
-\r
-      boolean [] graphGroupDrawn = new boolean[aa.length];\r
-\r
-\r
-      //\u03B2 \u03B1\r
-      for (int i = 0; i < aa.length; i++)\r
-      {\r
-          AlignmentAnnotation row = aa[i];\r
-\r
-          if (!row.visible)\r
-          {\r
-              continue;\r
-          }\r
-\r
-\r
-\r
-          if (row.graph>0)\r
-          {\r
-              if(row.graphGroup>-1 && graphGroupDrawn[ row.graphGroup ] )\r
-                continue;\r
-\r
-              // this is so that we draw the characters below the graph\r
-              y += row.height;\r
-\r
-              if (row.hasText)\r
-              {\r
-                  y -= av.charHeight;\r
-              }\r
-          }\r
-\r
-          if (row.hasText)\r
-          {\r
-              iconOffset = av.charHeight / 2;\r
-          }\r
-          else\r
-          {\r
-              iconOffset = 0;\r
-          }\r
-\r
-          for (j = startRes; j < endRes; j++)\r
-          {\r
-              if ((row.annotations.length <= j) ||\r
-                      (row.annotations[j] == null))\r
-              {\r
-                  validRes = false;\r
-              }\r
-              else\r
-              {\r
-                  validRes = true;\r
-              }\r
-\r
-              x = (j - startRes) * av.charWidth;\r
-\r
-              if (activeRow == i)\r
-              {\r
-                  g.setColor(Color.red);\r
-\r
-                  if (activeRes != null)\r
-                  {\r
-                      for (int n = 0; n < activeRes.size(); n++)\r
-                      {\r
-                          int v = Integer.parseInt(activeRes.elementAt(n).toString());\r
-\r
-                          if (v == j)\r
-                          {\r
-                              g.fillRect((j - startRes) * av.charWidth, y,\r
-                                  av.charWidth, row.height);\r
-                          }\r
-                      }\r
-                  }\r
-              }\r
-\r
-              if (validRes &&\r
-                      (row.annotations[j].displayCharacter.length() > 0))\r
-              {\r
-\r
-                  int charOffset = (av.charWidth -\r
-                      fm.charWidth(row.annotations[j].displayCharacter.charAt(\r
-                              0))) / 2;\r
-                  g.setColor(row.annotations[j].colour);\r
-\r
-                  if (j == 0 || row.graph>0)\r
-                  {\r
-                      g.drawString(row.annotations[j].displayCharacter, x+charOffset,\r
-                          y + iconOffset + 3);\r
-                  }\r
-                  else if (((row.annotations[j - 1] == null) ||\r
-                          (!row.annotations[j].displayCharacter.equals(\r
-                           row.annotations[j - 1].displayCharacter))))\r
-                  {\r
-                      g.drawString(row.annotations[j].displayCharacter, x+charOffset,\r
-                          y + iconOffset + 3);\r
-                  }\r
-              }\r
-\r
-              if (row.hasIcons)\r
-              {\r
-                  if (!validRes ||\r
-                          (row.annotations[j].secondaryStructure != lastSS[i]))\r
-                  {\r
-                      switch (lastSS[i])\r
-                      {\r
-                      case 'H':\r
-                          g.setColor(HELIX_COLOUR);\r
-                          g.fillRoundRect(lastSSX[i], y + 4 + iconOffset,\r
-                              x - lastSSX[i], 7, 8, 8);\r
-\r
-                          break;\r
-\r
-                      case 'E':\r
-                          g.setColor(SHEET_COLOUR);\r
-                          g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
-                              x - lastSSX[i] - 4, 7);\r
-                          g.fillPolygon(new int[] { x - 4, x - 4, x },\r
-                              new int[]\r
-                              {\r
-                                  y + iconOffset, y + 14 + iconOffset,\r
-                                  y + 8 + iconOffset\r
-                              }, 3);\r
-\r
-                          break;\r
-\r
-\r
-                      default:\r
-                          g.setColor(Color.gray);\r
-                          g.fillRect(lastSSX[i], y + 6 + iconOffset,\r
-                              x - lastSSX[i], 2);\r
-\r
-                          break;\r
-                      }\r
-\r
-                      if (validRes)\r
-                      {\r
-                          lastSS[i] = row.annotations[j].secondaryStructure;\r
-                      }\r
-                      else\r
-                      {\r
-                          lastSS[i] = ' ';\r
-                      }\r
-\r
-                      lastSSX[i] = x;\r
-                  }\r
-              }\r
-          }\r
-\r
-          x += av.charWidth;\r
-\r
-          if (row.hasIcons)\r
-          {\r
-              switch (lastSS[i])\r
-              {\r
-              case 'H':\r
-                  g.setColor(HELIX_COLOUR);\r
-                  g.fillRoundRect(lastSSX[i], y + 4 + iconOffset,\r
-                      x - lastSSX[i], 7, 8, 8);\r
-\r
-                  break;\r
-\r
-              case 'E':\r
-                  g.setColor(SHEET_COLOUR);\r
-\r
-                  if (row.annotations.length > endRes\r
-                      && row.annotations[endRes].secondaryStructure != 'E')\r
-                  {\r
-                    g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
-                               x - lastSSX[i] - 4, 7);\r
-                    g.fillPolygon(new int[]\r
-                                  {x - 4, x - 4, x},\r
-                                  new int[]\r
-                                  {\r
-                                  y + iconOffset, y + 14 + iconOffset,\r
-                                  y + 7 + iconOffset\r
-                    }, 3);\r
-                  }\r
-                  else\r
-                    g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
-                               x - lastSSX[i], 7);\r
-\r
-                  break;\r
-\r
-              case 'C':\r
-                  break;\r
-\r
-              default:\r
-                  g.setColor(Color.gray);\r
-                  g.fillRect(lastSSX[i], y + 6 + iconOffset, x - lastSSX[i], 2);\r
-\r
-                  break;\r
-              }\r
-          }\r
-\r
-          if (row.graph>0)\r
-          {\r
-              if(row.graph == AlignmentAnnotation.LINE_GRAPH )\r
-              {\r
-                if(row.graphGroup>-1 && !graphGroupDrawn[row.graphGroup])\r
-                 {\r
-                   float groupmax=-999999, groupmin=9999999;\r
-                   for(int gg=0; gg<aa.length; gg++)\r
-                   {\r
-                     if(aa[gg].graphGroup!=row.graphGroup)\r
-                       continue;\r
-\r
-                     if(aa[gg]!=row)\r
-                       aa[gg].visible = false;\r
-\r
-                     if(aa[gg].graphMax>groupmax)\r
-                       groupmax = aa[gg].graphMax;\r
-                     if(aa[gg].graphMin<groupmin)\r
-                       groupmin = aa[gg].graphMin;\r
-                   }\r
-\r
-                   for (int gg = 0; gg < aa.length; gg++)\r
-                   {\r
-                     if (aa[gg].graphGroup == row.graphGroup)\r
-                     {\r
-                       drawLineGraph(g, aa[gg], startRes, endRes, y,\r
-                                     groupmin, groupmax,\r
-                                     row.graphHeight);\r
-                     }\r
-                   }\r
-\r
-                   graphGroupDrawn[ row.graphGroup ] = true;\r
-                 }\r
-                 else\r
-                   drawLineGraph(g, row, startRes, endRes,\r
-                                 y, row.graphMin, row.graphMax, row.graphHeight  );\r
-              }\r
-              else if(row.graph == AlignmentAnnotation.BAR_GRAPH )\r
-                 drawBarGraph(g, row, startRes, endRes,\r
-                              row.graphMin, row.graphMax, y);\r
-          }\r
-\r
-          if (row.graph>0 && row.hasText)\r
-          {\r
-              y += av.charHeight;\r
-          }\r
-\r
-          if (row.graph==0)\r
-          {\r
-              y += aa[i].height;\r
-          }\r
-      }\r
-  }\r
-\r
-  public void drawLineGraph(Graphics g, AlignmentAnnotation aa,\r
-                            int sRes, int eRes,\r
-                            int y,\r
-                            float min, float max,\r
-                            int graphHeight)\r
-  {\r
-    if(sRes>aa.annotations.length)\r
-      return;\r
-\r
-\r
-    eRes = Math.min(eRes, aa.annotations.length);\r
-\r
-    int x = 0;\r
-\r
-    //Adjustment for fastpaint to left\r
-    if(eRes<av.endRes)\r
-      eRes++;\r
-\r
-    if(sRes==0)\r
-    {\r
-      sRes++;\r
-      x+=av.charWidth;\r
-    }\r
-\r
-    int y1=y, y2=y;\r
-    float range = max - min;\r
-\r
-    ////Draw origin\r
-    if(min<0)\r
-      y2 = (int)(y - (0-min / range)*graphHeight);\r
-\r
-    g.setColor(Color.gray);\r
-    g.drawLine(x-av.charWidth,y2,(eRes-sRes)*av.charWidth,y2);\r
-\r
-\r
-    for (int j = sRes; j < eRes; j++)\r
-    {\r
-      if(aa.annotations[j]==null || aa.annotations[j-1]==null)\r
-      {\r
-        x+=av.charWidth;\r
-        continue;\r
-      }\r
-        g.setColor(aa.annotations[j].colour);\r
-        y1 = y - (int) (((aa.annotations[j-1].value-min) / range) * graphHeight);\r
-        y2 = y - (int) (((aa.annotations[j].value-min) / range) * graphHeight);\r
-        g.drawLine(x-av.charWidth/2, y1, x+av.charWidth/2, y2);\r
-        x += av.charWidth;\r
-     }\r
-\r
-\r
-     if(aa.threshold!=null)\r
-     {\r
-         g.setColor(aa.threshold.colour);\r
-         y2 = (int)(y - ((aa.threshold.value-min) / range)*aa.graphHeight);\r
-         g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);\r
-     }\r
-\r
-  }\r
-\r
-  public void drawBarGraph(Graphics g, AlignmentAnnotation aa,\r
-                           int sRes, int eRes,\r
-                           float min, float max,\r
-                           int y)\r
-  {\r
-    if(sRes>aa.annotations.length)\r
-      return;\r
-\r
-\r
-    eRes = Math.min(eRes, aa.annotations.length);\r
-\r
-    int x=0, y1, y2;\r
-\r
-    float range = max - min;\r
-\r
-    y1 = y2 = y;\r
-\r
-    if(min<0)\r
-      y2 = (int)(y - (0-min / (range))*aa.graphHeight);\r
-\r
-    g.setColor(Color.gray);\r
-\r
-    g.drawLine(x,y2,(eRes-sRes)*av.charWidth,y2);\r
-\r
-    for (int j = sRes; j < eRes; j++)\r
-    {\r
-\r
-      if (aa.annotations[j] == null)\r
-      {\r
-        x += av.charWidth;\r
-        continue;\r
-      }\r
-\r
-        g.setColor(aa.annotations[j].colour);\r
-        y1 = y - (int) (((aa.annotations[j].value-min) / (range)) * aa.graphHeight);\r
-\r
-        if(y1-y2>0)\r
-          g.fillRect(x, y2, av.charWidth, y1-y2 );\r
-        else\r
-          g.fillRect(x, y1, av.charWidth, y2-y1 );\r
-\r
-        x += av.charWidth;\r
-    }\r
-\r
-\r
-    if(aa.threshold!=null)\r
-    {\r
-        g.setColor(aa.threshold.colour);\r
-        y2 = (int)(y - ((aa.threshold.value-min) / range)*aa.graphHeight);\r
-        g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);\r
-    }\r
-\r
-\r
-  }\r
-\r
-  // used by overview window\r
-  public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)\r
-  {\r
-      g.setColor(Color.white);\r
-      g.fillRect(0, 0, width, y);\r
-      g.setColor(new Color(0, 0, 180));\r
-\r
-      int x = 0, height;\r
-\r
-      for (int j = sRes; j < eRes; j++)\r
-      {\r
-          g.setColor(aa.annotations[j].colour);\r
-\r
-          height = (int) ((aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT);\r
-          if(height>y)\r
-              height = y;\r
-          g.fillRect(x, y - height, av.charWidth, height);\r
-          x += av.charWidth;\r
-      }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+
+public class AnnotationPanel
+    extends Panel implements AdjustmentListener
+{
+  AlignViewport av;
+  AlignmentPanel ap;
+  int activeRow = -1;
+
+  Vector activeRes;
+  static String HELIX = "Helix";
+  static String SHEET = "Sheet";
+  static String LABEL = "Label";
+  static String REMOVE = "Remove Annotation";
+  static String COLOUR = "Colour";
+  static Color HELIX_COLOUR = Color.red.darker();
+  static Color SHEET_COLOUR = Color.green.darker().darker();
+
+  Image image;
+  Graphics gg;
+  FontMetrics fm;
+  int imgWidth = 0;
+
+  boolean fastPaint = false;
+
+  public static int GRAPH_HEIGHT = 40;
+
+  boolean MAC = false;
+
+  public AnnotationPanel(AlignmentPanel ap)
+  {
+    if (System.getProperty("os.name").startsWith("Mac"))
+      MAC = true;
+
+    this.ap = ap;
+    av = ap.av;
+    setLayout(null);
+    adjustPanelHeight();
+
+    addMouseMotionListener(new MouseMotionAdapter()
+    {
+      public void mouseMoved(MouseEvent evt)
+      {
+        doMouseMoved(evt);
+      }
+    });
+
+    // ap.annotationScroller.getVAdjustable().addAdjustmentListener( this );
+  }
+
+
+  public AnnotationPanel(AlignViewport av)
+  {
+    this.av = av;
+  }
+
+
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+    ap.alabels.setScrollOffset( -evt.getValue());
+  }
+
+  public int adjustPanelHeight()
+  {
+    // setHeight of panels
+    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+
+
+    int height = 0;
+    if (aa != null)
+    {
+      for (int i = 0; i < aa.length; i++)
+      {
+        if (!aa[i].visible)
+        {
+          continue;
+        }
+
+        aa[i].height = 0;
+
+        if (aa[i].hasText)
+        {
+          aa[i].height += av.charHeight;
+        }
+        if (aa[i].hasIcons)
+        {
+          aa[i].height += 16;
+        }
+
+        if (aa[i].graph>0)
+        {
+          aa[i].height += GRAPH_HEIGHT;
+        }
+
+        if (aa[i].height == 0)
+        {
+          aa[i].height = 20;
+        }
+        height += aa[i].height;
+      }
+    }
+    else
+    {
+      height = 20;
+    }
+
+    this.setSize(getSize().width, height);
+
+    repaint();
+
+    return height;
+
+  }
+
+  public void addEditableColumn(int i)
+  {
+    if (activeRow == -1)
+    {
+      AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+      if(aa ==null)
+        return;
+
+      for (int j = 0; j < aa.length; j++)
+      {
+        if (aa[j].editable)
+        {
+          activeRow = j;
+          break;
+        }
+      }
+    }
+
+    if (activeRes == null)
+    {
+      activeRes = new Vector();
+      activeRes.addElement(String.valueOf(i));
+      return;
+    }
+
+    activeRes.addElement(String.valueOf(i));
+  }
+
+  public void doMouseMoved(MouseEvent evt)
+  {
+    AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+    if (aa == null)
+    {
+      return;
+    }
+
+    int row = -1;
+    int height = 0;
+    for (int i = 0; i < aa.length; i++)
+    {
+
+      if (aa[i].visible)
+      {
+        height += aa[i].height;
+      }
+
+      if (evt.getY() < height)
+      {
+        row = i;
+        break;
+      }
+    }
+
+    int res = evt.getX() / av.getCharWidth() + av.getStartRes();
+
+    if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+    if (row > -1 && res < aa[row].annotations.length && aa[row].annotations[res] != null)
+    {
+      StringBuffer text = new StringBuffer("Sequence position " + (res + 1) +
+                                           "  " +
+                                           aa[row].annotations[res].description);
+      ap.alignFrame.statusBar.setText(text.toString());
+    }
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  public void paint(Graphics g)
+  {
+
+    imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;
+
+    if (image == null || imgWidth != image.getWidth(this))
+    {
+      image = createImage(imgWidth, ap.annotationPanel.getSize().height);
+      gg = image.getGraphics();
+      gg.setFont(av.getFont());
+      fm = gg.getFontMetrics();
+      fastPaint = false;
+    }
+
+    if (fastPaint)
+    {
+      g.drawImage(image, 0, 0, this);
+      fastPaint = false;
+      return;
+    }
+
+    drawComponent(gg, av.startRes, av.endRes + 1);
+    g.setColor(Color.white);
+    g.fillRect(0, 0, getSize().width, getSize().height);
+    g.drawImage(image, 0, 0, this);
+  }
+
+  public void fastPaint(int horizontal)
+  {
+    if (horizontal == 0
+        || av.alignment.getAlignmentAnnotation() == null
+        || av.alignment.getAlignmentAnnotation().length < 1
+        )
+    {
+      repaint();
+      return;
+    }
+
+    gg.copyArea(0, 0, imgWidth, getSize().height, -horizontal * av.charWidth, 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;
+      sr = er - horizontal;
+    }
+    else if (horizontal < 0)
+    {
+      er = sr - horizontal;
+    }
+
+    gg.translate(transX, 0);
+
+    drawComponent(gg, sr, er);
+
+    gg.translate( -transX, 0);
+
+    fastPaint = true;
+    repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param g DOCUMENT ME!
+   * @param startRes DOCUMENT ME!
+   * @param endRes DOCUMENT ME!
+   */
+  public void drawComponent(Graphics g, int startRes, int endRes)
+  {
+    g.setFont(av.getFont());
+
+    if (fm == null)
+      fm = g.getFontMetrics();
+
+
+      g.setColor(Color.white);
+      g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getSize().height);
+
+      if ((av.alignment.getAlignmentAnnotation() == null) ||
+              (av.alignment.getAlignmentAnnotation().length < 1))
+      {
+          g.setColor(Color.white);
+          g.fillRect(0, 0, getSize().width, getSize().height);
+          g.setColor(Color.black);
+          if(av.validCharWidth)
+            g.drawString("Alignment has no annotations", 20, 15);
+
+          return;
+      }
+
+      AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+
+      int x = 0;
+      int y = 0;
+      int column=0;
+      char lastSS;
+      int lastSSX;
+      int iconOffset = av.charHeight / 2;
+      boolean validRes = false;
+
+      boolean [] graphGroupDrawn = new boolean[aa.length];
+
+
+      //\u03B2 \u03B1
+      for (int i = 0; i < aa.length; i++)
+      {
+          AlignmentAnnotation row = aa[i];
+
+          if (!row.visible)
+          {
+              continue;
+          }
+
+          lastSS = ' ';
+          lastSSX = 0;
+
+          if (row.graph>0)
+          {
+              if(row.graphGroup>-1 && graphGroupDrawn[ row.graphGroup ] )
+                continue;
+
+              // this is so that we draw the characters below the graph
+              y += row.height;
+
+              if (row.hasText)
+              {
+                  y -= av.charHeight;
+              }
+          }
+
+          if (row.hasText)
+          {
+              iconOffset = av.charHeight / 2;
+          }
+          else
+          {
+              iconOffset = 0;
+          }
+
+           x = 0;
+          while(x < endRes-startRes)
+          {
+            if (av.hasHiddenColumns)
+            {
+              column = av.getColumnSelection().adjustForHiddenColumns(startRes+x);
+              if (column > row.annotations.length-1)
+              {
+                break;
+              }
+            }
+            else
+                column = startRes+x;
+
+              if ( (row.annotations.length <= column) ||
+                  (row.annotations[column] == null))
+              {
+                validRes = false;
+              }
+              else
+              {
+                validRes = true;
+              }
+
+
+              if (av.validCharWidth && validRes &&
+                        (row.annotations[column].displayCharacter.length() > 0))
+              {
+                int charOffset = (av.charWidth -
+                    fm.charWidth(row.annotations[column].displayCharacter.charAt(
+                            0))) / 2;
+                g.setColor(row.annotations[column].colour);
+
+                if (column == 0 || row.graph>0)
+                {
+                    g.drawString(row.annotations[column].displayCharacter,
+                                (x*av.charWidth)+charOffset,
+                        y + iconOffset + 3);
+                }
+                else if (
+                    row.annotations[column - 1] == null
+                    ||(!row.annotations[column].displayCharacter.equals(
+                        row.annotations[column - 1].displayCharacter)
+                    ||
+              (row.annotations[column].displayCharacter.length() <2 &&
+               row.annotations[column].secondaryStructure==' ')))
+                {
+                    g.drawString(row.annotations[column].displayCharacter,
+                       (x*av.charWidth)+charOffset,
+                        y + iconOffset + 3);
+                    }
+              }
+
+              if (row.hasIcons)
+              {
+                  if (!validRes ||
+                          (row.annotations[column].secondaryStructure != lastSS))
+                  {
+                      switch (lastSS)
+                      {
+                      case 'H':
+                        g.setColor(HELIX_COLOUR);
+                        if (MAC)
+                        {
+                          //Off by 1 offset when drawing rects and ovals
+                          //to offscreen image on the MAC
+                          g.fillRoundRect(lastSSX, y + 4 + iconOffset,
+                                          (x*av.charWidth) - lastSSX, 7, 8, 8);
+                          break;
+                        }
+
+                        int sCol = (lastSSX / av.charWidth) + startRes;
+                        int x1 = lastSSX;
+                        int x2 = (x*av.charWidth);
+
+                       if(sCol==0 ||
+                          row.annotations[sCol-1]==null ||
+                          row.annotations[sCol-1].secondaryStructure!='H')
+                       {
+                         g.fillArc(lastSSX, y+4+iconOffset, av.charWidth, 8, 90,180) ;
+                         x1 += av.charWidth/2;
+                       }
+
+                        if(row.annotations[column]==null ||
+                           row.annotations[column].secondaryStructure!='H')
+                        {
+                          g.fillArc((x*av.charWidth)-av.charWidth,
+                                    y+4+iconOffset, av.charWidth, 8, 270,180);
+                          x2 -= av.charWidth/2;
+                        }
+
+                        g.fillRect(x1, y+4+iconOffset, x2-x1, 8);
+                            break;
+
+                      case 'E':
+                          g.setColor(SHEET_COLOUR);
+                          g.fillRect(lastSSX, y + 4 + iconOffset,
+                              (x*av.charWidth) - lastSSX - 4, 7);
+                          g.fillPolygon(new int[] { (x*av.charWidth) - 4,
+                                        (x*av.charWidth) - 4,
+                                        (x*av.charWidth) },
+                              new int[]
+                              {
+                                  y + iconOffset, y + 14 + iconOffset,
+                                  y + 8 + iconOffset
+                              }, 3);
+
+                          break;
+
+
+                      default:
+                          g.setColor(Color.gray);
+                          g.fillRect(lastSSX, y + 6 + iconOffset,
+                              (x*av.charWidth) - lastSSX, 2);
+
+                          break;
+                      }
+
+                      if (validRes)
+                      {
+                          lastSS = row.annotations[column].secondaryStructure;
+                      }
+                      else
+                      {
+                          lastSS = ' ';
+                      }
+
+                      lastSSX = (x*av.charWidth);
+                  }
+              }
+
+
+          column++;
+          x++;
+          }
+
+          if(column>=row.annotations.length)
+              column = row.annotations.length-1;
+
+        //  x ++;
+
+          if (row.hasIcons)
+          {
+            switch (lastSS)
+            {
+              case 'H':
+                g.setColor(HELIX_COLOUR);
+                if (MAC)
+                {
+                  //Off by 1 offset when drawing rects and ovals
+                  //to offscreen image on the MAC
+                  g.fillRoundRect(lastSSX, y + 4 + iconOffset,
+                                  (x*av.charWidth) - lastSSX, 7, 8, 8);
+                  break;
+                }
+
+                int sCol = (lastSSX / av.charWidth) + startRes;
+                int x1 = lastSSX;
+                int x2 = (x*av.charWidth);
+
+                if (sCol == 0 ||
+                    row.annotations[sCol - 1] == null ||
+                    row.annotations[sCol - 1].secondaryStructure != 'H')
+                {
+                  g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90, 180);
+                  x1 += av.charWidth / 2;
+                }
+
+                if (row.annotations[column] == null ||
+                    row.annotations[column].secondaryStructure != 'H')
+                {
+                  g.fillArc((x*av.charWidth) - av.charWidth,
+                            y + 4 + iconOffset, av.charWidth, 8, 270,
+                            180);
+                  x2 -= av.charWidth / 2;
+                }
+
+                g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
+
+                break;
+
+              case 'E':
+                g.setColor(SHEET_COLOUR);
+
+                if (row.annotations[endRes] == null
+                    || row.annotations[endRes].secondaryStructure != 'E')
+                {
+                  g.fillRect(lastSSX, y + 4 + iconOffset,
+                             (x*av.charWidth) - lastSSX - 4, 7);
+                  g.fillPolygon(new int[]
+                                {(x*av.charWidth) - 4,
+                                (x*av.charWidth) - 4,
+                               (x*av.charWidth)},
+                                new int[]
+                                {
+                                y + iconOffset, y + 14 + iconOffset,
+                                y + 7 + iconOffset
+                  }, 3);
+                }
+                else
+                 {
+                   g.fillRect(lastSSX, y + 4 + iconOffset,
+                              (x+1) * av.charWidth - lastSSX, 7);
+                 }
+                break;
+
+              default:
+                g.setColor(Color.gray);
+                if(!av.wrapAlignment || endRes==av.endRes)
+                g.fillRect(lastSSX, y + 6 + iconOffset,
+                           (x*av.charWidth) - lastSSX, 2);
+
+                break;
+            }
+          }
+
+          if (row.graph>0)
+          {
+              if(row.graph == AlignmentAnnotation.LINE_GRAPH )
+              {
+                if(row.graphGroup>-1 && !graphGroupDrawn[row.graphGroup])
+                 {
+                   float groupmax=-999999, groupmin=9999999;
+                   for(int gg=0; gg<aa.length; gg++)
+                   {
+                     if(aa[gg].graphGroup!=row.graphGroup)
+                       continue;
+
+                     if(aa[gg]!=row)
+                       aa[gg].visible = false;
+
+                     if(aa[gg].graphMax>groupmax)
+                       groupmax = aa[gg].graphMax;
+                     if(aa[gg].graphMin<groupmin)
+                       groupmin = aa[gg].graphMin;
+                   }
+
+                   for (int gg = 0; gg < aa.length; gg++)
+                   {
+                     if (aa[gg].graphGroup == row.graphGroup)
+                     {
+                       drawLineGraph(g, aa[gg], startRes, endRes, y,
+                                     groupmin, groupmax,
+                                     row.graphHeight);
+                     }
+                   }
+
+                   graphGroupDrawn[ row.graphGroup ] = true;
+                 }
+                 else
+                   drawLineGraph(g, row, startRes, endRes,
+                                 y, row.graphMin, row.graphMax, row.graphHeight  );
+              }
+              else if(row.graph == AlignmentAnnotation.BAR_GRAPH )
+                 drawBarGraph(g, row, startRes, endRes,
+                              row.graphMin, row.graphMax, y);
+          }
+
+          if (row.graph>0 && row.hasText)
+          {
+              y += av.charHeight;
+          }
+
+          if (row.graph==0)
+          {
+              y += aa[i].height;
+          }
+      }
+  }
+
+  public void drawLineGraph(Graphics g, AlignmentAnnotation aa,
+                            int sRes, int eRes,
+                            int y,
+                            float min, float max,
+                            int graphHeight)
+  {
+    if(sRes>aa.annotations.length)
+      return;
+
+
+
+    int x = 0;
+
+    //Adjustment for fastpaint to left
+    if(eRes<av.endRes)
+      eRes++;
+
+    eRes = Math.min(eRes, aa.annotations.length);
+
+
+    if(sRes==0)
+    {
+      sRes++;
+      x+=av.charWidth;
+    }
+
+    int y1=y, y2=y;
+    float range = max - min;
+
+    ////Draw origin
+    if(min<0)
+      y2 = y - (int)((0-min / range)*graphHeight);
+
+    g.setColor(Color.gray);
+    g.drawLine(x-av.charWidth,y2,(eRes-sRes)*av.charWidth,y2);
+
+    eRes = Math.min(eRes, aa.annotations.length);
+
+    int column;
+    int aaMax = aa.annotations.length-1;
+
+    while( x < eRes - sRes )
+    {
+      column = sRes + x;
+      if(av.hasHiddenColumns)
+      {
+        column = av.getColumnSelection().adjustForHiddenColumns(column);
+      }
+
+      if (column > aaMax)
+      {
+        break;
+      }
+
+      if(aa.annotations[column]==null || aa.annotations[column-1]==null)
+      {
+        x++;
+        continue;
+      }
+
+        g.setColor(aa.annotations[column].colour);
+        y1 = y - (int) (((aa.annotations[column-1].value-min) / range) * graphHeight);
+        y2 = y - (int) (((aa.annotations[column].value-min) / range) * graphHeight);
+
+        g.drawLine(x*av.charWidth-av.charWidth/2, y1, x*av.charWidth+av.charWidth/2, y2);
+        x ++;
+     }
+
+     if(aa.threshold!=null)
+     {
+         g.setColor(aa.threshold.colour);
+
+         y2 = (int)(y - ((aa.threshold.value-min) / range)*graphHeight);
+         g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);
+    }
+  }
+
+  public void drawBarGraph(Graphics g, AlignmentAnnotation aa,
+                           int sRes, int eRes,
+                           float min, float max,
+                           int y)
+  {
+    if(sRes>aa.annotations.length)
+      return;
+
+    eRes = Math.min(eRes, aa.annotations.length);
+
+    int x=0, y1=y, y2=y;
+
+    float range = max - min;
+
+    if(min<0)
+      y2 = y - (int)((0-min / (range))*aa.graphHeight);
+
+    g.setColor(Color.gray);
+
+    g.drawLine(x,y2,(eRes-sRes)*av.charWidth,y2);
+
+    int column;
+    int aaMax = aa.annotations.length-1;
+
+    while( x < eRes-sRes )
+    {
+      column = sRes + x;
+      if(av.hasHiddenColumns)
+      {
+        column = av.getColumnSelection().adjustForHiddenColumns(column);
+      }
+
+      if(column > aaMax)
+      {
+          break;
+      }
+
+      if (aa.annotations[column] == null)
+      {
+        x ++;
+        continue;
+      }
+
+        g.setColor(aa.annotations[column].colour);
+        y1 = y - (int) (((aa.annotations[column].value-min) / (range)) * aa.graphHeight);
+
+        if(y1-y2>0)
+          g.fillRect(x*av.charWidth, y2, av.charWidth, y1-y2 );
+        else
+          g.fillRect(x*av.charWidth, y1, av.charWidth, y2-y1 );
+
+        x ++ ;
+
+    }
+    if(aa.threshold!=null)
+    {
+        g.setColor(aa.threshold.colour);
+        y2 = (int)(y - ((aa.threshold.value-min) / range)*aa.graphHeight);
+        g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);
+      }
+  }
+
+  // used by overview window
+  public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)
+  {
+      g.setColor(Color.white);
+      g.fillRect(0, 0, width, y);
+      g.setColor(new Color(0, 0, 180));
+
+      int x = 0, height;
+
+      for (int j = sRes; j < eRes; j++)
+      {
+          g.setColor(aa.annotations[j].colour);
+
+          height = (int) ((aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT);
+          if(height>y)
+              height = y;
+          g.fillRect(x, y - height, av.charWidth, height);
+          x += av.charWidth;
+      }
+    }
+}
diff --git a/src/jalview/appletgui/ColumnSelection.java b/src/jalview/appletgui/ColumnSelection.java
deleted file mode 100755 (executable)
index 33c4604..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-/**\r
- * NOTE: Columns are zero based.\r
- */\r
-public class ColumnSelection\r
-{\r
-  Vector selected = new Vector();\r
-\r
-  public void addElement(int col)\r
-  {\r
-    if(!selected.contains(new Integer(col)))\r
-      selected.addElement(new Integer(col));\r
-  }\r
-\r
-  public void clear()\r
-  {\r
-    selected.removeAllElements();\r
-  }\r
-\r
-  public void removeElement(int col)\r
-  {\r
-    Integer colInt = new Integer(col);\r
-    if (selected.contains(colInt))\r
-    {\r
-      selected.removeElement(colInt);\r
-    }\r
-  }\r
-\r
-  public void removeElements(int start, int end)\r
-  {\r
-    Integer colInt;\r
-    for(int i=start; i<end; i++)\r
-    {\r
-      colInt = new Integer(i);\r
-      if (selected.contains(colInt))\r
-      {\r
-          selected.removeElement(colInt);\r
-      }\r
-    }\r
-    }\r
-\r
-  public boolean contains(int col)\r
-  {\r
-    return selected.contains(new Integer(col));\r
-  }\r
-\r
-  public int columnAt(int i)\r
-  {\r
-    return ( (Integer) selected.elementAt(i)).intValue();\r
-  }\r
-\r
-  public int size()\r
-  {\r
-    return selected.size();\r
-  }\r
-\r
-  public int getMax()\r
-  {\r
-    int max = -1;\r
-\r
-    for (int i = 0; i < selected.size(); i++)\r
-    {\r
-      if (columnAt(i) > max)\r
-      {\r
-        max = columnAt(i);\r
-      }\r
-    }\r
-    return max;\r
-  }\r
-\r
-  public int getMin()\r
-  {\r
-    int min = 1000000000;\r
-\r
-    for (int i = 0; i < selected.size(); i++)\r
-    {\r
-      if (columnAt(i) < min)\r
-      {\r
-        min = columnAt(i);\r
-      }\r
-    }\r
-    return min;\r
-  }\r
-\r
-  public Vector asVector()\r
-  {\r
-    return selected;\r
-  }\r
-\r
-  public void compensateForEdit(int start, int change)\r
-  {\r
-    for (int i = 0; i < size(); i++)\r
-    {\r
-      int temp = columnAt(i);\r
-\r
-      if (temp >= start)\r
-      {\r
-        selected.setElementAt(new Integer(temp - change), i);\r
-      }\r
-    }\r
-  }\r
-}\r
index 4b890bb..1b73d92 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.io.*;\r
-\r
-public class CutAndPasteTransfer extends Panel implements ActionListener, MouseListener\r
-{\r
-  boolean pdbImport = false;\r
-  boolean treeImport = false;\r
-  Sequence seq;\r
-  AlignFrame alignFrame;\r
-\r
-  public CutAndPasteTransfer(boolean forImport, AlignFrame alignFrame)\r
-  {\r
-    try {\r
-        jbInit();\r
-    } catch (Exception e) {\r
-        e.printStackTrace();\r
-    }\r
-\r
-    this.alignFrame = alignFrame;\r
-\r
-    if (!forImport)\r
-    {\r
-      buttonPanel.setVisible(false);\r
-    }\r
-  }\r
-\r
-  public String getText()\r
-  {\r
-    return textarea.getText();\r
-  }\r
-\r
-  public void setText(String text)\r
-  {\r
-    textarea.setText(text);\r
-  }\r
-\r
-  public void setPDBImport(Sequence seq)\r
-  {\r
-    this.seq = seq;\r
-    pdbImport = true;\r
-  }\r
-\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==ok)\r
-      ok_actionPerformed();\r
-    else if(evt.getSource()==cancel)\r
-      cancel_actionPerformed();\r
-  }\r
-\r
-  protected void ok_actionPerformed()\r
-  {\r
-    String text = getText();\r
-    int length = text.length();\r
-    textarea.append("\n");\r
-    if(textarea.getText().length()==length)\r
-    {\r
-      String warning = "\n\n#################################################\n"\r
-          +"WARNING!! THIS IS THE MAXIMUM SIZE OF TEXTAREA!!\n"\r
-          +"\nCAN'T INPUT FULL ALIGNMENT"\r
-          +"\n\nYOU MUST DELETE THIS WARNING TO CONTINUE"\r
-          +"\n\nMAKE SURE LAST SEQUENCE PASTED IS COMPLETE"\r
-          +"\n#################################################\n";\r
-      textarea.setText(text.substring(0, text.length()-warning.length())\r
-          +warning);\r
-\r
-      textarea.setCaretPosition(text.length());\r
-    }\r
-\r
-    if(pdbImport)\r
-    {\r
-      new MCview.AppletPDBViewer(text, AppletFormatAdapter.PASTE,\r
-                                 seq,\r
-                                 alignFrame.getSeqcanvas());\r
-    }\r
-    else if(treeImport)\r
-    {\r
-      try{\r
-        jalview.io.NewickFile fin = new jalview.io.NewickFile(textarea.getText(),\r
-            "Paste");\r
-\r
-        fin.parse();\r
-        if(fin.getTree()!=null)\r
-          alignFrame.loadTree(fin, "Pasted tree file");\r
-\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        textarea.setText("Could not parse Newick file!\n" + ex);\r
-        return;\r
-      }\r
-    }\r
-    else if(alignFrame!=null)\r
-    {\r
-      SequenceI[] sequences = null;\r
-\r
-      String format = new IdentifyFile().Identify(text, AppletFormatAdapter.PASTE);\r
-      try{\r
-        sequences = new AppletFormatAdapter().readFile(text, AppletFormatAdapter.PASTE, format);\r
-      }catch(java.io.IOException ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-      if (sequences != null)\r
-      {\r
-        AlignFrame af = new AlignFrame(new Alignment(sequences), alignFrame.applet,\r
-                                       "Cut & Paste input - " + format,\r
-                                       false);\r
-        af.statusBar.setText("Successfully pasted alignment file");\r
-      }\r
-    }\r
-\r
-   if(this.getParent() instanceof Frame)\r
-    ((Frame)this.getParent()).setVisible(false);\r
-   else\r
-     ((Dialog)this.getParent()).setVisible(false);\r
-  }\r
-\r
-  protected void cancel_actionPerformed()\r
-  {\r
-    textarea.setText("");\r
-    if(this.getParent() instanceof Frame)\r
-     ((Frame)this.getParent()).setVisible(false);\r
-    else\r
-     ((Dialog)this.getParent()).setVisible(false);\r
-  }\r
-\r
-  protected TextArea textarea = new TextArea();\r
-  Button ok = new Button();\r
-  Button cancel = new Button();\r
-  protected Panel buttonPanel = new Panel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-\r
-\r
-  private void jbInit() throws Exception {\r
-      textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 10));\r
-      textarea.setText("Paste your alignment file here");\r
-      textarea.addMouseListener(this);\r
-      this.setLayout(borderLayout1);\r
-      ok.setLabel("OK");\r
-      ok.addActionListener(this);\r
-      cancel.setLabel("Cancel");\r
-      cancel.addActionListener(this);\r
-      this.add(buttonPanel, BorderLayout.SOUTH);\r
-      buttonPanel.add(ok, null);\r
-      buttonPanel.add(cancel, null);\r
-      this.add(textarea, java.awt.BorderLayout.CENTER);\r
-  }\r
-\r
-  public void mousePressed(MouseEvent evt) {\r
-      if (textarea.getText().startsWith("Paste your")) {\r
-          textarea.setText("");\r
-     }\r
-  }\r
-  public void mouseReleased(MouseEvent evt){}\r
-  public void mouseClicked(MouseEvent evt){}\r
-  public void mouseEntered(MouseEvent evt){}\r
-  public void mouseExited(MouseEvent evt){}\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.io.*;
+
+public class CutAndPasteTransfer extends Panel implements ActionListener, MouseListener
+{
+  boolean pdbImport = false;
+  boolean treeImport = false;
+  Sequence seq;
+  AlignFrame alignFrame;
+
+  public CutAndPasteTransfer(boolean forImport, AlignFrame alignFrame)
+  {
+    try {
+        jbInit();
+    } catch (Exception e) {
+        e.printStackTrace();
+    }
+
+    this.alignFrame = alignFrame;
+
+    if (!forImport)
+    {
+      buttonPanel.setVisible(false);
+    }
+  }
+
+  public String getText()
+  {
+    return textarea.getText();
+  }
+
+  public void setText(String text)
+  {
+    textarea.setText(text);
+  }
+
+  public void setPDBImport(Sequence seq)
+  {
+    this.seq = seq;
+    pdbImport = true;
+  }
+
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==ok)
+      ok_actionPerformed();
+    else if(evt.getSource()==cancel)
+      cancel_actionPerformed();
+  }
+
+  protected void ok_actionPerformed()
+  {
+    String text = getText();
+    int length = text.length();
+    textarea.append("\n");
+    if(textarea.getText().length()==length)
+    {
+      String warning = "\n\n#################################################\n"
+          +"WARNING!! THIS IS THE MAXIMUM SIZE OF TEXTAREA!!\n"
+          +"\nCAN'T INPUT FULL ALIGNMENT"
+          +"\n\nYOU MUST DELETE THIS WARNING TO CONTINUE"
+          +"\n\nMAKE SURE LAST SEQUENCE PASTED IS COMPLETE"
+          +"\n#################################################\n";
+      textarea.setText(text.substring(0, text.length()-warning.length())
+          +warning);
+
+      textarea.setCaretPosition(text.length());
+    }
+
+    if(pdbImport)
+    {
+      new MCview.AppletPDBViewer(text, AppletFormatAdapter.PASTE,
+                                 seq,
+                                 alignFrame.getSeqcanvas());
+    }
+    else if(treeImport)
+    {
+      try{
+        jalview.io.NewickFile fin = new jalview.io.NewickFile(textarea.getText(),
+            "Paste");
+
+        fin.parse();
+        if(fin.getTree()!=null)
+          alignFrame.loadTree(fin, "Pasted tree file");
+
+      }
+      catch (Exception ex)
+      {
+        textarea.setText("Could not parse Newick file!\n" + ex);
+        return;
+      }
+    }
+    else if(alignFrame!=null)
+    {
+      SequenceI[] sequences = null;
+
+      String format = new IdentifyFile().Identify(text, AppletFormatAdapter.PASTE);
+      try{
+        sequences = new AppletFormatAdapter().readFile(text, AppletFormatAdapter.PASTE, format);
+      }catch(java.io.IOException ex)
+      {
+        ex.printStackTrace();
+      }
+      if (sequences != null)
+      {
+        AlignFrame af = new AlignFrame(new Alignment(sequences), alignFrame.viewport.applet,
+                                       "Cut & Paste input - " + format,
+                                       false);
+        af.statusBar.setText("Successfully pasted alignment file");
+      }
+    }
+
+   if(this.getParent() instanceof Frame)
+    ((Frame)this.getParent()).setVisible(false);
+   else
+     ((Dialog)this.getParent()).setVisible(false);
+  }
+
+  protected void cancel_actionPerformed()
+  {
+    textarea.setText("");
+    if(this.getParent() instanceof Frame)
+     ((Frame)this.getParent()).setVisible(false);
+    else
+     ((Dialog)this.getParent()).setVisible(false);
+  }
+
+  protected TextArea textarea = new TextArea();
+  Button ok = new Button();
+  Button cancel = new Button();
+  protected Panel buttonPanel = new Panel();
+  BorderLayout borderLayout1 = new BorderLayout();
+
+
+  private void jbInit() throws Exception {
+      textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 10));
+      textarea.setText("Paste your alignment file here");
+      textarea.addMouseListener(this);
+      this.setLayout(borderLayout1);
+      ok.setLabel("OK");
+      ok.addActionListener(this);
+      cancel.setLabel("Cancel");
+      cancel.addActionListener(this);
+      this.add(buttonPanel, BorderLayout.SOUTH);
+      buttonPanel.add(ok, null);
+      buttonPanel.add(cancel, null);
+      this.add(textarea, java.awt.BorderLayout.CENTER);
+  }
+
+  public void mousePressed(MouseEvent evt) {
+      if (textarea.getText().startsWith("Paste your")) {
+          textarea.setText("");
+     }
+  }
+  public void mouseReleased(MouseEvent evt){}
+  public void mouseClicked(MouseEvent evt){}
+  public void mouseEntered(MouseEvent evt){}
+  public void mouseExited(MouseEvent evt){}
+}
index 83a8340..727694d 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.appletgui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class FeatureRenderer\r
-{\r
-    AlignViewport av;\r
-\r
-\r
-    // A higher level for grouping features of a\r
-    // particular type\r
-    Hashtable featureGroups = null;\r
-\r
-    // This is actually an Integer held in the hashtable,\r
-    // Retrieved using the key feature type\r
-    Object currentColour;\r
-\r
-    String [] renderOrder;\r
-\r
-    FontMetrics fm;\r
-    int charOffset;\r
-\r
-    /**\r
-     * Creates a new FeatureRenderer object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     */\r
-    public FeatureRenderer(AlignViewport av)\r
-    {\r
-        this.av = av;\r
-        initColours();\r
-    }\r
-\r
-\r
-    public void transferSettings(FeatureRenderer fr)\r
-    {\r
-      renderOrder = fr.renderOrder;\r
-      featureGroups = fr.featureGroups;\r
-      featureColours = fr.featureColours;\r
-    }\r
-\r
-\r
-    public Color findFeatureColour(Color initialCol, SequenceI seq, int i)\r
-    {\r
-      overview = true;\r
-      if(!av.showSequenceFeatures)\r
-        return initialCol;\r
-\r
-        lastSequence = seq;\r
-        sequenceFeatures = lastSequence.getSequenceFeatures();\r
-        if(sequenceFeatures==null)\r
-          return initialCol;\r
-\r
-        sfSize = sequenceFeatures.length;\r
-\r
-      if(jalview.util.Comparison.isGap(lastSequence.getCharAt(i)))\r
-        return Color.white;\r
-\r
-      currentColour = null;\r
-\r
-      drawSequence(null, lastSequence, lastSequence.findPosition(i), -1,-1, -1, -1);\r
-\r
-      if(currentColour==null)\r
-        return initialCol;\r
-\r
-      return new Color( ((Integer)currentColour).intValue() );\r
-    }\r
-\r
-    /**\r
-     * This is used by the Molecule Viewer to get the accurate colour\r
-     * of the rendered sequence\r
-     */\r
-    boolean overview = false;\r
-\r
-    int white = Color.white.getRGB();\r
-    public int findFeatureColour(int initialCol, int seqIndex, int column)\r
-    {\r
-      if(!av.showSequenceFeatures)\r
-        return initialCol;\r
-\r
-      if(seqIndex!=lastSequenceIndex)\r
-      {\r
-        lastSequence = av.alignment.getSequenceAt(seqIndex);\r
-        lastSequenceIndex = seqIndex;\r
-        sequenceFeatures = lastSequence.getSequenceFeatures();\r
-        if(sequenceFeatures==null)\r
-          return initialCol;\r
-\r
-        sfSize = sequenceFeatures.length;\r
-      }\r
-\r
-\r
-      if(jalview.util.Comparison.isGap(lastSequence.getCharAt(column)))\r
-        return Color.white.getRGB();\r
-\r
-      currentColour = null;\r
-\r
-      drawSequence(null, lastSequence, lastSequence.findPosition(column), -1,-1, -1, -1);\r
-\r
-      if(currentColour==null)\r
-        return initialCol;\r
-\r
-      return  ((Integer)currentColour).intValue();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     * @param sg DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-   // String type;\r
-   // SequenceFeature sf;\r
-    int lastSequenceIndex=-1;\r
-    SequenceI lastSequence;\r
-    SequenceFeature [] sequenceFeatures;\r
-    int sfSize, sfindex, spos, epos;\r
-\r
-    public void drawSequence(Graphics g, SequenceI seq,\r
-                             int start, int end, int y1, int width, int height)\r
-    {\r
-      if (   seq.getSequenceFeatures() == null\r
-          || seq.getSequenceFeatures().length==0)\r
-        return;\r
-\r
-\r
-      if (av.featuresDisplayed == null || renderOrder==null)\r
-       {\r
-         findAllFeatures();\r
-         if(av.featuresDisplayed.size()<1)\r
-           return;\r
-\r
-         sequenceFeatures = seq.getSequenceFeatures();\r
-         sfSize = sequenceFeatures.length;\r
-       }\r
-       if(lastSequence==null || seq!=lastSequence)\r
-      {\r
-        lastSequence = seq;\r
-        sequenceFeatures = seq.getSequenceFeatures();\r
-        sfSize = sequenceFeatures.length;\r
-      }\r
-      if(!overview)\r
-      {\r
-        spos = lastSequence.findPosition(start);\r
-        epos = lastSequence.findPosition(end);\r
-        if(g!=null)\r
-          fm = g.getFontMetrics();\r
-      }\r
-      String type;\r
-      for(int renderIndex=0; renderIndex<renderOrder.length; renderIndex++)\r
-       {\r
-        type =  renderOrder[renderIndex];\r
-        if(!av.featuresDisplayed.containsKey(type))\r
-          continue;\r
-\r
-        // loop through all features in sequence to find\r
-        // current feature to render\r
-        for (sfindex = 0; sfindex < sfSize; sfindex++)\r
-        {\r
-          if (!sequenceFeatures[sfindex].type.equals(type))\r
-            continue;\r
-\r
-          if (featureGroups != null\r
-              && sequenceFeatures[sfindex].featureGroup != null\r
-              &&\r
-              featureGroups.containsKey(sequenceFeatures[sfindex].featureGroup)\r
-              &&\r
-              ! ( (Boolean) featureGroups.get(sequenceFeatures[sfindex].featureGroup)).\r
-              booleanValue())\r
-          {\r
-            continue;\r
-          }\r
-\r
-          if (!overview && (sequenceFeatures[sfindex].getBegin() > epos\r
-                            || sequenceFeatures[sfindex].getEnd() < spos))\r
-            continue;\r
-\r
-          if (overview)\r
-          {\r
-            if (sequenceFeatures[sfindex].begin <= start &&\r
-                sequenceFeatures[sfindex].end >= start)\r
-            {\r
-              currentColour = av.featuresDisplayed.get(sequenceFeatures[sfindex].\r
-                  type);\r
-            }\r
-\r
-          }\r
-          else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))\r
-          {\r
-\r
-            renderFeature(g, seq,\r
-                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
-                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
-                          new Color( ( (Integer) av.featuresDisplayed.get(\r
-                sequenceFeatures[sfindex].type)).intValue()),\r
-                          start, end, y1, width, height);\r
-            renderFeature(g, seq,\r
-                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
-                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
-                          new Color( ( (Integer) av.featuresDisplayed.get(\r
-                sequenceFeatures[sfindex].type)).intValue()),\r
-                          start, end, y1, width, height);\r
-\r
-          }\r
-          else\r
-            renderFeature(g, seq,\r
-                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
-                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
-                          getColour(sequenceFeatures[sfindex].type),\r
-                          start, end, y1, width, height);\r
-\r
-        }\r
-      }\r
-    }\r
-\r
-\r
-    char s;\r
-    int i;\r
-    void renderFeature(Graphics g, SequenceI seq,\r
-                       int fstart, int fend, Color featureColour, int start, int end,  int y1, int width, int height)\r
-    {\r
-\r
-      if (((fstart <= end) && (fend >= start)))\r
-      {\r
-        if (fstart < start)\r
-        { // fix for if the feature we have starts before the sequence start,\r
-          fstart = start; // but the feature end is still valid!!\r
-        }\r
-\r
-        if (fend >= end)\r
-        {\r
-          fend = end;\r
-        }\r
-\r
-          for (i = fstart; i <= fend; i++)\r
-          {\r
-            s = seq.getSequence().charAt(i);\r
-\r
-            if (jalview.util.Comparison.isGap(s))\r
-            {\r
-              continue;\r
-            }\r
-\r
-            g.setColor(featureColour);\r
-\r
-            g.fillRect( (i - start) * width, y1, width, height);\r
-\r
-            g.setColor(Color.white);\r
-            charOffset = (width - fm.charWidth(s)) / 2;\r
-            g.drawString(String.valueOf(s),\r
-                         charOffset + (width * (i - start)),\r
-                         (y1 + height) - height / 5); //pady = height / 5;\r
-\r
-          }\r
-      }\r
-    }\r
-\r
-    void findAllFeatures()\r
-    {\r
-      av.featuresDisplayed = new Hashtable();\r
-      Vector allfeatures = new Vector();\r
-      for (int i = 0; i < av.alignment.getHeight(); i++)\r
-      {\r
-        SequenceFeature [] features = av.alignment.getSequenceAt(i).getSequenceFeatures();\r
-\r
-        if (features == null)\r
-          continue;\r
-\r
-        int index = 0;\r
-        while (index < features.length)\r
-        {\r
-          if (!av.featuresDisplayed.containsKey(features[index].getType()))\r
-          {\r
-            av.featuresDisplayed.put(features[index].getType(),\r
-                                  new Integer( getColour(features[index].getType()).getRGB()) );\r
-            allfeatures.addElement(features[index].getType());\r
-          }\r
-          index++;\r
-        }\r
-      }\r
-\r
-      renderOrder = new String[allfeatures.size()];\r
-      Enumeration en = allfeatures.elements();\r
-      int i = allfeatures.size()-1;\r
-      while(en.hasMoreElements())\r
-      {\r
-        renderOrder[i] = en.nextElement().toString();\r
-        i--;\r
-      }\r
-    }\r
-\r
-    public Color getColour(String featureType)\r
-    {\r
-      return (Color)featureColours.get(featureType);\r
-    }\r
-\r
-    public void addNewFeature(String name, Color col)\r
-    {\r
-\r
-      setColour(name, col);\r
-      if(av.featuresDisplayed==null)\r
-        av.featuresDisplayed = new Hashtable();\r
-\r
-\r
-      av.featuresDisplayed.put(name, "NOGROUP");\r
-    }\r
-\r
-    public void setColour(String featureType, Color col)\r
-    {\r
-      featureColours.put(featureType, col);\r
-    }\r
-\r
-    public void setFeaturePriority(Object [][] data)\r
-    {\r
-        // The feature table will display high priority\r
-        // features at the top, but theses are the ones\r
-        // we need to render last, so invert the data\r
-        if(av.featuresDisplayed!=null)\r
-          av.featuresDisplayed.clear();\r
-\r
-        renderOrder = new String[data.length];\r
-\r
-        if (data.length > 0)\r
-          for (int i = 0; i < data.length; i++)\r
-          {\r
-            String type = data[i][0].toString();\r
-            setColour(type, (Color) data[i][1]);\r
-            if ( ( (Boolean) data[i][2]).booleanValue())\r
-            {\r
-              av.featuresDisplayed.put(type, new Integer(getColour(type).getRGB()));\r
-            }\r
-\r
-            renderOrder[data.length - i - 1] = type;\r
-          }\r
-    }\r
-\r
-    Hashtable featureColours = new Hashtable();\r
-    void initColours()\r
-    {\r
-      featureColours.put("active site", new Color(255, 75, 0));\r
-      featureColours.put("binding site", new Color(245, 85, 0));\r
-      featureColours.put("calcium-binding region", new Color(235, 95, 0));\r
-      featureColours.put("chain", new Color(225, 105, 0));\r
-      featureColours.put("coiled-coil region", new Color(215, 115, 0));\r
-      featureColours.put("compositionally biased region", new Color(205, 125, 0));\r
-      featureColours.put("cross-link", new Color(195, 135, 0));\r
-      featureColours.put("disulfide bond", new Color(185, 145, 0));\r
-      featureColours.put("DNA-binding region", new Color(175, 155, 0));\r
-      featureColours.put("domain", new Color(165, 165, 0));\r
-      featureColours.put("glycosylation site", new Color(155, 175, 0));\r
-      featureColours.put("helix", new Color(145, 185, 0));\r
-      featureColours.put("initiator methionine", new Color(135, 195, 5));\r
-      featureColours.put("lipid moiety-binding region", new Color(125, 205, 15));\r
-      featureColours.put("metal ion-binding site", new Color(115, 215, 25));\r
-      featureColours.put("modified residue", new Color(105, 225, 35));\r
-      featureColours.put("mutagenesis site", new Color(95, 235, 45));\r
-      featureColours.put("non-consecutive residues", new Color(85, 245, 55));\r
-      featureColours.put("non-terminal residue", new Color(75, 255, 65));\r
-      featureColours.put("nucleotide phosphate-binding region",\r
-                         new Color(65, 245, 75));\r
-      featureColours.put("peptide", new Color(55, 235, 85));\r
-      featureColours.put("propeptide", new Color(45, 225, 95));\r
-      featureColours.put("region of interest", new Color(35, 215, 105));\r
-      featureColours.put("repeat", new Color(25, 205, 115));\r
-      featureColours.put("selenocysteine", new Color(15, 195, 125));\r
-      featureColours.put("sequence conflict", new Color(5, 185, 135));\r
-      featureColours.put("sequence variant", new Color(0, 175, 145));\r
-      featureColours.put("short sequence motif", new Color(0, 165, 155));\r
-      featureColours.put("signal peptide", new Color(0, 155, 165));\r
-      featureColours.put("site", new Color(0, 145, 175));\r
-      featureColours.put("splice variant", new Color(0, 135, 185));\r
-      featureColours.put("strand", new Color(0, 125, 195));\r
-      featureColours.put("topological domain", new Color(0, 115, 205));\r
-      featureColours.put("transit peptide", new Color(0, 105, 215));\r
-      featureColours.put("transmembrane region", new Color(0, 95, 225));\r
-      featureColours.put("turn", new Color(0, 85, 235));\r
-      featureColours.put("unsure residue", new Color(0, 75, 245));\r
-      featureColours.put("zinc finger region", new Color(0, 65, 255));\r
-    }\r
-\r
-}\r
-\r
-\r
-\r
+
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.appletgui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class FeatureRenderer
+{
+    AlignViewport av;
+
+    Hashtable featureColours = new Hashtable();
+
+    // A higher level for grouping features of a
+    // particular type
+    Hashtable featureGroups = null;
+
+    // Holds web links for feature groups and feature types
+    // in the form label|link
+    Hashtable featureLinks = null;
+
+
+    // This is actually an Integer held in the hashtable,
+    // Retrieved using the key feature type
+    Object currentColour;
+
+    String [] renderOrder;
+
+    FontMetrics fm;
+    int charOffset;
+
+    float transparency = 1f;
+
+    TransparencySetter transparencySetter = null;
+
+    /**
+     * Creates a new FeatureRenderer object.
+     *
+     * @param av DOCUMENT ME!
+     */
+    public FeatureRenderer(AlignViewport av)
+    {
+        this.av = av;
+
+        if(!System.getProperty("java.version").startsWith("1.1"))
+             transparencySetter = new TransparencySetter();
+    }
+
+
+    public void transferSettings(FeatureRenderer fr)
+    {
+      renderOrder = fr.renderOrder;
+      featureGroups = fr.featureGroups;
+      featureColours = fr.featureColours;
+      transparency =  fr.transparency;
+    }
+
+
+    public Color findFeatureColour(Color initialCol, SequenceI seq, int i)
+    {
+      overview = true;
+      if(!av.showSequenceFeatures)
+        return initialCol;
+
+        lastSequence = seq;
+        sequenceFeatures = lastSequence.getSequenceFeatures();
+        if(sequenceFeatures==null)
+          return initialCol;
+
+        sfSize = sequenceFeatures.length;
+
+      if(jalview.util.Comparison.isGap(lastSequence.getCharAt(i)))
+        return Color.white;
+
+      currentColour = null;
+
+      drawSequence(null, lastSequence, lastSequence.findPosition(i), -1,-1);
+
+      if(currentColour==null)
+        return initialCol;
+
+      return new Color( ((Integer)currentColour).intValue() );
+    }
+
+    /**
+     * This is used by the Molecule Viewer to get the accurate colour
+     * of the rendered sequence
+     */
+    boolean overview = false;
+
+    int white = Color.white.getRGB();
+    public int findFeatureColour(int initialCol, int seqIndex, int column)
+    {
+      if(!av.showSequenceFeatures)
+        return initialCol;
+
+      if(seqIndex!=lastSequenceIndex)
+      {
+        lastSequence = av.alignment.getSequenceAt(seqIndex);
+        lastSequenceIndex = seqIndex;
+        sequenceFeatures = lastSequence.getSequenceFeatures();
+        if(sequenceFeatures==null)
+          return initialCol;
+
+        sfSize = sequenceFeatures.length;
+      }
+
+
+      if(jalview.util.Comparison.isGap(lastSequence.getCharAt(column)))
+        return Color.white.getRGB();
+
+      currentColour = null;
+
+      drawSequence(null, lastSequence, lastSequence.findPosition(column), -1,-1);
+
+      if(currentColour==null)
+        return initialCol;
+
+      return  ((Integer)currentColour).intValue();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     * @param sg DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+   // String type;
+   // SequenceFeature sf;
+    int lastSequenceIndex=-1;
+    SequenceI lastSequence;
+    SequenceFeature [] sequenceFeatures;
+    int sfSize, sfindex, spos, epos;
+
+    public void drawSequence(Graphics g, SequenceI seq,
+                             int start, int end, int y1)
+    {
+      if (   seq.getSequenceFeatures() == null
+          || seq.getSequenceFeatures().length==0)
+        return;
+
+      if(transparencySetter!=null && g!=null)
+      {
+        transparencySetter.setTransparency(g, transparency);
+      }
+
+      if (av.featuresDisplayed == null || renderOrder==null)
+       {
+         findAllFeatures();
+         if(av.featuresDisplayed.size()<1)
+           return;
+
+         sequenceFeatures = seq.getSequenceFeatures();
+         sfSize = sequenceFeatures.length;
+       }
+       if(lastSequence==null || seq!=lastSequence)
+      {
+        lastSequence = seq;
+        sequenceFeatures = seq.getSequenceFeatures();
+        sfSize = sequenceFeatures.length;
+      }
+      if(!overview)
+      {
+        spos = lastSequence.findPosition(start);
+        epos = lastSequence.findPosition(end);
+        if(g!=null)
+          fm = g.getFontMetrics();
+      }
+      String type;
+      for(int renderIndex=0; renderIndex<renderOrder.length; renderIndex++)
+       {
+        type =  renderOrder[renderIndex];
+        if(!av.featuresDisplayed.containsKey(type))
+          continue;
+
+        // loop through all features in sequence to find
+        // current feature to render
+        for (sfindex = 0; sfindex < sfSize; sfindex++)
+        {
+          if (!sequenceFeatures[sfindex].type.equals(type))
+            continue;
+
+          if (featureGroups != null
+              && sequenceFeatures[sfindex].featureGroup != null
+              &&
+              featureGroups.containsKey(sequenceFeatures[sfindex].featureGroup)
+              &&
+              ! ( (Boolean) featureGroups.get(sequenceFeatures[sfindex].featureGroup)).
+              booleanValue())
+          {
+            continue;
+          }
+
+          if (!overview && (sequenceFeatures[sfindex].getBegin() > epos
+                            || sequenceFeatures[sfindex].getEnd() < spos))
+            continue;
+
+          if (overview)
+          {
+            if (sequenceFeatures[sfindex].begin <= start &&
+                sequenceFeatures[sfindex].end >= start)
+            {
+              currentColour = av.featuresDisplayed.get(sequenceFeatures[sfindex].
+                  type);
+            }
+
+          }
+          else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
+          {
+
+            renderFeature(g, seq,
+                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                          new Color( ( (Integer) av.featuresDisplayed.get(
+                sequenceFeatures[sfindex].type)).intValue()),
+                          start, end, y1);
+            renderFeature(g, seq,
+                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                          new Color( ( (Integer) av.featuresDisplayed.get(
+                sequenceFeatures[sfindex].type)).intValue()),
+                          start, end, y1);
+
+          }
+          else
+            renderFeature(g, seq,
+                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                          getColour(sequenceFeatures[sfindex].type),
+                          start, end, y1);
+
+        }
+      }
+
+      if(transparencySetter!=null && g!=null)
+      {
+        transparencySetter.setTransparency(g, 1.0f);
+      }
+    }
+
+
+    char s;
+    int i;
+    void renderFeature(Graphics g, SequenceI seq,
+                       int fstart, int fend, Color featureColour, int start, int end,  int y1)
+    {
+
+      if (((fstart <= end) && (fend >= start)))
+      {
+        if (fstart < start)
+        { // fix for if the feature we have starts before the sequence start,
+          fstart = start; // but the feature end is still valid!!
+        }
+
+        if (fend >= end)
+        {
+          fend = end;
+        }
+
+          for (i = fstart; i <= fend; i++)
+          {
+            s = seq.getSequence().charAt(i);
+
+            if (jalview.util.Comparison.isGap(s))
+            {
+              continue;
+            }
+
+            g.setColor(featureColour);
+
+            g.fillRect( (i - start) * av.charWidth, y1, av.charWidth, av.charHeight);
+
+            if(!av.validCharWidth)
+              continue;
+
+            g.setColor(Color.white);
+            charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+            g.drawString(String.valueOf(s),
+                         charOffset + (av.charWidth * (i - start)),
+                         (y1 + av.charHeight) - av.charHeight / 5); //pady = height / 5;
+
+          }
+      }
+    }
+
+    void findAllFeatures()
+    {
+      jalview.schemes.UserColourScheme ucs = new
+          jalview.schemes.UserColourScheme();
+
+      av.featuresDisplayed = new Hashtable();
+      Vector allfeatures = new Vector();
+      for (int i = 0; i < av.alignment.getHeight(); i++)
+      {
+        SequenceFeature [] features = av.alignment.getSequenceAt(i).getSequenceFeatures();
+
+        if (features == null)
+          continue;
+
+        int index = 0;
+        while (index < features.length)
+        {
+          if (!av.featuresDisplayed.containsKey(features[index].getType()))
+          {
+            if (getColour(features[index].getType()) == null)
+            {
+              featureColours.put(features[index].getType(),
+                                 ucs.createColourFromName(features[index].
+                  getType()));
+            }
+
+
+            av.featuresDisplayed.put(features[index].getType(),
+                                  new Integer( getColour(features[index].getType()).getRGB()) );
+            allfeatures.addElement(features[index].getType());
+          }
+          index++;
+        }
+      }
+
+      renderOrder = new String[allfeatures.size()];
+      Enumeration en = allfeatures.elements();
+      int i = allfeatures.size()-1;
+      while(en.hasMoreElements())
+      {
+        renderOrder[i] = en.nextElement().toString();
+        i--;
+      }
+    }
+
+    public Color getColour(String featureType)
+    {
+      return (Color)featureColours.get(featureType);
+    }
+
+    public void addNewFeature(String name, Color col)
+    {
+
+      setColour(name, col);
+      if(av.featuresDisplayed==null)
+        av.featuresDisplayed = new Hashtable();
+
+
+      av.featuresDisplayed.put(name, "NOGROUP");
+    }
+
+    public void setColour(String featureType, Color col)
+    {
+      featureColours.put(featureType, col);
+    }
+
+    public void setFeaturePriority(Object [][] data)
+    {
+        // The feature table will display high priority
+        // features at the top, but theses are the ones
+        // we need to render last, so invert the data
+        if(av.featuresDisplayed!=null)
+          av.featuresDisplayed.clear();
+
+        renderOrder = new String[data.length];
+
+        if (data.length > 0)
+          for (int i = 0; i < data.length; i++)
+          {
+            String type = data[i][0].toString();
+            setColour(type, (Color) data[i][1]);
+            if ( ( (Boolean) data[i][2]).booleanValue())
+            {
+              av.featuresDisplayed.put(type, new Integer(getColour(type).getRGB()));
+            }
+
+            renderOrder[data.length - i - 1] = type;
+          }
+    }
+}
+
+  class TransparencySetter
+  {
+    void setTransparency(Graphics g, float value)
+    {
+     Graphics2D g2 = (Graphics2D) g;
+     g2.setComposite(
+        AlphaComposite.getInstance(
+             AlphaComposite.SRC_OVER, value));
+    }
+  }
+
+
+
+
index 6710ed4..77d221e 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.appletgui;\r
-\r
-import jalview.datamodel.*;\r
-import java.awt.*;\r
-import java.util.*;\r
-import java.awt.event.*;\r
-\r
-\r
-public class FeatureSettings extends Panel implements ItemListener,\r
-    MouseListener, MouseMotionListener\r
-{\r
-  FeatureRenderer fr;\r
-  AlignmentPanel ap;\r
-  AlignViewport av;\r
-  Frame frame;\r
-  Panel groupPanel;\r
-  Panel featurePanel = new Panel();\r
-  ScrollPane scrollPane;\r
-  boolean alignmentHasFeatures = false;\r
-\r
-  public FeatureSettings(AlignViewport av, final AlignmentPanel ap)\r
-  {\r
-    this.ap = ap;\r
-    this.av = av;\r
-    fr = ap.seqPanel.seqCanvas.getFeatureRenderer();\r
-\r
-    setTableData();\r
-\r
-    this.setLayout(new BorderLayout());\r
-    scrollPane = new ScrollPane();\r
-    scrollPane.add(featurePanel);\r
-    if (alignmentHasFeatures)\r
-      add(scrollPane, BorderLayout.CENTER);\r
-\r
-    if(groupPanel!=null)\r
-    {\r
-      groupPanel.setLayout(\r
-          new GridLayout( fr.featureGroups.size() / 4 + 1, 4));\r
-      groupPanel.validate();\r
-\r
-      add(groupPanel, BorderLayout.NORTH);\r
-    }\r
-    frame = new Frame();\r
-    frame.add(this);\r
-    int height = featurePanel.getComponentCount()*50 +30;\r
-\r
-    height = Math.max(100, height);\r
-    height = Math.min(400, height);\r
-\r
-    jalview.bin.JalviewLite.addFrame(frame, "Feature Settings", 280,\r
-                                     height);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    g.setColor(Color.black);\r
-    g.drawString("No Features added to this alignment!!", 10, 20);\r
-  }\r
-\r
-  void setTableData()\r
-  {\r
-    alignmentHasFeatures = false;\r
-\r
-    if(fr.featureGroups==null)\r
-      fr.featureGroups = new Hashtable();\r
-\r
-    Vector allFeatures = new Vector();\r
-    Vector allGroups = new Vector();\r
-    SequenceFeature[] tmpfeatures;\r
-    String group;\r
-\r
-\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
-    {\r
-      if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)\r
-        continue;\r
-\r
-      alignmentHasFeatures = true;\r
-\r
-      tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();\r
-      int index = 0;\r
-      while (index < tmpfeatures.length)\r
-      {\r
-        if(tmpfeatures[index].getFeatureGroup()!=null)\r
-        {\r
-          group = tmpfeatures[index].featureGroup;\r
-          if(!allGroups.contains(group))\r
-           {\r
-             allGroups.addElement(group);\r
-\r
-             boolean visible = true;\r
-             if (fr.featureGroups.containsKey(group))\r
-             {\r
-               visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();\r
-             }\r
-\r
-             fr.featureGroups.put(group, new Boolean(visible));\r
-\r
-             if (groupPanel == null)\r
-             {\r
-               groupPanel = new Panel();\r
-             }\r
-\r
-             Checkbox check = new Checkbox(group, visible);\r
-             check.setFont(new Font("Serif", Font.BOLD, 12));\r
-             check.addItemListener(this);\r
-             groupPanel.add(check);\r
-           }\r
-        }\r
-\r
-        if (!allFeatures.contains(tmpfeatures[index].getType()))\r
-        {\r
-            allFeatures.addElement(tmpfeatures[index].getType());\r
-        }\r
-         index ++;\r
-      }\r
-    }\r
-\r
-    resetTable(false);\r
-  }\r
-\r
- //This routine adds and removes checkboxes depending on\r
- //Group selection states\r
-  void resetTable(boolean groupsChanged)\r
-  {\r
-    SequenceFeature [] tmpfeatures;\r
-    String group=null, type;\r
-    Vector visibleChecks = new Vector();\r
-\r
-     for (int i = 0; i < av.alignment.getHeight(); i++)\r
-     {\r
-         if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)\r
-           continue;\r
-\r
-         tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();\r
-         int index = 0;\r
-         while (index < tmpfeatures.length)\r
-         {\r
-           group = tmpfeatures[index].featureGroup;\r
-\r
-           if (group==null || fr.featureGroups.get(group)==null ||\r
-               ((Boolean) fr.featureGroups.get(group)).booleanValue())\r
-           {\r
-             type = tmpfeatures[index].getType();\r
-             if(!visibleChecks.contains(type) )\r
-             {\r
-               visibleChecks.addElement(type);\r
-             }\r
-           }\r
-           index++;\r
-         }\r
-     }\r
-\r
-       Component[] comps;\r
-       int cSize = featurePanel.getComponentCount();\r
-       Checkbox check;\r
-       //This will remove any checkboxes which shouldn't be\r
-       //visible\r
-       for (int i = 0; i < cSize; i++)\r
-       {\r
-         comps = featurePanel.getComponents();\r
-         check = (Checkbox) comps[i];\r
-         if (!visibleChecks.contains(check.getLabel()))\r
-         {\r
-           featurePanel.remove(i);\r
-           cSize --;\r
-           i--;\r
-         }\r
-       }\r
-\r
-       if(fr.renderOrder!=null)\r
-       {\r
-         //First add the checks in the previous render order,\r
-         //in case the window has been closed and reopened\r
-         for(int ro=fr.renderOrder.length-1; ro>-1; ro--)\r
-         {\r
-              String item = fr.renderOrder[ro];\r
-\r
-              if(!visibleChecks.contains(item))\r
-                continue;\r
-\r
-              visibleChecks.removeElement(item);\r
-\r
-              addCheck(false, item);\r
-         }\r
-       }\r
-\r
-       // now add checkboxes which should be visible,\r
-       // if they have not already been added\r
-       Enumeration en = visibleChecks.elements();\r
-       while(en.hasMoreElements())\r
-       {\r
-         addCheck(groupsChanged, en.nextElement().toString());\r
-       }\r
-\r
-\r
-   featurePanel.setLayout(new GridLayout(featurePanel.getComponentCount(), 1, 10,5));\r
-   featurePanel.validate();\r
-\r
-\r
-   if(scrollPane!=null)\r
-     scrollPane.validate();\r
-\r
-   itemStateChanged(null);\r
-  }\r
-\r
-  void addCheck(boolean groupsChanged, String type)\r
-  {\r
-    boolean addCheck;\r
-    Component [] comps = featurePanel.getComponents();\r
-    Checkbox check;\r
-    addCheck = true;\r
-    for (int i = 0; i < featurePanel.getComponentCount(); i++)\r
-    {\r
-      check = (Checkbox) comps[i];\r
-      if (check.getLabel().equals(type))\r
-      {\r
-        addCheck = false;\r
-        break;\r
-      }\r
-    }\r
-\r
-    if (addCheck)\r
-    {\r
-      boolean selected = false;\r
-      if (groupsChanged || av.featuresDisplayed.containsKey(type))\r
-      {\r
-        selected = true;\r
-      }\r
-\r
-      check = new Checkbox(type, selected);\r
-      check.addMouseListener(this);\r
-      check.addMouseMotionListener(this);\r
-      check.setBackground(fr.getColour(type));\r
-      check.addItemListener(this);\r
-      featurePanel.add(check);\r
-    }\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if (evt != null)\r
-    {\r
-      //Is the source a top level featureGroup?\r
-      Checkbox source = (Checkbox) evt.getSource();\r
-      if (fr.featureGroups.containsKey(source.getLabel()))\r
-      {\r
-        fr.featureGroups.put(source.getLabel(), new Boolean(source.getState()));\r
-        ap.seqPanel.seqCanvas.repaint();\r
-        if (ap.overviewPanel != null)\r
-          ap.overviewPanel.updateOverviewImage();\r
-\r
-        resetTable(true);\r
-        return;\r
-      }\r
-    }\r
-\r
-      Component[] comps = featurePanel.getComponents();\r
-      int cSize = comps.length;\r
-\r
-      Object[][] tmp = new Object[cSize][3];\r
-      int tmpSize = 0;\r
-      for (int i = 0; i < cSize; i++)\r
-      {\r
-        Checkbox check = (Checkbox) comps[i];\r
-        tmp[tmpSize][0] = check.getLabel();\r
-        tmp[tmpSize][1] = fr.getColour(check.getLabel());\r
-        tmp[tmpSize][2] = new Boolean(check.getState());\r
-        tmpSize++;\r
-      }\r
-\r
-      Object[][]data = new Object[tmpSize][3];\r
-      System.arraycopy(tmp, 0, data,0, tmpSize);\r
-\r
-      fr.setFeaturePriority(data);\r
-      ap.seqPanel.seqCanvas.repaint();\r
-      if (ap.overviewPanel != null)\r
-        ap.overviewPanel.updateOverviewImage();\r
-  }\r
-\r
-  Checkbox selectedCheck;\r
-  boolean dragging = false;\r
-\r
-  public void mousePressed(MouseEvent evt)\r
-  {\r
-    selectedCheck = (Checkbox)evt.getSource();\r
-  }\r
-\r
-  public void mouseDragged(MouseEvent evt)\r
-  {\r
-      dragging = true;\r
-  }\r
-\r
-  public void mouseReleased(MouseEvent evt)\r
-  {\r
-    Component comp = null;\r
-    Checkbox  target = null;\r
-\r
-    int height = evt.getY()+evt.getComponent().getLocation().y;\r
-\r
-    if(height > this.getSize().height)\r
-     {\r
-       comp = featurePanel.getComponent(featurePanel.getComponentCount()-1);\r
-     }\r
-     else if(height < 0)\r
-     {\r
-       comp = featurePanel.getComponent(0);\r
-     }\r
-     else\r
-     {\r
-       comp = featurePanel.getComponentAt(evt.getX(),\r
-                                  evt.getY() +\r
-                                  evt.getComponent().getLocation().y);\r
-     }\r
-\r
-    if(comp!=null && comp instanceof Checkbox)\r
-      target = (Checkbox)comp;\r
-\r
-    if (   selectedCheck != null\r
-        && target != null\r
-        && selectedCheck != target)\r
-    {\r
-      int targetIndex = -1;\r
-      for(int i=0; i<featurePanel.getComponentCount(); i++)\r
-      {\r
-          if(target==featurePanel.getComponent(i))\r
-          { targetIndex = i; break; }\r
-      }\r
-\r
-      featurePanel.remove(selectedCheck);\r
-      featurePanel.add(selectedCheck, targetIndex);\r
-      featurePanel.validate();\r
-      itemStateChanged(null);\r
-    }\r
-  }\r
-\r
-  public void setUserColour(String feature, Color col)\r
-  {\r
-    fr.setColour(feature, col);\r
-    featurePanel.removeAll();\r
-    resetTable(false);\r
-    ap.repaint();\r
-  }\r
-\r
-  public void mouseEntered(MouseEvent evt){}\r
-  public void mouseExited(MouseEvent evt){}\r
-  public void mouseClicked(MouseEvent evt)\r
-  {\r
-    Checkbox check = (Checkbox) evt.getSource();\r
-    if(evt.getClickCount()>1)\r
-    {\r
-       new UserDefinedColours(this, check.getLabel(),\r
-                              fr.getColour(check.getLabel()));\r
-    }\r
-  }\r
-  public void mouseMoved(MouseEvent evt){}\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.appletgui;
+
+import jalview.datamodel.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+
+public class FeatureSettings extends Panel implements ItemListener,
+    MouseListener, MouseMotionListener, ActionListener, AdjustmentListener
+{
+  FeatureRenderer fr;
+  AlignmentPanel ap;
+  AlignViewport av;
+  Frame frame;
+  Panel groupPanel;
+  Panel featurePanel = new Panel();
+  ScrollPane scrollPane;
+  boolean alignmentHasFeatures = false;
+  Image linkImage;
+  Scrollbar transparency ;
+
+  public FeatureSettings(AlignViewport av, final AlignmentPanel ap)
+  {
+    this.ap = ap;
+    this.av = av;
+    fr = ap.seqPanel.seqCanvas.getFeatureRenderer();
+
+    transparency = new Scrollbar(Scrollbar.HORIZONTAL,
+     100 - (int)(fr.transparency*100), 1, 1, 100);
+
+    if(fr.transparencySetter!=null)
+    {
+      transparency.addAdjustmentListener(this);
+    }
+    else
+      transparency.setEnabled(false);
+
+    java.net.URL url = getClass().getResource("/images/link.gif");
+    if (url != null)
+    {
+      linkImage = java.awt.Toolkit.getDefaultToolkit().getImage(url);
+    }
+
+
+    if(av.featuresDisplayed==null)
+      fr.findAllFeatures();
+
+    setTableData();
+
+    this.setLayout(new BorderLayout());
+    scrollPane = new ScrollPane();
+    scrollPane.add(featurePanel);
+    if (alignmentHasFeatures)
+      add(scrollPane, BorderLayout.CENTER);
+
+    Button invert = new Button("Invert Selection");
+    invert.addActionListener(this);
+
+    Panel lowerPanel = new Panel(new GridLayout(2,1,5,10));
+    lowerPanel.add(invert);
+
+    Panel tPanel = new Panel(new BorderLayout());
+
+    if(fr.transparencySetter!=null)
+    {
+      tPanel.add(transparency, BorderLayout.CENTER);
+      tPanel.add(new Label("Transparency"), BorderLayout.EAST);
+    }
+    else
+      tPanel.add(new Label("Transparency not available in this web browser"), BorderLayout.CENTER);
+
+    lowerPanel.add(tPanel, BorderLayout.SOUTH);
+
+    add(lowerPanel, BorderLayout.SOUTH);
+
+
+
+    if(groupPanel!=null)
+    {
+      groupPanel.setLayout(
+          new GridLayout( fr.featureGroups.size() / 4 + 1, 4));
+      groupPanel.validate();
+
+      add(groupPanel, BorderLayout.NORTH);
+    }
+    frame = new Frame();
+    frame.add(this);
+    int height = featurePanel.getComponentCount()*50 +60;
+
+
+    height = Math.max(200, height);
+    height = Math.min(400, height);
+
+    jalview.bin.JalviewLite.addFrame(frame, "Feature Settings", 280,
+                                     height);
+  }
+
+  public void paint(Graphics g)
+  {
+    g.setColor(Color.black);
+    g.drawString("No Features added to this alignment!!", 10, 20);
+    g.drawString("(Features can be added from searches or", 10, 40);
+    g.drawString("from Jalview / GFF features files)", 10, 60);
+  }
+
+  void setTableData()
+  {
+    alignmentHasFeatures = false;
+
+    if(fr.featureGroups==null)
+      fr.featureGroups = new Hashtable();
+
+    Vector allFeatures = new Vector();
+    Vector allGroups = new Vector();
+    SequenceFeature[] tmpfeatures;
+    String group;
+
+
+    for (int i = 0; i < av.alignment.getHeight(); i++)
+    {
+      if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
+        continue;
+
+      alignmentHasFeatures = true;
+
+      tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
+      int index = 0;
+      while (index < tmpfeatures.length)
+      {
+        if(tmpfeatures[index].getFeatureGroup()!=null)
+        {
+          group = tmpfeatures[index].featureGroup;
+          if(!allGroups.contains(group))
+           {
+             allGroups.addElement(group);
+
+             boolean visible = true;
+             if (fr.featureGroups.containsKey(group))
+             {
+               visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();
+             }
+
+             fr.featureGroups.put(group, new Boolean(visible));
+
+             if (groupPanel == null)
+             {
+               groupPanel = new Panel();
+             }
+
+             Checkbox check =  new MyCheckbox(
+                group,
+                visible,
+                (fr.featureLinks!=null && fr.featureLinks.containsKey(group))
+                 );
+
+
+             check.addMouseListener(this);
+             check.setFont(new Font("Serif", Font.BOLD, 12));
+             check.addItemListener(this);
+             groupPanel.add(check);
+           }
+        }
+
+        if (!allFeatures.contains(tmpfeatures[index].getType()))
+        {
+            allFeatures.addElement(tmpfeatures[index].getType());
+        }
+         index ++;
+      }
+    }
+
+    resetTable(false);
+  }
+
+ //This routine adds and removes checkboxes depending on
+ //Group selection states
+  void resetTable(boolean groupsChanged)
+  {
+    SequenceFeature [] tmpfeatures;
+    String group=null, type;
+    Vector visibleChecks = new Vector();
+
+     for (int i = 0; i < av.alignment.getHeight(); i++)
+     {
+         if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
+           continue;
+
+         tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
+         int index = 0;
+         while (index < tmpfeatures.length)
+         {
+           group = tmpfeatures[index].featureGroup;
+
+           if (group==null || fr.featureGroups.get(group)==null ||
+               ((Boolean) fr.featureGroups.get(group)).booleanValue())
+           {
+             type = tmpfeatures[index].getType();
+             if(!visibleChecks.contains(type) )
+             {
+               visibleChecks.addElement(type);
+             }
+           }
+           index++;
+         }
+     }
+
+       Component[] comps;
+       int cSize = featurePanel.getComponentCount();
+       Checkbox check;
+       //This will remove any checkboxes which shouldn't be
+       //visible
+       for (int i = 0; i < cSize; i++)
+       {
+         comps = featurePanel.getComponents();
+         check = (Checkbox) comps[i];
+         if (!visibleChecks.contains(check.getLabel()))
+         {
+           featurePanel.remove(i);
+           cSize --;
+           i--;
+         }
+       }
+
+       if(fr.renderOrder!=null)
+       {
+         //First add the checks in the previous render order,
+         //in case the window has been closed and reopened
+         for(int ro=fr.renderOrder.length-1; ro>-1; ro--)
+         {
+              String item = fr.renderOrder[ro];
+
+              if(!visibleChecks.contains(item))
+                continue;
+
+              visibleChecks.removeElement(item);
+
+              addCheck(false, item);
+         }
+       }
+
+       // now add checkboxes which should be visible,
+       // if they have not already been added
+       Enumeration en = visibleChecks.elements();
+
+       while(en.hasMoreElements())
+       {
+         addCheck(groupsChanged, en.nextElement().toString());
+       }
+
+
+   featurePanel.setLayout(new GridLayout(featurePanel.getComponentCount(), 1, 10,5));
+   featurePanel.validate();
+
+
+   if(scrollPane!=null)
+     scrollPane.validate();
+
+   itemStateChanged(null);
+  }
+
+  void addCheck(boolean groupsChanged, String type)
+  {
+    boolean addCheck;
+    Component [] comps = featurePanel.getComponents();
+    Checkbox check;
+    addCheck = true;
+    for (int i = 0; i < featurePanel.getComponentCount(); i++)
+    {
+      check = (Checkbox) comps[i];
+      if (check.getLabel().equals(type))
+      {
+        addCheck = false;
+        break;
+      }
+    }
+
+    if (addCheck)
+    {
+      boolean selected = false;
+      if (groupsChanged || av.featuresDisplayed.containsKey(type))
+      {
+        selected = true;
+      }
+
+      check = new MyCheckbox(type,
+                             selected,
+          (fr.featureLinks!=null && fr.featureLinks.containsKey(type))
+           );
+
+      check.addMouseListener(this);
+      check.addMouseMotionListener(this);
+      check.setBackground(fr.getColour(type));
+      check.addItemListener(this);
+      featurePanel.add(check);
+    }
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    for(int i=0; i<featurePanel.getComponentCount(); i++)
+    {
+      Checkbox check = (Checkbox)featurePanel.getComponent(i);
+      check.setState(!check.getState());
+    }
+    selectionChanged();
+  }
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if (evt != null)
+    {
+      //Is the source a top level featureGroup?
+      Checkbox source = (Checkbox) evt.getSource();
+      if (fr.featureGroups.containsKey(source.getLabel()))
+      {
+        fr.featureGroups.put(source.getLabel(), new Boolean(source.getState()));
+        ap.seqPanel.seqCanvas.repaint();
+        if (ap.overviewPanel != null)
+          ap.overviewPanel.updateOverviewImage();
+
+        resetTable(true);
+        return;
+      }
+    }
+    selectionChanged();
+  }
+
+  void selectionChanged()
+  {
+      Component[] comps = featurePanel.getComponents();
+      int cSize = comps.length;
+
+      Object[][] tmp = new Object[cSize][3];
+      int tmpSize = 0;
+      for (int i = 0; i < cSize; i++)
+      {
+        Checkbox check = (Checkbox) comps[i];
+        tmp[tmpSize][0] = check.getLabel();
+        tmp[tmpSize][1] = fr.getColour(check.getLabel());
+        tmp[tmpSize][2] = new Boolean(check.getState());
+        tmpSize++;
+      }
+
+      Object[][]data = new Object[tmpSize][3];
+      System.arraycopy(tmp, 0, data,0, tmpSize);
+
+      fr.setFeaturePriority(data);
+      ap.seqPanel.seqCanvas.repaint();
+      if (ap.overviewPanel != null)
+        ap.overviewPanel.updateOverviewImage();
+  }
+
+  MyCheckbox selectedCheck;
+  boolean dragging = false;
+
+  public void mousePressed(MouseEvent evt)
+  {
+
+    selectedCheck = (MyCheckbox)evt.getSource();
+
+    if(fr.featureLinks!=null
+       && fr.featureLinks.containsKey(selectedCheck.getLabel() )
+        )
+      {
+        if(evt.getX()>selectedCheck.stringWidth+20)
+        {
+          evt.consume();
+        }
+      }
+
+  }
+
+  public void mouseDragged(MouseEvent evt)
+  {
+    if(((Component)evt.getSource()).getParent()!=featurePanel)
+      return;
+      dragging = true;
+  }
+
+  public void mouseReleased(MouseEvent evt)
+  {
+    if(((Component)evt.getSource()).getParent()!=featurePanel)
+      return;
+
+    Component comp = null;
+    Checkbox  target = null;
+
+    int height = evt.getY()+evt.getComponent().getLocation().y;
+
+    if(height > featurePanel.getSize().height)
+     {
+
+       comp = featurePanel.getComponent(featurePanel.getComponentCount()-1);
+     }
+     else if(height < 0)
+     {
+       comp = featurePanel.getComponent(0);
+     }
+     else
+     {
+       comp = featurePanel.getComponentAt(evt.getX(),
+                                  evt.getY() +
+                                  evt.getComponent().getLocation().y);
+     }
+
+    if(comp!=null && comp instanceof Checkbox)
+      target = (Checkbox)comp;
+
+    if (   selectedCheck != null
+        && target != null
+        && selectedCheck != target)
+    {
+      int targetIndex = -1;
+      for(int i=0; i<featurePanel.getComponentCount(); i++)
+      {
+          if(target==featurePanel.getComponent(i))
+          { targetIndex = i; break; }
+      }
+
+      featurePanel.remove(selectedCheck);
+      featurePanel.add(selectedCheck, targetIndex);
+      featurePanel.validate();
+      itemStateChanged(null);
+    }
+  }
+
+  public void setUserColour(String feature, Color col)
+  {
+    fr.setColour(feature, col);
+    featurePanel.removeAll();
+    resetTable(false);
+    ap.repaint();
+  }
+
+  public void mouseEntered(MouseEvent evt){}
+  public void mouseExited(MouseEvent evt){}
+  public void mouseClicked(MouseEvent evt)
+  {
+    MyCheckbox check = (MyCheckbox) evt.getSource();
+
+    if (fr.featureLinks!=null
+        && fr.featureLinks.containsKey(check.getLabel()))
+    {
+      if (evt.getX() > check.stringWidth + 20)
+      {
+        evt.consume();
+        String link = fr.featureLinks.get(check.getLabel()).toString();
+        ap.alignFrame.showURL(link.substring(link.indexOf("|") + 1),
+                              link.substring(0, link.indexOf("|")));
+      }
+    }
+
+    if(check.getParent()!=featurePanel)
+      return;
+
+    if(evt.getClickCount()>1)
+    {
+       new UserDefinedColours(this, check.getLabel(),
+                              fr.getColour(check.getLabel()));
+    }
+  }
+  public void mouseMoved(MouseEvent evt){}
+
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+    fr.transparency = ( (float) (100 - transparency.getValue()) / 100f);
+    ap.seqPanel.seqCanvas.repaint();
+
+  }
+
+  class MyCheckbox extends Checkbox
+  {
+    public int stringWidth;
+    boolean hasLink;
+    public MyCheckbox(String label, boolean checked, boolean haslink)
+    {
+      super(label, checked);
+
+      FontMetrics fm = av.nullFrame.getFontMetrics(av.nullFrame.getFont());
+      stringWidth = fm.stringWidth(label);
+      this.hasLink = haslink;
+    }
+
+    public void paint(Graphics g)
+    {
+      if (hasLink)
+        g.drawImage(linkImage, stringWidth + 25,(
+        getSize().height-linkImage.getHeight(this))/2,
+                    this);
+    }
+  }
+}
+
+
index 1201278..1fe05ac 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class Finder extends Panel implements ActionListener\r
-{\r
-  AlignViewport av;\r
-  AlignmentPanel ap;\r
-  Frame frame;\r
-\r
-  SearchResults searchResults;\r
-\r
-  int seqIndex = 0;\r
-  int resIndex = 0;\r
-  public Finder(final AlignmentPanel ap)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    this.av = ap.av;\r
-    this.ap = ap;\r
-    frame = new Frame();\r
-    frame.add(this);\r
-    jalview.bin.JalviewLite.addFrame(frame, "Find", 340, 120);\r
-    frame.repaint();\r
-    frame.addWindowListener(new WindowAdapter()\r
-    {\r
-      public void windowClosing(WindowEvent evt)\r
-      {\r
-        ap.highlightSearchResults(null);\r
-      }\r
-    });\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if (evt.getSource() == textfield)\r
-      doSearch(false);\r
-\r
-    else if (evt.getSource() == findNext)\r
-      doSearch(false);\r
-\r
-    else if (evt.getSource() == findAll)\r
-    {\r
-      resIndex = 0;\r
-      seqIndex = 0;\r
-      doSearch(true);\r
-    }\r
-    else if(evt.getSource() == createNewGroup)\r
-      createNewGroup_actionPerformed();\r
-  }\r
-\r
-\r
-  public void createNewGroup_actionPerformed()\r
-  {\r
-\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(true, null);\r
-    Dialog dialog = new Dialog(ap.alignFrame, "Enter New Feature Name", true);\r
-    dialog.add(cap);\r
-\r
-    cap.setText(textfield.getText());\r
-\r
-    dialog.setBounds( frame.getLocation().x+frame.getSize().width+5,\r
-                      frame.getLocation().y+20,300,100);\r
-    dialog.show();\r
-\r
-\r
-    String featureName = cap.getText().trim();\r
-    if(featureName.length()<1)\r
-      return;\r
-\r
-\r
-    for (int i = 0; i < searchResults.getSize(); i ++ )\r
-    {\r
-        SequenceI seq = searchResults.getResultSequence(i);\r
-\r
-        SequenceFeature sf = new SequenceFeature(featureName,\r
-            null, null,\r
-            searchResults.getResultStart(i),\r
-           searchResults.getResultEnd(i), "Search Results");\r
-\r
-        ap.seqPanel.seqCanvas.getFeatureRenderer().addNewFeature(\r
-            featureName, new Color(60,160,115));\r
-        seq.addSequenceFeature(sf);\r
-    }\r
-\r
-    ap.seqPanel.seqCanvas.getFeatureRenderer().findAllFeatures();\r
-    ap.alignFrame.sequenceFeatures.setState(true);\r
-    av.showSequenceFeatures(true);\r
-    ap.highlightSearchResults(null);\r
-  }\r
-\r
-  void doSearch(boolean findAll)\r
-  {\r
-    createNewGroup.setEnabled(false);\r
-\r
-    String searchString = textfield.getText().toUpperCase();\r
-\r
-    com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);\r
-\r
-    searchResults = new SearchResults();\r
-\r
-    Sequence seq;\r
-    String item = null;\r
-    boolean found = false;\r
-\r
-    ////// is the searchString a residue number?\r
-    try\r
-    {\r
-      int res = Integer.parseInt(searchString);\r
-      found = true;\r
-\r
-      if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize() < 1)\r
-      {\r
-        seq = (Sequence) av.getAlignment().getSequenceAt(0);\r
-      }\r
-      else\r
-      {\r
-        seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));\r
-      }\r
-\r
-\r
-      searchResults.addResult(seq, res, res);\r
-\r
-    }\r
-    catch (NumberFormatException ex)\r
-    {}\r
-    ///////////////////////////////////////////////\r
-\r
-\r
-    int end = av.alignment.getHeight();\r
-\r
-    SequenceGroup selection = av.getSelectionGroup();\r
-    if (selection != null)\r
-    {\r
-      if (selection.getSize() < 1 ||\r
-          (selection.getEndRes() - selection.getStartRes() < 2))\r
-      {\r
-        selection = null;\r
-      }\r
-    }\r
-\r
-    while (!found && seqIndex < end)\r
-    {\r
-\r
-      seq = (Sequence) av.alignment.getSequenceAt(seqIndex);\r
-\r
-      if (selection != null && !selection.sequences.contains(seq))\r
-      {\r
-        seqIndex++;\r
-        resIndex = 0;\r
-        continue;\r
-      }\r
-\r
-      item = seq.getSequence().toUpperCase();\r
-\r
-      if (selection != null && selection.getEndRes() < av.alignment.getWidth())\r
-      {\r
-        item = item.substring(0, selection.getEndRes() + 1);\r
-      }\r
-\r
-      ///Shall we ignore gaps????\r
-      StringBuffer noGapsSB = new StringBuffer();\r
-      int insertCount = 0;\r
-      Vector spaces = new Vector();\r
-\r
-      for (int j = 0; j < item.length(); j++)\r
-      {\r
-\r
-        if (!jalview.util.Comparison.isGap(item.charAt(j)))\r
-        {\r
-          noGapsSB.append(item.charAt(j));\r
-          spaces.addElement(new Integer(insertCount));\r
-        }\r
-        else\r
-        {\r
-          insertCount++;\r
-        }\r
-      }\r
-\r
-      String noGaps = noGapsSB.toString();\r
-\r
-      for (int r = resIndex; r < noGaps.length(); r++)\r
-      {\r
-\r
-        if (regex.searchFrom(noGaps, r))\r
-        {\r
-          resIndex = regex.matchedFrom();\r
-          if (selection != null &&\r
-              (resIndex + Integer.parseInt(spaces.elementAt(resIndex).toString())) <\r
-              selection.getStartRes())\r
-          {\r
-            continue;\r
-          }\r
-\r
-\r
-          int sres = seq.findPosition(resIndex +\r
-                                      Integer.parseInt(spaces.\r
-              elementAt(resIndex).toString()));\r
-          int eres = seq.findPosition(regex.matchedTo() - 1 +\r
-                                      Integer.parseInt(\r
-                                      spaces.elementAt(regex.matchedTo() - 1).\r
-                                      toString()));\r
-\r
-          searchResults.addResult(seq, sres, eres);\r
-\r
-          if (!findAll)\r
-          {\r
-            // thats enough, break and display the result\r
-            found = true;\r
-            resIndex++;\r
-            break;\r
-          }\r
-\r
-          r = resIndex;\r
-        }\r
-        else\r
-          break;\r
-      }\r
-      if (!found)\r
-      {\r
-        seqIndex++;\r
-        resIndex = 0;\r
-      }\r
-    }\r
-\r
-    Vector idMatch = new Vector();\r
-    for (int id = 0; id < av.alignment.getHeight(); id++)\r
-    {\r
-      if (regex.search(av.alignment.getSequenceAt(id).getName()))\r
-      {\r
-        idMatch.addElement(av.alignment.getSequenceAt(id));\r
-      }\r
-    }\r
-\r
-    if (searchResults.getSize() == 0 && idMatch.size() > 0)\r
-    {\r
-      ap.idPanel.highlightSearchResults(idMatch);\r
-    }\r
-\r
-    if (searchResults.getSize() > 0)\r
-    {\r
-      createNewGroup.setEnabled(true);\r
-    }\r
-    else\r
-    {\r
-      searchResults = null;\r
-      resIndex = 0;\r
-      seqIndex = 0;\r
-    }\r
-\r
-    // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
-    ap.highlightSearchResults(searchResults);\r
-\r
-    if (findAll)\r
-    {\r
-      String message = (searchResults==null?0 : searchResults.getSize()) + " matches found.";\r
-      ap.alignFrame.statusBar.setText("Search results: "+searchString+" : "+message);\r
-    }\r
-\r
-  }\r
-\r
-  Label jLabel1 = new Label();\r
-  protected TextField textfield = new TextField();\r
-  protected Button findAll = new Button();\r
-  protected Button findNext = new Button();\r
-  Panel jPanel1 = new Panel();\r
-  GridLayout gridLayout1 = new GridLayout();\r
-  protected Button createNewGroup = new Button();\r
-\r
-\r
-  private void jbInit() throws Exception {\r
-      jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));\r
-      jLabel1.setText("Find");\r
-      jLabel1.setBounds(new Rectangle(3, 30, 34, 15));\r
-      this.setLayout(null);\r
-      textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
-      textfield.setText("");\r
-      textfield.setBounds(new Rectangle(40, 27, 133, 21));\r
-      textfield.addKeyListener(new java.awt.event.KeyAdapter() {\r
-              public void keyTyped(KeyEvent e) {\r
-                  textfield_keyTyped(e);\r
-              }\r
-          });\r
-      textfield.addActionListener(this);\r
-      findAll.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
-      findAll.setLabel("Find all");\r
-      findAll.addActionListener(this);\r
-      findNext.setEnabled(false);\r
-      findNext.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
-      findNext.setLabel("Find Next");\r
-      findNext.addActionListener(this);\r
-      jPanel1.setBounds(new Rectangle(180, 5, 141, 64));\r
-      jPanel1.setLayout(gridLayout1);\r
-      gridLayout1.setHgap(0);\r
-      gridLayout1.setRows(3);\r
-      gridLayout1.setVgap(2);\r
-      createNewGroup.setEnabled(false);\r
-      createNewGroup.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
-      createNewGroup.setLabel("New Feature");\r
-      createNewGroup.addActionListener(this);\r
-      jPanel1.add(findNext, null);\r
-      jPanel1.add(findAll, null);\r
-      jPanel1.add(createNewGroup, null);\r
-      this.add(textfield, null);\r
-      this.add(jLabel1, null);\r
-      this.add(jPanel1, null);\r
-  }\r
-\r
-  void textfield_keyTyped(KeyEvent e) {\r
-      findNext.setEnabled(true);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import java.awt.Rectangle;
+
+public class Finder extends Panel implements ActionListener
+{
+  AlignViewport av;
+  AlignmentPanel ap;
+  Frame frame;
+
+  SearchResults searchResults;
+
+  int seqIndex = 0;
+  int resIndex = 0;
+  public Finder(final AlignmentPanel ap)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    this.av = ap.av;
+    this.ap = ap;
+    frame = new Frame();
+    frame.add(this);
+    jalview.bin.JalviewLite.addFrame(frame, "Find", 340, 120);
+    frame.repaint();
+    frame.addWindowListener(new WindowAdapter()
+    {
+      public void windowClosing(WindowEvent evt)
+      {
+        ap.highlightSearchResults(null);
+      }
+    });
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if (evt.getSource() == textfield)
+      doSearch(false);
+
+    else if (evt.getSource() == findNext)
+      doSearch(false);
+
+    else if (evt.getSource() == findAll)
+    {
+      resIndex = 0;
+      seqIndex = 0;
+      doSearch(true);
+    }
+    else if(evt.getSource() == createNewGroup)
+      createNewGroup_actionPerformed();
+  }
+
+
+  public void createNewGroup_actionPerformed()
+  {
+
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(true, null);
+    Dialog dialog = new Dialog(ap.alignFrame, "Enter New Feature Name", true);
+    dialog.add(cap);
+
+    cap.setText(textfield.getText());
+
+    dialog.setBounds( frame.getLocation().x+frame.getSize().width+5,
+                      frame.getLocation().y+20,300,100);
+    dialog.show();
+
+
+    String featureName = cap.getText().trim();
+    if(featureName.length()<1)
+      return;
+
+
+    for (int i = 0; i < searchResults.getSize(); i ++ )
+    {
+        SequenceI seq = searchResults.getResultSequence(i);
+
+        SequenceFeature sf = new SequenceFeature(featureName,
+            null, null,
+            searchResults.getResultStart(i),
+           searchResults.getResultEnd(i), "Search Results");
+
+        ap.seqPanel.seqCanvas.getFeatureRenderer().addNewFeature(
+            featureName, new Color(60,160,115));
+        seq.addSequenceFeature(sf);
+    }
+
+    ap.seqPanel.seqCanvas.getFeatureRenderer().findAllFeatures();
+    ap.alignFrame.sequenceFeatures.setState(true);
+    av.showSequenceFeatures(true);
+    ap.highlightSearchResults(null);
+  }
+
+  void doSearch(boolean findAll)
+  {
+    createNewGroup.setEnabled(false);
+
+    String searchString = textfield.getText();
+    if(!caseSensitive.getState())
+      searchString = searchString.toUpperCase();
+
+    com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);
+
+    searchResults = new SearchResults();
+
+    Sequence seq;
+    String item = null;
+    boolean found = false;
+
+    ////// is the searchString a residue number?
+    try
+    {
+      int res = Integer.parseInt(searchString);
+      found = true;
+
+      if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize(false) < 1)
+      {
+        seq = (Sequence) av.getAlignment().getSequenceAt(0);
+      }
+      else
+      {
+        seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));
+      }
+
+
+      searchResults.addResult(seq, res, res);
+
+    }
+    catch (NumberFormatException ex)
+    {}
+    ///////////////////////////////////////////////
+
+
+    int end = av.alignment.getHeight();
+
+    SequenceGroup selection = av.getSelectionGroup();
+    if (selection != null)
+    {
+      if (selection.getSize(false) < 1 ||
+          (selection.getEndRes() - selection.getStartRes() < 2))
+      {
+        selection = null;
+      }
+    }
+
+    while (!found && seqIndex < end)
+    {
+
+      seq = (Sequence) av.alignment.getSequenceAt(seqIndex);
+
+      if (selection != null && !selection.getSequences(false).contains(seq))
+      {
+        seqIndex++;
+        resIndex = 0;
+        continue;
+      }
+
+      item = seq.getSequence();
+      if(!caseSensitive.getState())
+        item = item.toUpperCase();
+
+      if (selection != null && selection.getEndRes() < av.alignment.getWidth())
+      {
+        item = item.substring(0, selection.getEndRes() + 1);
+      }
+
+      ///Shall we ignore gaps????
+      StringBuffer noGapsSB = new StringBuffer();
+      int insertCount = 0;
+      Vector spaces = new Vector();
+
+      for (int j = 0; j < item.length(); j++)
+      {
+
+        if (!jalview.util.Comparison.isGap(item.charAt(j)))
+        {
+          noGapsSB.append(item.charAt(j));
+          spaces.addElement(new Integer(insertCount));
+        }
+        else
+        {
+          insertCount++;
+        }
+      }
+
+      String noGaps = noGapsSB.toString();
+
+      for (int r = resIndex; r < noGaps.length(); r++)
+      {
+
+        if (regex.searchFrom(noGaps, r))
+        {
+          resIndex = regex.matchedFrom();
+          if (selection != null &&
+              (resIndex + Integer.parseInt(spaces.elementAt(resIndex).toString())) <
+              selection.getStartRes())
+          {
+            continue;
+          }
+
+
+          int sres = seq.findPosition(resIndex +
+                                      Integer.parseInt(spaces.
+              elementAt(resIndex).toString()));
+          int eres = seq.findPosition(regex.matchedTo() - 1 +
+                                      Integer.parseInt(
+                                      spaces.elementAt(regex.matchedTo() - 1).
+                                      toString()));
+
+          searchResults.addResult(seq, sres, eres);
+
+          if (!findAll)
+          {
+            // thats enough, break and display the result
+            found = true;
+            resIndex++;
+            break;
+          }
+
+          r = resIndex;
+        }
+        else
+          break;
+      }
+      if (!found)
+      {
+        seqIndex++;
+        resIndex = 0;
+      }
+    }
+
+    Vector idMatch = new Vector();
+    for (int id = 0; id < av.alignment.getHeight(); id++)
+    {
+      if (regex.search(av.alignment.getSequenceAt(id).getName()))
+      {
+        idMatch.addElement(av.alignment.getSequenceAt(id));
+      }
+    }
+
+    if (searchResults.getSize() == 0 && idMatch.size() > 0)
+    {
+      ap.idPanel.highlightSearchResults(idMatch);
+    }
+
+    if (searchResults.getSize() > 0)
+    {
+      createNewGroup.setEnabled(true);
+    }
+    else
+    {
+      searchResults = null;
+      resIndex = 0;
+      seqIndex = 0;
+    }
+
+    // if allResults is null, this effectively switches displaySearch flag in seqCanvas
+    ap.highlightSearchResults(searchResults);
+
+    if (findAll)
+    {
+      String message = (searchResults==null?0 : searchResults.getSize()) + " matches found.";
+      ap.alignFrame.statusBar.setText("Search results: "+searchString+" : "+message);
+    }
+
+  }
+
+  Label jLabel1 = new Label();
+  protected TextField textfield = new TextField();
+  protected Button findAll = new Button();
+  protected Button findNext = new Button();
+  Panel jPanel1 = new Panel();
+  GridLayout gridLayout1 = new GridLayout();
+  protected Button createNewGroup = new Button();
+  Checkbox caseSensitive = new Checkbox();
+
+  private void jbInit() throws Exception {
+      jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
+      jLabel1.setText("Find");
+      jLabel1.setBounds(new Rectangle(3, 30, 34, 15));
+      this.setLayout(null);
+      textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+      textfield.setText("");
+      textfield.setBounds(new Rectangle(40, 27, 133, 21));
+      textfield.addKeyListener(new java.awt.event.KeyAdapter() {
+              public void keyTyped(KeyEvent e) {
+                  textfield_keyTyped(e);
+              }
+          });
+      textfield.addActionListener(this);
+      findAll.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+      findAll.setLabel("Find all");
+      findAll.addActionListener(this);
+      findNext.setEnabled(false);
+      findNext.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+      findNext.setLabel("Find Next");
+      findNext.addActionListener(this);
+      jPanel1.setBounds(new Rectangle(180, 5, 141, 64));
+      jPanel1.setLayout(gridLayout1);
+      gridLayout1.setHgap(0);
+      gridLayout1.setRows(3);
+      gridLayout1.setVgap(2);
+      createNewGroup.setEnabled(false);
+      createNewGroup.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+      createNewGroup.setLabel("New Feature");
+      createNewGroup.addActionListener(this);
+    caseSensitive.setLabel("Match Case");
+    caseSensitive.setBounds(new Rectangle(40, 49, 126, 23));
+    jPanel1.add(findNext, null);
+      jPanel1.add(findAll, null);
+      jPanel1.add(createNewGroup, null);
+    this.add(caseSensitive);
+    this.add(textfield, null);
+      this.add(jLabel1, null);
+      this.add(jPanel1, null);
+  }
+
+  void textfield_keyTyped(KeyEvent e) {
+      findNext.setEnabled(true);
+  }
+
+}
index 843ffe7..e73355f 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-\r
-import java.awt.event.*;\r
-\r
-public class FontChooser\r
-    extends Panel implements ActionListener, ItemListener\r
-{\r
-  AlignmentPanel ap;\r
-  TreePanel tp;\r
-  Font oldFont;\r
-  boolean init = true;\r
-  Frame frame;\r
-\r
-  public FontChooser(TreePanel tp)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    this.tp = tp;\r
-    oldFont = tp.getTreeFont();\r
-    init();\r
-  }\r
-\r
-  public FontChooser(AlignmentPanel ap)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    this.ap = ap;\r
-    oldFont = ap.av.getFont();\r
-    init();\r
-  }\r
-\r
-  void init()\r
-  {\r
-    String fonts[] = Toolkit.getDefaultToolkit().getFontList();\r
-    for (int i = 0; i < fonts.length; i++)\r
-    {\r
-      fontName.addItem(fonts[i]);\r
-    }\r
-\r
-    for (int i = 1; i < 31; i++)\r
-    {\r
-      fontSize.addItem(i + "");\r
-    }\r
-\r
-    fontStyle.addItem("plain");\r
-    fontStyle.addItem("bold");\r
-    fontStyle.addItem("italic");\r
-\r
-    fontName.select(oldFont.getName());\r
-    fontSize.select(oldFont.getSize() + "");\r
-    fontStyle.select(oldFont.getStyle());\r
-\r
-    Frame frame = new Frame();\r
-    this.frame = frame;\r
-    frame.add(this);\r
-    jalview.bin.JalviewLite.addFrame(frame, "Change Font", 440, 115);\r
-\r
-    init = false;\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==ok)\r
-      ok_actionPerformed();\r
-    else if(evt.getSource()==cancel)\r
-      cancel_actionPerformed();\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if(evt.getSource()==fontName)\r
-      fontName_actionPerformed();\r
-    else if(evt.getSource()==fontSize)\r
-      fontSize_actionPerformed();\r
-    else if(evt.getSource()==fontStyle)\r
-      fontStyle_actionPerformed();\r
-  }\r
-\r
-\r
-  protected void ok_actionPerformed()\r
-  {\r
-    frame.setVisible(false);\r
-    if (ap != null)\r
-    {\r
-      if (ap.getOverviewPanel() != null)\r
-      {\r
-        ap.getOverviewPanel().updateOverviewImage();\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  protected void cancel_actionPerformed()\r
-  {\r
-    if(ap!=null)\r
-    {\r
-      ap.av.setFont(oldFont);\r
-      ap.repaint();\r
-    }\r
-    else if(tp!=null)\r
-    {\r
-      tp.setTreeFont(oldFont);\r
-      tp.treeCanvas.repaint();\r
-    }\r
-\r
-    fontName.select(oldFont.getName());\r
-    fontSize.select(oldFont.getSize() + "");\r
-    fontStyle.select(oldFont.getStyle());\r
-\r
-    frame.setVisible(false);\r
-  }\r
-\r
-  void changeFont()\r
-  {\r
-    Font newFont = new Font(fontName.getSelectedItem().toString(),\r
-                            fontStyle.getSelectedIndex(),\r
-                            Integer.parseInt(fontSize.getSelectedItem().\r
-                                             toString())\r
-        );\r
-    if (ap != null)\r
-    {\r
-      ap.av.setFont(newFont);\r
-      ap.fontChanged();\r
-    }\r
-    else if(tp != null)\r
-    {\r
-      tp.setTreeFont(newFont);\r
-      }\r
-  }\r
-\r
-  protected void fontName_actionPerformed()\r
-  {\r
-    if (init)\r
-    {\r
-      return;\r
-    }\r
-    changeFont();\r
-  }\r
-\r
-  protected void fontSize_actionPerformed()\r
-  {\r
-    if (init)\r
-    {\r
-      return;\r
-    }\r
-    changeFont();\r
-  }\r
-\r
-  protected void fontStyle_actionPerformed()\r
-  {\r
-    if (init)\r
-    {\r
-      return;\r
-    }\r
-    changeFont();\r
-  }\r
-  Label label1 = new Label();\r
-  protected Choice fontSize = new Choice();\r
-  protected Choice fontStyle = new Choice();\r
-  Label label2 = new Label();\r
-  Label label3 = new Label();\r
-  protected Choice fontName = new Choice();\r
-  Button ok = new Button();\r
-  Button cancel = new Button();\r
-  Panel panel1 = new Panel();\r
-  Panel panel2 = new Panel();\r
-  Panel panel3 = new Panel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  BorderLayout borderLayout2 = new BorderLayout();\r
-  BorderLayout borderLayout3 = new BorderLayout();\r
-  Panel panel4 = new Panel();\r
-  Panel panel5 = new Panel();\r
-  BorderLayout borderLayout4 = new BorderLayout();\r
-\r
-\r
-  private void jbInit() throws Exception {\r
-      label1.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      label1.setAlignment(Label.RIGHT);\r
-      label1.setText("Font: ");\r
-      this.setLayout(borderLayout4);\r
-      fontSize.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      fontSize.addItemListener(this);\r
-      fontStyle.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      fontStyle.addItemListener(this);\r
-      label2.setAlignment(Label.RIGHT);\r
-      label2.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      label2.setText("Size: ");\r
-      label3.setAlignment(Label.RIGHT);\r
-      label3.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      label3.setText("Style: ");\r
-      fontName.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      fontName.addItemListener(this);\r
-      ok.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      ok.setLabel("OK");\r
-      ok.addActionListener(this);\r
-      cancel.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      cancel.setLabel("Cancel");\r
-      cancel.addActionListener(this);\r
-      this.setBackground(Color.white);\r
-      panel1.setLayout(borderLayout1);\r
-      panel2.setLayout(borderLayout3);\r
-      panel3.setLayout(borderLayout2);\r
-      panel5.setBackground(Color.white);\r
-      panel4.setBackground(Color.white);\r
-      panel1.setBackground(Color.white);\r
-      panel2.setBackground(Color.white);\r
-      panel3.setBackground(Color.white);\r
-      panel1.add(label1, BorderLayout.WEST);\r
-      panel1.add(fontName, BorderLayout.CENTER);\r
-      panel5.add(panel1, null);\r
-      panel5.add(panel3, null);\r
-      panel5.add(panel2, null);\r
-      panel2.add(label3, BorderLayout.WEST);\r
-      panel2.add(fontStyle, BorderLayout.CENTER);\r
-      panel3.add(label2, BorderLayout.WEST);\r
-      panel3.add(fontSize, BorderLayout.CENTER);\r
-      this.add(panel4, BorderLayout.SOUTH);\r
-      panel4.add(ok, null);\r
-      panel4.add(cancel, null);\r
-      this.add(panel5, BorderLayout.CENTER);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+
+import java.awt.event.*;
+
+public class FontChooser
+    extends Panel implements ActionListener, ItemListener
+{
+  AlignmentPanel ap;
+  TreePanel tp;
+  Font oldFont;
+  boolean init = true;
+  Frame frame;
+
+  public FontChooser(TreePanel tp)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    this.tp = tp;
+    oldFont = tp.getTreeFont();
+    init();
+  }
+
+  public FontChooser(AlignmentPanel ap)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    this.ap = ap;
+    oldFont = ap.av.getFont();
+    init();
+  }
+
+  void init()
+  {
+    String fonts[] = Toolkit.getDefaultToolkit().getFontList();
+    for (int i = 0; i < fonts.length; i++)
+    {
+      fontName.addItem(fonts[i]);
+    }
+
+    for (int i = 1; i < 31; i++)
+    {
+      fontSize.addItem(i + "");
+    }
+
+    fontStyle.addItem("plain");
+    fontStyle.addItem("bold");
+    fontStyle.addItem("italic");
+
+    fontName.select(oldFont.getName());
+    fontSize.select(oldFont.getSize() + "");
+    fontStyle.select(oldFont.getStyle());
+
+    Frame frame = new Frame();
+    this.frame = frame;
+    frame.add(this);
+    jalview.bin.JalviewLite.addFrame(frame, "Change Font", 440, 115);
+
+    init = false;
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==ok)
+      ok_actionPerformed();
+    else if(evt.getSource()==cancel)
+      cancel_actionPerformed();
+  }
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if(evt.getSource()==fontName)
+      fontName_actionPerformed();
+    else if(evt.getSource()==fontSize)
+      fontSize_actionPerformed();
+    else if(evt.getSource()==fontStyle)
+      fontStyle_actionPerformed();
+  }
+
+
+  protected void ok_actionPerformed()
+  {
+    frame.setVisible(false);
+    if (ap != null)
+    {
+      if (ap.getOverviewPanel() != null)
+      {
+        ap.getOverviewPanel().updateOverviewImage();
+      }
+    }
+
+  }
+
+  protected void cancel_actionPerformed()
+  {
+    if(ap!=null)
+    {
+      ap.av.setFont(oldFont);
+      ap.repaint();
+    }
+    else if(tp!=null)
+    {
+      tp.setTreeFont(oldFont);
+      tp.treeCanvas.repaint();
+    }
+
+    fontName.select(oldFont.getName());
+    fontSize.select(oldFont.getSize() + "");
+    fontStyle.select(oldFont.getStyle());
+
+    frame.setVisible(false);
+  }
+
+  void changeFont()
+  {
+    Font newFont = new Font(fontName.getSelectedItem().toString(),
+                            fontStyle.getSelectedIndex(),
+                            Integer.parseInt(fontSize.getSelectedItem().
+                                             toString())
+        );
+    if (ap != null)
+    {
+      ap.av.setFont(newFont);
+      ap.fontChanged();
+    }
+    else if(tp != null)
+    {
+      tp.setTreeFont(newFont);
+      }
+  }
+
+  protected void fontName_actionPerformed()
+  {
+    if (init)
+    {
+      return;
+    }
+    changeFont();
+  }
+
+  protected void fontSize_actionPerformed()
+  {
+    if (init)
+    {
+      return;
+    }
+    changeFont();
+  }
+
+  protected void fontStyle_actionPerformed()
+  {
+    if (init)
+    {
+      return;
+    }
+    changeFont();
+  }
+  Label label1 = new Label();
+  protected Choice fontSize = new Choice();
+  protected Choice fontStyle = new Choice();
+  Label label2 = new Label();
+  Label label3 = new Label();
+  protected Choice fontName = new Choice();
+  Button ok = new Button();
+  Button cancel = new Button();
+  Panel panel1 = new Panel();
+  Panel panel2 = new Panel();
+  Panel panel3 = new Panel();
+  BorderLayout borderLayout1 = new BorderLayout();
+  BorderLayout borderLayout2 = new BorderLayout();
+  BorderLayout borderLayout3 = new BorderLayout();
+  Panel panel4 = new Panel();
+  Panel panel5 = new Panel();
+  BorderLayout borderLayout4 = new BorderLayout();
+
+
+  private void jbInit() throws Exception {
+      label1.setFont(new java.awt.Font("Verdana", 0, 11));
+      label1.setAlignment(Label.RIGHT);
+      label1.setText("Font: ");
+      this.setLayout(borderLayout4);
+      fontSize.setFont(new java.awt.Font("Verdana", 0, 11));
+      fontSize.addItemListener(this);
+      fontStyle.setFont(new java.awt.Font("Verdana", 0, 11));
+      fontStyle.addItemListener(this);
+      label2.setAlignment(Label.RIGHT);
+      label2.setFont(new java.awt.Font("Verdana", 0, 11));
+      label2.setText("Size: ");
+      label3.setAlignment(Label.RIGHT);
+      label3.setFont(new java.awt.Font("Verdana", 0, 11));
+      label3.setText("Style: ");
+      fontName.setFont(new java.awt.Font("Verdana", 0, 11));
+      fontName.addItemListener(this);
+      ok.setFont(new java.awt.Font("Verdana", 0, 11));
+      ok.setLabel("OK");
+      ok.addActionListener(this);
+      cancel.setFont(new java.awt.Font("Verdana", 0, 11));
+      cancel.setLabel("Cancel");
+      cancel.addActionListener(this);
+      this.setBackground(Color.white);
+      panel1.setLayout(borderLayout1);
+      panel2.setLayout(borderLayout3);
+      panel3.setLayout(borderLayout2);
+      panel5.setBackground(Color.white);
+      panel4.setBackground(Color.white);
+      panel1.setBackground(Color.white);
+      panel2.setBackground(Color.white);
+      panel3.setBackground(Color.white);
+      panel1.add(label1, BorderLayout.WEST);
+      panel1.add(fontName, BorderLayout.CENTER);
+      panel5.add(panel1, null);
+      panel5.add(panel3, null);
+      panel5.add(panel2, null);
+      panel2.add(label3, BorderLayout.WEST);
+      panel2.add(fontStyle, BorderLayout.CENTER);
+      panel3.add(label2, BorderLayout.WEST);
+      panel3.add(fontSize, BorderLayout.CENTER);
+      this.add(panel4, BorderLayout.SOUTH);
+      panel4.add(ok, null);
+      panel4.add(cancel, null);
+      this.add(panel5, BorderLayout.CENTER);
+  }
+
+}
index 44ba2e0..b8255ca 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class IdCanvas\r
-    extends Panel\r
-{\r
-  protected AlignViewport av;\r
-\r
-  protected boolean showScores = true;\r
-\r
-  protected int maxIdLength = -1;\r
-  protected String maxIdStr = null;\r
-  Image image;\r
-  Graphics gg;\r
-  int imgHeight = 0;\r
-  boolean fastPaint = false;\r
-\r
-  java.util.Vector searchResults;\r
-\r
-  public IdCanvas(AlignViewport av)\r
-  {\r
-    setLayout(null);\r
-    this.av = av;\r
-    PaintRefresher.Register(this, av.alignment);\r
-  }\r
-\r
-  public void drawIdString(Graphics gg, SequenceI s, int i, int starty,\r
-                           int ypos)\r
-  {\r
-    int charHeight = av.getCharHeight();\r
-\r
-    if (searchResults != null && searchResults.contains(s))\r
-    {\r
-      gg.setColor(Color.black);\r
-      gg.fillRect(0, ((i - starty) * charHeight) + ypos,\r
-                  getSize().width, charHeight);\r
-      gg.setColor(Color.white);\r
-    }\r
-    else if (av.getSelectionGroup() != null &&\r
-             av.getSelectionGroup().sequences.contains(s))\r
-    {\r
-      gg.setColor(Color.lightGray);\r
-      gg.fillRect(0, ((i - starty) * charHeight) + ypos,\r
-                  getSize().width, charHeight);\r
-      gg.setColor(Color.white);\r
-    }\r
-    else\r
-    {\r
-      gg.setColor(s.getColor());\r
-      gg.fillRect(0, ((i - starty) * charHeight) + ypos,\r
-                  getSize().width, charHeight);\r
-      gg.setColor(Color.black);\r
-    }\r
-\r
-\r
-    gg.drawString( s.getDisplayId(av.getShowJVSuffix()), 0,\r
-                  ((i - starty) * charHeight) + ypos +\r
-                  charHeight - (charHeight / 5));\r
-\r
-  }\r
-\r
-  public void fastPaint(int vertical)\r
-  {\r
-    if (gg == null)\r
-    {\r
-      repaint();\r
-      return;\r
-    }\r
-\r
-    gg.copyArea(0, 0, getSize().width, imgHeight, 0, -vertical * av.charHeight);\r
-\r
-    int ss = av.startSeq, es = av.endSeq, transY = 0;\r
-    if (vertical > 0) // scroll down\r
-    {\r
-      ss = es - vertical;\r
-      if (ss < av.startSeq) // ie scrolling too fast, more than a page at a time\r
-      {\r
-        ss = av.startSeq;\r
-      }\r
-      else\r
-      {\r
-        transY = imgHeight - vertical * av.charHeight;\r
-      }\r
-    }\r
-    else if (vertical < 0)\r
-    {\r
-      es = ss - vertical;\r
-      if (es > av.endSeq)\r
-      {\r
-        es = av.endSeq;\r
-      }\r
-    }\r
-\r
-    gg.translate(0, transY);\r
-\r
-    drawIds(ss, es);\r
-\r
-    gg.translate(0, -transY);\r
-\r
-    fastPaint = true;\r
-    repaint();\r
-  }\r
-\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    if (getSize().height < 0 || getSize().width < 0)\r
-    {\r
-      return;\r
-    }\r
-    if (fastPaint)\r
-    {\r
-      fastPaint = false;\r
-      g.drawImage(image, 0, 0, this);\r
-      return;\r
-    }\r
-\r
-    imgHeight = getSize().height;\r
-    imgHeight -= imgHeight % av.charHeight;\r
-\r
-    if (imgHeight < 1)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (image == null || imgHeight != image.getHeight(this))\r
-    {\r
-      image = createImage(getSize().width, imgHeight);\r
-      gg = image.getGraphics();\r
-      gg.setFont(av.getFont());\r
-    }\r
-\r
-    //Fill in the background\r
-    gg.setColor(Color.white);\r
-    Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
-                           av.getFont().getSize());\r
-    gg.setFont(italic);\r
-\r
-    gg.fillRect(0, 0, getSize().width, getSize().height);\r
-    drawIds(av.getStartSeq(), av.endSeq);\r
-    g.drawImage(image, 0, 0, this);\r
-  }\r
-\r
-  void drawIds(int starty, int endy)\r
-  {\r
-    Color currentColor = Color.white;\r
-    Color currentTextColor = Color.black;\r
-    Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
-                             av.getFont().getSize());\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      int annotationHeight = 0;\r
-      AnnotationLabels labels = null;\r
-\r
-      if(av.showAnnotation)\r
-      {\r
-        AnnotationPanel ap = new AnnotationPanel(av);\r
-        annotationHeight = ap.adjustPanelHeight();\r
-        labels = new AnnotationLabels(av);\r
-      }\r
-\r
-      int hgap = av.charHeight;\r
-      if (av.scaleAboveWrapped)\r
-        hgap += av.charHeight;\r
-\r
-      int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-          + hgap\r
-          + annotationHeight;\r
-\r
-        int rowSize = av.getEndRes() - av.getStartRes();\r
-\r
-        // Draw the rest of the panels\r
-        for (int ypos = hgap, row = av.startRes;\r
-                (ypos <= getSize().height) && (row < av.alignment.getWidth());\r
-                ypos += cHeight, row += rowSize)\r
-        {\r
-            for (int i = starty; i < av.alignment.getHeight(); i++)\r
-            {\r
-                SequenceI s = av.alignment.getSequenceAt(i);\r
-                gg.setFont(italic);\r
-                drawIdString(gg, s, i, 0, ypos);\r
-            }\r
-\r
-            if(labels!=null)\r
-            {\r
-              gg.translate(0, ypos+(av.getAlignment().getHeight() * av.charHeight));\r
-              labels.drawComponent(gg, getSize().width);\r
-              gg.translate(0, -ypos-(av.getAlignment().getHeight() * av.charHeight));\r
-            }\r
-        }\r
-\r
-    }\r
-    else\r
-    {\r
-\r
-      //Now draw the id strings\r
-      for (int i = starty; i < endy; i++)\r
-      {\r
-        // Selected sequence colours\r
-\r
-        if (searchResults != null &&\r
-            searchResults.contains(av.alignment.getSequenceAt(i)))\r
-        {\r
-          gg.setColor(Color.black);\r
-          currentColor = Color.black;\r
-          currentTextColor = Color.white;\r
-        }\r
-        else if (av.getSelectionGroup() != null\r
-                 &&\r
-                 av.getSelectionGroup().sequences.contains(av.alignment.\r
-            getSequenceAt(i)))\r
-        {\r
-          currentColor = Color.lightGray;\r
-          currentTextColor = Color.black;\r
-        }\r
-        else\r
-        {\r
-          currentColor = av.alignment.getSequenceAt(i).getColor();\r
-          currentTextColor = Color.black;\r
-        }\r
-\r
-        gg.setColor(currentColor);\r
-\r
-        gg.fillRect(0,\r
-                    ((i - starty) * av.charHeight),\r
-                    getSize().width,\r
-                    av.charHeight);\r
-\r
-        gg.setColor(currentTextColor);\r
-\r
-        gg.drawString(av.alignment.getSequenceAt(i)\r
-            .getDisplayId(av.getShowJVSuffix()), 0,\r
-                      ((i - starty) * av.charHeight) +\r
-                      av.charHeight - (av.charHeight / 5));\r
-      }\r
-\r
-      // add a border\r
-      gg.setColor(Color.white);\r
-      gg.fillRect(getSize().width - 4, 0, 4, getSize().height);\r
-    }\r
-\r
-  }\r
-\r
-  public void setHighlighted(java.util.Vector found)\r
-  {\r
-    searchResults = found;\r
-    repaint();\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+
+public class IdCanvas
+    extends Panel
+{
+  protected AlignViewport av;
+
+  protected boolean showScores = true;
+
+  protected int maxIdLength = -1;
+  protected String maxIdStr = null;
+  Image image;
+  Graphics gg;
+  int imgHeight = 0;
+  boolean fastPaint = false;
+
+  java.util.Vector searchResults;
+
+  public IdCanvas(AlignViewport av)
+  {
+    setLayout(null);
+    this.av = av;
+    PaintRefresher.Register(this, av.alignment);
+  }
+
+  public void drawIdString(Graphics gg, SequenceI s, int i, int starty,
+                           int ypos)
+  {
+    int charHeight = av.getCharHeight();
+
+    if (searchResults != null && searchResults.contains(s))
+    {
+      gg.setColor(Color.black);
+      gg.fillRect(0, ((i - starty) * charHeight) + ypos,
+                  getSize().width, charHeight);
+      gg.setColor(Color.white);
+    }
+    else if (av.getSelectionGroup() != null &&
+             av.getSelectionGroup().getSequences(false).contains(s))
+    {
+      gg.setColor(Color.lightGray);
+      gg.fillRect(0, ((i - starty) * charHeight) + ypos,
+                  getSize().width, charHeight);
+      gg.setColor(Color.white);
+    }
+    else
+    {
+      gg.setColor(s.getColor());
+      gg.fillRect(0, ((i - starty) * charHeight) + ypos,
+                  getSize().width, charHeight);
+      gg.setColor(Color.black);
+    }
+
+
+    gg.drawString( s.getDisplayId(av.getShowJVSuffix()), 0,
+                  ((i - starty) * charHeight) + ypos +
+                  charHeight - (charHeight / 5));
+
+    if (av.hasHiddenRows && av.showHiddenMarkers)
+          drawMarker(i, starty, ypos);
+
+  }
+
+  public void fastPaint(int vertical)
+  {
+    if (gg == null)
+    {
+      repaint();
+      return;
+    }
+
+    gg.copyArea(0, 0, getSize().width, imgHeight, 0, -vertical * av.charHeight);
+
+    int ss = av.startSeq, es = av.endSeq, transY = 0;
+    if (vertical > 0) // scroll down
+    {
+      ss = es - vertical;
+      if (ss < av.startSeq) // ie scrolling too fast, more than a page at a time
+      {
+        ss = av.startSeq;
+      }
+      else
+      {
+        transY = imgHeight - vertical * av.charHeight;
+      }
+    }
+    else if (vertical < 0)
+    {
+      es = ss - vertical;
+      if (es > av.endSeq)
+      {
+        es = av.endSeq;
+      }
+    }
+
+    gg.translate(0, transY);
+
+    drawIds(ss, es);
+
+    gg.translate(0, -transY);
+
+    fastPaint = true;
+    repaint();
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  public void paint(Graphics g)
+  {
+    if (getSize().height < 0 || getSize().width < 0)
+    {
+      return;
+    }
+    if (fastPaint)
+    {
+      fastPaint = false;
+      g.drawImage(image, 0, 0, this);
+      return;
+    }
+
+    imgHeight = getSize().height;
+    imgHeight -= imgHeight % av.charHeight;
+
+    if (imgHeight < 1)
+    {
+      return;
+    }
+
+    if (image == null || imgHeight != image.getHeight(this))
+    {
+      image = createImage(getSize().width, imgHeight);
+      gg = image.getGraphics();
+      gg.setFont(av.getFont());
+    }
+
+    //Fill in the background
+    gg.setColor(Color.white);
+    Font italic = new Font(av.getFont().getName(), Font.ITALIC,
+                           av.getFont().getSize());
+    gg.setFont(italic);
+
+    gg.fillRect(0, 0, getSize().width, getSize().height);
+    drawIds(av.startSeq, av.endSeq);
+    g.drawImage(image, 0, 0, this);
+  }
+
+  void drawIds(int starty, int endy)
+  {
+    Font italic = new Font(av.getFont().getName(), Font.ITALIC,
+                           av.getFont().getSize());
+
+    gg.setFont(italic);
+
+    Color currentColor = Color.white;
+    Color currentTextColor = Color.black;
+
+    if (av.getWrapAlignment())
+    {
+      int maxwidth = av.alignment.getWidth();
+      int alheight = av.alignment.getHeight();
+
+      if (av.hasHiddenColumns)
+        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+      int annotationHeight = 0;
+      AnnotationLabels labels = null;
+
+      if (av.showAnnotation)
+      {
+        AnnotationPanel ap = new AnnotationPanel(av);
+        annotationHeight = ap.adjustPanelHeight();
+        labels = new AnnotationLabels(av);
+      }
+
+      int hgap = av.charHeight;
+      if (av.scaleAboveWrapped)
+        hgap += av.charHeight;
+
+      int cHeight = alheight * av.charHeight
+          + hgap
+          + annotationHeight;
+
+      int rowSize = av.getEndRes() - av.getStartRes();
+
+      // Draw the rest of the panels
+      for (int ypos = hgap, row = av.startRes;
+           (ypos <= getSize().height) && (row < maxwidth);
+           ypos += cHeight, row += rowSize)
+      {
+        for (int i = starty; i < alheight; i++)
+        {
+          if (av.hasHiddenRows)
+          {
+            setHiddenFont(i);
+          }
+          else
+            gg.setFont(italic);
+
+          SequenceI s = av.alignment.getSequenceAt(i);
+          drawIdString(gg, s, i, 0, ypos);
+        }
+
+        if (labels != null)
+        {
+          gg.translate(0, ypos + (alheight * av.charHeight));
+          labels.drawComponent(gg, getSize().width);
+          gg.translate(0, -ypos - (alheight * av.charHeight));
+        }
+
+      }
+    }
+    else
+    {
+      //Now draw the id strings
+
+      //Now draw the id strings
+      for (int i = starty; i < endy; i++)
+      {
+        if (av.hasHiddenRows)
+        {
+          setHiddenFont(i);
+        }
+
+        // Selected sequence colours
+        if ( (searchResults != null) &&
+            searchResults.contains(av.alignment.getSequenceAt(i)))
+        {
+          currentColor = Color.black;
+          currentTextColor = Color.white;
+        }
+        else if ( (av.getSelectionGroup() != null) &&
+                 av.getSelectionGroup().getSequences(false).contains(
+                     av.alignment.getSequenceAt(i)))
+        {
+          currentColor = Color.lightGray;
+          currentTextColor = Color.black;
+        }
+        else
+        {
+          currentColor = av.alignment.getSequenceAt(i).getColor();
+          currentTextColor = Color.black;
+        }
+
+        gg.setColor(currentColor);
+
+        gg.fillRect(0, (i - starty) * av.charHeight, getSize().width,
+                    av.charHeight);
+
+        gg.setColor(currentTextColor);
+
+        String string = av.alignment.getSequenceAt(i).getDisplayId(av.
+            getShowJVSuffix());
+
+        gg.drawString(string, 0,
+                      ( ( (i - starty) * av.charHeight) + av.charHeight) -
+                      (av.charHeight / 5));
+
+        if (av.hasHiddenRows && av.showHiddenMarkers)
+          drawMarker(i, starty, 0);
+      }
+    }
+  }
+
+  public void setHighlighted(java.util.Vector found)
+  {
+    searchResults = found;
+    repaint();
+  }
+
+  void drawMarker(int i, int starty, int yoffset)
+  {
+    int hiddenIndex = av.adjustForHiddenSeqs(i);
+    int lastIndex = av.adjustForHiddenSeqs(i - 1);
+    int nextIndex = av.adjustForHiddenSeqs(i + 1);
+
+    boolean below = (hiddenIndex > lastIndex + 1);
+    boolean above = (nextIndex>hiddenIndex+1);
+
+      gg.setColor(Color.blue);
+      if(below)
+      {
+        gg.fillPolygon(new int[]
+                       {getSize().width- av.charHeight,
+                       getSize().width- av.charHeight,
+                       getSize().width},
+                       new int[]
+                       {
+                       (i - starty) * av.charHeight +yoffset,
+                       (i - starty) * av.charHeight +yoffset+ av.charHeight / 4,
+                       (i - starty) * av.charHeight+yoffset
+        }, 3);
+      }
+      if(above)
+      {
+        gg.fillPolygon(new int[]
+                      {getSize().width- av.charHeight,
+                      getSize().width - av.charHeight,
+                      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);
+
+      }
+  }
+
+  void setHiddenFont(int i)
+  {
+  /*  System.out.println(i+" "+av.alignment.getHeight());
+    if (av.alignment.getSequenceAt(i).getHiddenSequences() != null)
+      gg.setFont(new Font(av.getFont().getName(), Font.BOLD,
+                          av.getFont().getSize()));
+    else
+      gg.setFont(new Font(av.getFont().getName(), Font.ITALIC,
+                          av.getFont().getSize()));*/
+  }
+}
index d159a4c..a04d7bf 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class IdPanel\r
-    extends Panel implements MouseListener, MouseMotionListener\r
-{\r
-\r
-  protected IdCanvas idCanvas;\r
-  protected AlignViewport av;\r
-  protected AlignmentPanel alignPanel;\r
-  ScrollThread scrollThread = null;\r
-\r
-  int offy;\r
-  int width;\r
-  int lastid = -1;\r
-  boolean mouseDragging = false;\r
-  java.util.Vector links = new java.util.Vector();\r
-\r
-  public IdPanel(AlignViewport av, AlignmentPanel parent)\r
-  {\r
-    this.av = av;\r
-    alignPanel = parent;\r
-    idCanvas = new IdCanvas(av);\r
-    setLayout(new BorderLayout());\r
-    add(idCanvas, BorderLayout.CENTER);\r
-    idCanvas.addMouseListener(this);\r
-    idCanvas.addMouseMotionListener(this);\r
-\r
-    String label, url;\r
-    if(parent.alignFrame.applet!=null)\r
-    {\r
-      for (int i = 1; i < 10; i++)\r
-      {\r
-        label = parent.alignFrame.applet.getParameter("linkLabel_" + i);\r
-        url = parent.alignFrame.applet.getParameter("linkURL_" + i);\r
-\r
-        if (label != null && url != null)\r
-          links.addElement(label + "|" + url);\r
-\r
-      }\r
-    }\r
-    if (links.size() < 1)\r
-    {\r
-      links = new java.util.Vector();\r
-      links.addElement("SRS|http://srs.ebi.ac.uk/srs7bin/cgi-bin/wgetz?-e+[uniprot-all:$SEQUENCE_ID$]+-vn+2");\r
-    }\r
-  }\r
-\r
-  public void mouseMoved(MouseEvent e)\r
-  {}\r
-\r
-  public void mouseDragged(MouseEvent e)\r
-  {\r
-    mouseDragging = true;\r
-\r
-    int y = e.getY();\r
-    if (av.getWrapAlignment())\r
-    {\r
-      y -= 2 * av.charHeight;\r
-    }\r
-    int seq = av.getIndex(y);\r
-\r
-    if (seq < 0)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (seq < lastid)\r
-    {\r
-      selectSeqs(lastid - 1, seq);\r
-    }\r
-    else if (seq > lastid)\r
-    {\r
-      selectSeqs(lastid + 1, seq);\r
-    }\r
-\r
-    lastid = seq;\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void mouseClicked(MouseEvent e)\r
-  {\r
-    if (e.getClickCount() < 2)\r
-        return;\r
-\r
-    int y = e.getY();\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      y -= (2 * av.charHeight);\r
-    }\r
-\r
-    //DEFAULT LINK IS FIRST IN THE LINK LIST\r
-    int seq = av.getIndex(y);\r
-    String id = av.getAlignment().getSequenceAt(seq).getName();\r
-    if (id.indexOf("|") > -1)\r
-        id = id.substring(id.lastIndexOf("|") + 1);\r
-\r
-    String target = links.elementAt(0).toString();\r
-    target = target.substring(0, target.indexOf("|"));\r
-    String url = links.elementAt(0).toString();\r
-    url = url.substring(url.indexOf("|")+1);\r
-\r
-    int index = url.indexOf("$SEQUENCE_ID$");\r
-    url = url.substring(0, index)+ id + url.substring(index+13);\r
-\r
-    try\r
-    {\r
-\r
-      alignPanel.alignFrame.showURL(url, target);\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-  }\r
-\r
-  public void mouseEntered(MouseEvent e)\r
-  {\r
-    if (scrollThread != null)\r
-    {\r
-      scrollThread.running = false;\r
-    }\r
-  }\r
-\r
-  public void mouseExited(MouseEvent e)\r
-  {\r
-    if (av.getWrapAlignment())\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (mouseDragging && e.getY() < 0 && av.getStartSeq() > 0)\r
-    {\r
-      scrollThread = new ScrollThread(true);\r
-    }\r
-\r
-    if (mouseDragging && e.getY() >= getSize().height &&\r
-        av.alignment.getHeight() > av.getEndSeq())\r
-    {\r
-      scrollThread = new ScrollThread(false);\r
-    }\r
-  }\r
-\r
-  public void mousePressed(MouseEvent e)\r
-  {\r
-    if (e.getClickCount() >1 )\r
-    {\r
-      return;\r
-    }\r
-\r
-    int y = e.getY();\r
-    if (av.getWrapAlignment())\r
-    {\r
-      y -= 2 * av.charHeight;\r
-    }\r
-\r
-    int seq = av.getIndex(y);\r
-    if (seq == -1)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if ( (e.getModifiers() & InputEvent.BUTTON3_MASK) ==\r
-        InputEvent.BUTTON3_MASK)\r
-    {\r
-      APopupMenu popup = new APopupMenu(alignPanel, (Sequence) av.getAlignment().getSequenceAt(seq), links);\r
-      this.add(popup);\r
-      popup.show(this, e.getX(), e.getY());\r
-      return;\r
-    }\r
-\r
-    if (!e.isControlDown() && !e.isShiftDown() &&\r
-        av.alignment.findGroup(av.alignment.getSequenceAt(seq)) != null)\r
-    {\r
-\r
-      SequenceGroup selection = new SequenceGroup();\r
-      SequenceGroup sg = av.alignment.findGroup(av.alignment.getSequenceAt(seq));\r
-      selection.setStartRes(0);\r
-      selection.setEndRes(av.alignment.getWidth() - 1);\r
-      for (int i = 0; i < sg.getSize(); i++)\r
-      {\r
-        selection.addSequence(sg.getSequenceAt(i), true);\r
-      }\r
-\r
-      av.setSelectionGroup(selection);\r
-      return;\r
-    }\r
-\r
-    if (av.getSelectionGroup() == null ||\r
-        (!e.isControlDown() && av.getSelectionGroup() != null))\r
-    {\r
-      av.setSelectionGroup(new SequenceGroup());\r
-    }\r
-\r
-    av.getSelectionGroup().setStartRes(0);\r
-    av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);\r
-\r
-    if (e.isShiftDown() && lastid != -1)\r
-    {\r
-      selectSeqs(lastid, seq);\r
-    }\r
-    else\r
-    {\r
-      selectSeq(seq);\r
-    }\r
-\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  void selectSeq(int seq)\r
-  {\r
-    lastid = seq;\r
-    SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);\r
-    av.getSelectionGroup().addOrRemove(pickedSeq, false);\r
-  }\r
-\r
-  void selectSeqs(int start, int end)\r
-  {\r
-\r
-    lastid = start;\r
-    if (end < start)\r
-    {\r
-      int tmp = start;\r
-      start = end;\r
-      end = tmp;\r
-      lastid = end;\r
-    }\r
-\r
-    for (int i = start; i <= end; i++)\r
-    {\r
-      av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i), false);\r
-    }\r
-\r
-  }\r
-\r
-  public void mouseReleased(MouseEvent e)\r
-  {\r
-    if (scrollThread != null)\r
-    {\r
-      scrollThread.running = false;\r
-    }\r
-\r
-    if(av.getSelectionGroup()!=null)\r
-      av.getSelectionGroup().recalcConservation();\r
-\r
-    mouseDragging = false;\r
-    PaintRefresher.Refresh(this, av.alignment);\r
-  }\r
-\r
-  public void highlightSearchResults(java.util.Vector found)\r
-  {\r
-    idCanvas.setHighlighted(found);\r
-\r
-    if (found == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    int index = av.alignment.findIndex( (SequenceI) found.elementAt(0));\r
-\r
-    // do we need to scroll the panel?\r
-    if (av.getStartSeq() > index || av.getEndSeq() < index)\r
-    {\r
-      alignPanel.setScrollValues(av.getStartRes(), index);\r
-    }\r
-  }\r
-\r
-  // this class allows scrolling off the bottom of the visible alignment\r
-  class ScrollThread\r
-      extends Thread\r
-  {\r
-    boolean running = false;\r
-    boolean up = true;\r
-    public ScrollThread(boolean up)\r
-    {\r
-      this.up = up;\r
-      start();\r
-    }\r
-\r
-    public void stopScrolling()\r
-    {\r
-      running = false;\r
-    }\r
-\r
-    public void run()\r
-    {\r
-      running = true;\r
-      while (running)\r
-      {\r
-        if (alignPanel.scrollUp(up))\r
-        {\r
-          // scroll was ok, so add new sequence to selection\r
-          int seq = av.getStartSeq();\r
-          if (!up)\r
-          {\r
-            seq = av.getEndSeq();\r
-          }\r
-\r
-          if (seq < lastid)\r
-          {\r
-            selectSeqs(lastid - 1, seq);\r
-          }\r
-          else if (seq > lastid)\r
-          {\r
-            selectSeqs(lastid + 1, seq);\r
-          }\r
-\r
-          lastid = seq;\r
-        }\r
-        else\r
-        {\r
-          running = false;\r
-        }\r
-\r
-        alignPanel.repaint();\r
-        try\r
-        {\r
-          Thread.sleep(100);\r
-        }\r
-        catch (Exception ex)\r
-        {}\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+
+public class IdPanel
+    extends Panel implements MouseListener, MouseMotionListener
+{
+
+  protected IdCanvas idCanvas;
+  protected AlignViewport av;
+  protected AlignmentPanel alignPanel;
+  ScrollThread scrollThread = null;
+
+  int offy;
+  int width;
+  int lastid = -1;
+  boolean mouseDragging = false;
+  java.util.Vector links = new java.util.Vector();
+
+  public IdPanel(AlignViewport av, AlignmentPanel parent)
+  {
+    this.av = av;
+    alignPanel = parent;
+    idCanvas = new IdCanvas(av);
+    setLayout(new BorderLayout());
+    add(idCanvas, BorderLayout.CENTER);
+    idCanvas.addMouseListener(this);
+    idCanvas.addMouseMotionListener(this);
+
+    String label, url;
+    if(av.applet!=null)
+    {
+      for (int i = 1; i < 10; i++)
+      {
+        label = av.applet.getParameter("linkLabel_" + i);
+        url = av.applet.getParameter("linkURL_" + i);
+
+        if (label != null && url != null)
+          links.addElement(label + "|" + url);
+
+      }
+    }
+    if (links.size() < 1)
+    {
+      links = new java.util.Vector();
+      links.addElement("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+    }
+  }
+
+  Tooltip tooltip;
+  public void mouseMoved(MouseEvent e)
+  {
+    int seq = alignPanel.seqPanel.findSeq(e);
+
+    SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+
+    if(sequence.getDescription()==null)
+    {
+      if(tooltip!=null)
+        tooltip.setVisible(false);
+      tooltip = null;
+      return;
+    }
+
+    if (tooltip == null)
+      tooltip = new Tooltip(
+          sequence.getDisplayId(true)
+          + "\n" + sequence.getDescription(), idCanvas);
+    else
+      tooltip.setTip(sequence.getDisplayId(true)
+                     + "\n" + sequence.getDescription());
+
+    tooltip.repaint();
+
+  }
+
+  public void mouseDragged(MouseEvent e)
+  {
+    mouseDragging = true;
+
+    int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));
+
+    if (seq < lastid)
+    {
+      selectSeqs(lastid - 1, seq);
+    }
+    else if (seq > lastid)
+    {
+      selectSeqs(lastid + 1, seq);
+    }
+
+    lastid = seq;
+    alignPanel.repaint();
+  }
+
+  public void mouseClicked(MouseEvent e)
+  {
+    if (e.getClickCount() < 2)
+        return;
+
+
+    //DEFAULT LINK IS FIRST IN THE LINK LIST
+    int seq = alignPanel.seqPanel.findSeq(e);
+    String id = av.getAlignment().getSequenceAt(seq).getName();
+    if (id.indexOf("|") > -1)
+        id = id.substring(id.lastIndexOf("|") + 1);
+
+    String target = links.elementAt(0).toString();
+    target = target.substring(0, target.indexOf("|"));
+    String url = links.elementAt(0).toString();
+    url = url.substring(url.indexOf("|")+1);
+
+    int index = url.indexOf("$SEQUENCE_ID$");
+    url = url.substring(0, index)+ id + url.substring(index+13);
+
+    try
+    {
+
+      alignPanel.alignFrame.showURL(url, target);
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+
+  public void mouseEntered(MouseEvent e)
+  {
+    if (scrollThread != null)
+    {
+      scrollThread.running = false;
+    }
+  }
+
+  public void mouseExited(MouseEvent e)
+  {
+    if (av.getWrapAlignment())
+    {
+      return;
+    }
+
+    if (mouseDragging && e.getY() < 0 && av.getStartSeq() > 0)
+    {
+      scrollThread = new ScrollThread(true);
+    }
+
+    if (mouseDragging && e.getY() >= getSize().height &&
+        av.alignment.getHeight() > av.getEndSeq())
+    {
+      scrollThread = new ScrollThread(false);
+    }
+  }
+
+  public void mousePressed(MouseEvent e)
+  {
+    if (e.getClickCount() >1 )
+    {
+      return;
+    }
+
+    int y = e.getY();
+    if (av.getWrapAlignment())
+    {
+      y -= 2 * av.charHeight;
+    }
+
+    int seq = alignPanel.seqPanel.findSeq(e);
+
+    if ( (e.getModifiers() & InputEvent.BUTTON3_MASK) ==
+        InputEvent.BUTTON3_MASK)
+    {
+      APopupMenu popup = new APopupMenu(alignPanel, (Sequence) av.getAlignment().getSequenceAt(seq), links);
+      this.add(popup);
+      popup.show(this, e.getX(), e.getY());
+      return;
+    }
+
+
+    if ((av.getSelectionGroup() == null) ||
+            ((!e.isControlDown() && !e.isShiftDown()) && av.getSelectionGroup() != null))
+    {
+      av.setSelectionGroup(new SequenceGroup());
+      av.getSelectionGroup().setStartRes(0);
+      av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);
+    }
+
+
+    if (e.isShiftDown() && lastid != -1)
+    {
+      selectSeqs(lastid, seq);
+    }
+    else
+    {
+      selectSeq(seq);
+    }
+
+    alignPanel.repaint();
+  }
+
+  void selectSeq(int seq)
+  {
+    lastid = seq;
+    SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);
+    av.getSelectionGroup().addOrRemove(pickedSeq, false);
+  }
+
+  void selectSeqs(int start, int end)
+  {
+
+    lastid = start;
+    if (end < start)
+    {
+      int tmp = start;
+      start = end;
+      end = tmp;
+      lastid = end;
+    }
+
+    for (int i = start; i <= end; i++)
+    {
+      av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i), false);
+    }
+
+  }
+
+  public void mouseReleased(MouseEvent e)
+  {
+    if (scrollThread != null)
+    {
+      scrollThread.running = false;
+    }
+
+    if(av.getSelectionGroup()!=null)
+      av.getSelectionGroup().recalcConservation();
+
+    mouseDragging = false;
+    PaintRefresher.Refresh(this, av.alignment);
+  }
+
+  public void highlightSearchResults(java.util.Vector found)
+  {
+    idCanvas.setHighlighted(found);
+
+    if (found == null)
+    {
+      return;
+    }
+
+    int index = av.alignment.findIndex( (SequenceI) found.elementAt(0));
+
+    // do we need to scroll the panel?
+    if (av.getStartSeq() > index || av.getEndSeq() < index)
+    {
+      alignPanel.setScrollValues(av.getStartRes(), index);
+    }
+  }
+
+  // this class allows scrolling off the bottom of the visible alignment
+  class ScrollThread
+      extends Thread
+  {
+    boolean running = false;
+    boolean up = true;
+    public ScrollThread(boolean up)
+    {
+      this.up = up;
+      start();
+    }
+
+    public void stopScrolling()
+    {
+      running = false;
+    }
+
+    public void run()
+    {
+      running = true;
+      while (running)
+      {
+        if (alignPanel.scrollUp(up))
+        {
+          // scroll was ok, so add new sequence to selection
+          int seq = av.getStartSeq();
+          if (!up)
+          {
+            seq = av.getEndSeq();
+          }
+
+          if (seq < lastid)
+          {
+            selectSeqs(lastid - 1, seq);
+          }
+          else if (seq > lastid && seq<av.alignment.getHeight())
+          {
+            selectSeqs(lastid + 1, seq);
+          }
+
+
+          lastid = seq;
+        }
+        else
+        {
+          running = false;
+        }
+
+        alignPanel.repaint();
+        try
+        {
+          Thread.sleep(100);
+        }
+        catch (Exception ex)
+        {}
+      }
+    }
+  }
+
+}
index 5b4de85..78943b8 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-public class IdwidthAdjuster\r
-    extends Panel implements MouseListener, MouseMotionListener\r
-{\r
-  boolean active = false;\r
-  int oldX = 0;\r
-  Image image;\r
-  AlignmentPanel ap;\r
-\r
-  public IdwidthAdjuster(AlignmentPanel ap)\r
-  {\r
-    setLayout(null);\r
-    this.ap = ap;\r
-    java.net.URL url = getClass().getResource("/images/idwidth.gif");\r
-    if (url != null)\r
-    {\r
-      image = java.awt.Toolkit.getDefaultToolkit().getImage(url);\r
-    }\r
-\r
-    addMouseListener(this);\r
-    addMouseMotionListener(this);\r
-  }\r
-\r
-  public void mousePressed(MouseEvent evt)\r
-  {\r
-    oldX = evt.getX();\r
-  }\r
-\r
-  public void mouseReleased(MouseEvent evt)\r
-  {\r
-    active = false;\r
-    repaint();\r
-  }\r
-\r
-  public void mouseEntered(MouseEvent evt)\r
-  {\r
-    active = true;\r
-    repaint();\r
-  }\r
-\r
-  public void mouseExited(MouseEvent evt)\r
-  {\r
-    active = false;\r
-    repaint();\r
-  }\r
-\r
-  public void mouseDragged(MouseEvent evt)\r
-  {\r
-    active = true;\r
-    Dimension d = ap.idPanel.idCanvas.getSize();\r
-    int dif = evt.getX() - oldX;\r
-\r
-    if (d.width + dif > 20 || dif > 0)\r
-    {\r
-      ap.setIdWidth(d.width + dif, d.height);\r
-      this.setSize(d.width + dif, getSize().height);\r
-    }\r
-\r
-    oldX = evt.getX();\r
-  }\r
-\r
-  public void mouseMoved(MouseEvent evt)\r
-  {}\r
-\r
-  public void mouseClicked(MouseEvent evt)\r
-  {}\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    g.setColor(Color.white);\r
-    g.fillRect(0, 0, getSize().width, getSize().height);\r
-    if (active)\r
-    {\r
-      if (image != null)\r
-      {\r
-        g.drawImage(image, getSize().width - 20, 2, this);\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class IdwidthAdjuster
+    extends Panel implements MouseListener, MouseMotionListener
+{
+  boolean active = false;
+  int oldX = 0;
+  Image image;
+  AlignmentPanel ap;
+
+  public IdwidthAdjuster(AlignmentPanel ap)
+  {
+    setLayout(null);
+    this.ap = ap;
+    java.net.URL url = getClass().getResource("/images/idwidth.gif");
+    if (url != null)
+    {
+      image = java.awt.Toolkit.getDefaultToolkit().getImage(url);
+    }
+
+    addMouseListener(this);
+    addMouseMotionListener(this);
+  }
+
+  public void mousePressed(MouseEvent evt)
+  {
+    oldX = evt.getX();
+  }
+
+  public void mouseReleased(MouseEvent evt)
+  {
+    active = false;
+    repaint();
+  }
+
+  public void mouseEntered(MouseEvent evt)
+  {
+    active = true;
+    repaint();
+  }
+
+  public void mouseExited(MouseEvent evt)
+  {
+    active = false;
+    repaint();
+  }
+
+  public void mouseDragged(MouseEvent evt)
+  {
+    active = true;
+    Dimension d = ap.idPanel.idCanvas.getSize();
+    int dif = evt.getX() - oldX;
+
+    if (d.width + dif > 20 || dif > 0)
+    {
+      ap.setIdWidth(d.width + dif, d.height);
+      this.setSize(d.width + dif, getSize().height);
+    }
+
+    oldX = evt.getX();
+  }
+
+  public void mouseMoved(MouseEvent evt)
+  {}
+
+  public void mouseClicked(MouseEvent evt)
+  {}
+
+  public void paint(Graphics g)
+  {
+    g.setColor(Color.white);
+    g.fillRect(0, 0, getSize().width, getSize().height);
+    if (active)
+    {
+      if (image != null)
+      {
+        g.drawImage(image, getSize().width - 20, 2, this);
+      }
+    }
+  }
+
+}
index a4b7f06..2c7a2f2 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-public class OverviewPanel\r
-    extends Panel implements Runnable, MouseMotionListener, MouseListener\r
-{\r
-  Image miniMe;\r
-  AlignViewport av;\r
-  AlignmentPanel ap;\r
-  float scalew = 1f;\r
-  float scaleh = 1f;\r
-\r
-  public int width, sequencesHeight;\r
-  int graphHeight = 20;\r
-  int boxX = -1, boxY = -1, boxWidth = -1, boxHeight = -1;\r
-\r
-  boolean resizing = false;\r
-\r
-  // Can set different properties in this seqCanvas than\r
-  // main visible SeqCanvas\r
-  SequenceRenderer sr;\r
-  FeatureRenderer fr;\r
-\r
-\r
-  Frame nullFrame;\r
-\r
-  public OverviewPanel(AlignmentPanel ap)\r
-  {\r
-    this.av = ap.av;\r
-    this.ap = ap;\r
-    setLayout(null);\r
-    nullFrame = new Frame();\r
-    nullFrame.addNotify();\r
-\r
-\r
-    sr = new SequenceRenderer(av);\r
-    sr.graphics = nullFrame.getGraphics();\r
-    sr.renderGaps( false );\r
-    sr.forOverview = true;\r
-    fr = new FeatureRenderer(av);\r
-    fr.overview = true;\r
-\r
-\r
-\r
-    // scale the initial size of overviewpanel to shape of alignment\r
-    float initialScale = (float) av.alignment.getWidth() /\r
-        (float) av.alignment.getHeight();\r
-\r
-    if(av.vconsensus==null)\r
-          graphHeight = 0;\r
-\r
-    if (av.alignment.getWidth() > av.alignment.getHeight())\r
-    {\r
-      // wider\r
-      width = 400;\r
-      sequencesHeight = (int) (400f / initialScale);\r
-      if(sequencesHeight<40)\r
-              sequencesHeight = 40;\r
-    }\r
-    else\r
-    {\r
-      // taller\r
-      width = (int) (400f * initialScale);\r
-      sequencesHeight = 300;\r
-      if (width < 120)\r
-      {\r
-        width = 120;\r
-      }\r
-    }\r
-\r
-    setSize(new Dimension(width, sequencesHeight + graphHeight));\r
-    addComponentListener(new ComponentAdapter()\r
-    {\r
-\r
-      public void componentResized(ComponentEvent evt)\r
-      {\r
-        if (getSize().width != width ||\r
-            getSize().height != sequencesHeight + graphHeight)\r
-        {\r
-          updateOverviewImage();\r
-        }\r
-      }\r
-    });\r
-\r
-    addMouseMotionListener(this);\r
-\r
-    addMouseListener(this);\r
-\r
-    updateOverviewImage();\r
-\r
-  }\r
-\r
-\r
-  public void mouseEntered(MouseEvent evt)\r
-  {}\r
-  public void mouseExited(MouseEvent evt)\r
-  {}\r
-  public void mouseClicked(MouseEvent evt)\r
-  {}\r
-  public void mouseMoved(MouseEvent evt)\r
-  {}\r
-  public void mousePressed(MouseEvent evt)\r
-  {\r
-    boxX = evt.getX();\r
-    boxY = evt.getY();\r
-\r
-    checkValid();\r
-    repaint();\r
-  }\r
-\r
-  public void mouseReleased(MouseEvent evt)\r
-  {\r
-    boxX = evt.getX();\r
-    boxY = evt.getY();\r
-    checkValid();\r
-    ap.setScrollValues( (int) (boxX / scalew / av.getCharWidth()),\r
-                         (int) (boxY / scaleh / av.getCharHeight()));\r
-  }\r
-\r
-  public void mouseDragged(MouseEvent evt)\r
-  {\r
-    boxX = evt.getX();\r
-    boxY = evt.getY();\r
-    checkValid();\r
-    ap.setScrollValues( (int) (boxX / scalew / av.getCharWidth()),\r
-                         (int) (boxY / scaleh / av.getCharHeight()));\r
-\r
-    repaint();\r
-    ap.repaint();\r
-  }\r
-\r
-  void checkValid()\r
-  {\r
-    if (boxY < 0)\r
-    {\r
-      boxY = 0;\r
-    }\r
-\r
-    if (boxY > sequencesHeight - boxHeight)\r
-    {\r
-      boxY = sequencesHeight - boxHeight + 1;\r
-    }\r
-\r
-    if (boxX < 0)\r
-    {\r
-      boxX = 0;\r
-    }\r
-\r
-    if (boxX > width - boxWidth)\r
-    {\r
-      boxX = width - boxWidth;\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void updateOverviewImage()\r
-  {\r
-    if (resizing)\r
-    {\r
-        resizeAgain = true;\r
-        return;\r
-    }\r
-\r
-    if (av.showSequenceFeatures)\r
-   {\r
-     fr.featureGroups = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups;\r
-     fr.featureColours = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours;\r
-   }\r
-\r
-    resizing = true;\r
-\r
-    if ( (getSize().width > 0) && (getSize().height > 0))\r
-    {\r
-      width = getSize().width;\r
-      sequencesHeight = getSize().height - graphHeight;\r
-    }\r
-    setSize(new Dimension(width, sequencesHeight + graphHeight));\r
-    setBoxPosition();\r
-\r
-    Thread thread = new Thread(this);\r
-    thread.start();\r
-        repaint();\r
-  }\r
-\r
-  // This is set true if the user resizes whilst\r
-  // the overview is being calculated\r
-    boolean resizeAgain = false;\r
-\r
-  public void run()\r
-  {\r
-    miniMe = null;\r
-    int alwidth = av.alignment.getWidth();\r
-    int alheight = av.alignment.getHeight();\r
-\r
-    if (av.showSequenceFeatures)\r
-    {\r
-      fr.renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;\r
-      fr.featureGroups = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups;\r
-      fr.featureColours = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours;\r
-      fr.sequenceFeatures = ap.seqPanel.seqCanvas.getFeatureRenderer().sequenceFeatures;\r
-    }\r
-\r
-    if (getSize().width > 0 && getSize().height > 0)\r
-    {\r
-      width = getSize().width;\r
-      sequencesHeight = getSize().height - graphHeight;\r
-    }\r
-\r
-    setSize(new Dimension(width, sequencesHeight + graphHeight));\r
-\r
-    int fullsizeWidth = alwidth * av.getCharWidth();\r
-    int fullsizeHeight = alheight * av.getCharHeight();\r
-\r
-    scalew = (float) width / (float) fullsizeWidth;\r
-    scaleh = (float) sequencesHeight / (float) fullsizeHeight;\r
-\r
-    miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);\r
-\r
-    Graphics mg = miniMe.getGraphics();\r
-    float sampleCol = (float) alwidth / (float) width;\r
-    float sampleRow = (float) alheight / (float) sequencesHeight;\r
-\r
-    int lastcol=0, lastseq=0;\r
-    int xstart=0, ystart=0;\r
-    Color color = Color.yellow;\r
-    int col, sameRow = 0, sameCol = 0;\r
-    jalview.datamodel.SequenceI sequence;\r
-\r
-    for (int row = 0; row <= sequencesHeight; row++)\r
-    {\r
-      if((int)(row*sampleRow)==lastseq)\r
-      {\r
-        sameRow ++;\r
-        continue;\r
-      }\r
-\r
-      sequence = av.getAlignment().getSequenceAt(lastseq);\r
-\r
-      for (col = 0; col < width; col++)\r
-      {\r
-        if((int)(col*sampleCol) == lastcol)\r
-        {\r
-          sameCol ++;\r
-          continue;\r
-        }\r
-\r
-        lastcol = (int)(col*sampleCol);\r
-\r
-        if(sequence.getLength()>lastcol)\r
-        {\r
-          color = sr.findSequenceColour(sequence, lastcol);\r
-\r
-          if (av.showSequenceFeatures)\r
-            color = fr.findFeatureColour(color,\r
-                                        sequence,\r
-                                        lastcol);\r
-        }\r
-        else\r
-          color = color.white;\r
-\r
-        mg.setColor(color);\r
-        if (sameCol == 1 && sameRow == 1)\r
-          mg.drawLine(xstart, ystart, xstart, ystart);\r
-        else\r
-          mg.fillRect(xstart, ystart, sameCol, sameRow);\r
-\r
-        xstart = col;\r
-        sameCol = 1;\r
-      }\r
-\r
-\r
-      lastseq = (int)(row*sampleRow);\r
-      ystart = row;\r
-      sameRow = 1;\r
-    }\r
-\r
-    if (av.conservation != null)\r
-    {\r
-      for (col = 0; col < width; col++)\r
-      {\r
-        lastcol = (int) (col * sampleCol);\r
-        {\r
-          mg.translate(col, sequencesHeight);\r
-          ap.annotationPanel.drawGraph(mg, av.conservation,\r
-                                       (int) (sampleCol) + 1,\r
-                                       graphHeight,\r
-                                       (int) (col * sampleCol),\r
-                                       (int) (col * sampleCol) + 1);\r
-          mg.translate( -col, -sequencesHeight);\r
-        }\r
-      }\r
-    }\r
-\r
-\r
-\r
-    System.gc();\r
-\r
-    resizing = false;\r
-\r
-    setBoxPosition();\r
-\r
-    if(resizeAgain)\r
-    {\r
-      resizeAgain = false;\r
-      updateOverviewImage();\r
-    }\r
-  }\r
-\r
-  public void setBoxPosition()\r
-  {\r
-    int fullsizeWidth = av.alignment.getWidth() * av.getCharWidth();\r
-    int fullsizeHeight = av.alignment.getHeight() * av.getCharHeight();\r
-\r
-    scalew = (float) width / (float) fullsizeWidth;\r
-    scaleh = (float) sequencesHeight / (float) fullsizeHeight;\r
-\r
-    boxX = (int) (av.getStartRes() * av.getCharWidth() * scalew);\r
-    boxY = (int) (av.getStartSeq() * av.getCharHeight() * scaleh);\r
-    boxWidth = (int) ( (av.getEndRes() - av.getStartRes() + 1) *\r
-                      av.getCharWidth() * scalew);\r
-    boxHeight = (int) (av.getEndSeq() * av.getCharHeight() * scaleh) - boxY;\r
-    repaint();\r
-  }\r
-\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    if (miniMe != null)\r
-    {\r
-      g.drawImage(miniMe, 0, 0, this);\r
-    }\r
-    else\r
-    {\r
-      g.setColor(Color.white);\r
-      g.fillRect(0, 0, getSize().width, getSize().height);\r
-      g.setColor(Color.black);\r
-      g.setFont(new Font("Verdana", Font.BOLD, 15));\r
-      g.drawString("Recalculating", 5, sequencesHeight / 2);\r
-      g.drawString("Overview.....", 5, (sequencesHeight / 2) + 20);\r
-    }\r
-\r
-    g.setColor(Color.red);\r
-    g.drawRect(boxX, boxY, boxWidth, boxHeight);\r
-    g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class OverviewPanel
+    extends Panel implements Runnable, MouseMotionListener, MouseListener
+{
+  Image miniMe;
+  Image offscreen;
+  AlignViewport av;
+  AlignmentPanel ap;
+  float scalew = 1f;
+  float scaleh = 1f;
+
+  public int width, sequencesHeight;
+  int graphHeight = 20;
+  int boxX = -1, boxY = -1, boxWidth = -1, boxHeight = -1;
+
+  boolean resizing = false;
+
+  // Can set different properties in this seqCanvas than
+  // main visible SeqCanvas
+  SequenceRenderer sr;
+  FeatureRenderer fr;
+
+
+  Frame nullFrame;
+
+  public OverviewPanel(AlignmentPanel ap)
+  {
+    this.av = ap.av;
+    this.ap = ap;
+    setLayout(null);
+    nullFrame = new Frame();
+    nullFrame.addNotify();
+
+
+    sr = new SequenceRenderer(av);
+    sr.graphics = nullFrame.getGraphics();
+    sr.renderGaps = false;
+    sr.forOverview = true;
+    fr = new FeatureRenderer(av);
+    fr.overview = true;
+
+
+
+    // scale the initial size of overviewpanel to shape of alignment
+    float initialScale = (float) av.alignment.getWidth() /
+        (float) av.alignment.getHeight();
+
+    if(av.vconsensus==null)
+          graphHeight = 0;
+
+    if (av.alignment.getWidth() > av.alignment.getHeight())
+    {
+      // wider
+      width = 400;
+      sequencesHeight = (int) (400f / initialScale);
+      if(sequencesHeight<40)
+              sequencesHeight = 40;
+    }
+    else
+    {
+      // taller
+      width = (int) (400f * initialScale);
+      sequencesHeight = 300;
+      if (width < 120)
+      {
+        width = 120;
+      }
+    }
+
+    setSize(new Dimension(width, sequencesHeight + graphHeight));
+    addComponentListener(new ComponentAdapter()
+    {
+
+      public void componentResized(ComponentEvent evt)
+      {
+        if (getSize().width != width ||
+            getSize().height != sequencesHeight + graphHeight)
+        {
+          updateOverviewImage();
+        }
+      }
+    });
+
+    addMouseMotionListener(this);
+
+    addMouseListener(this);
+
+    updateOverviewImage();
+
+  }
+
+
+  public void mouseEntered(MouseEvent evt)
+  {}
+  public void mouseExited(MouseEvent evt)
+  {}
+  public void mouseClicked(MouseEvent evt)
+  {}
+  public void mouseMoved(MouseEvent evt)
+  {}
+  public void mousePressed(MouseEvent evt)
+  {
+    boxX = evt.getX();
+    boxY = evt.getY();
+    checkValid();
+  }
+
+  public void mouseReleased(MouseEvent evt)
+  {
+    boxX = evt.getX();
+    boxY = evt.getY();
+    checkValid();
+  }
+
+  public void mouseDragged(MouseEvent evt)
+  {
+    boxX = evt.getX();
+    boxY = evt.getY();
+    checkValid();
+  }
+
+  void checkValid()
+  {
+    if (boxY < 0)
+    {
+        boxY = 0;
+    }
+
+    if (boxY > (sequencesHeight - boxHeight))
+    {
+        boxY = sequencesHeight - boxHeight + 1;
+    }
+
+    if (boxX < 0)
+    {
+        boxX = 0;
+    }
+
+    if (boxX > (width - boxWidth))
+    {
+      if(av.hasHiddenColumns)
+      {
+        //Try smallest possible box
+        boxWidth = (int) ( (av.endRes - av.startRes + 1) *
+                               av.getCharWidth() * scalew);
+      }
+      boxX = width - boxWidth;
+    }
+
+    int col = (int) (boxX / scalew / av.getCharWidth());
+    int row = (int) (boxY / scaleh / av.getCharHeight());
+
+    if (av.hasHiddenColumns)
+    {
+      if (!av.getColumnSelection().isVisible(col))
+      {
+        return;
+      }
+
+      col = av.getColumnSelection().findColumnPosition(col);
+    }
+
+    if( av.hasHiddenRows )
+    {
+      row = av.alignment.getHiddenSequences().findIndexWithoutHiddenSeqs(row);
+    }
+
+    ap.setScrollValues( col, row );
+    ap.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void updateOverviewImage()
+  {
+    if (resizing)
+    {
+        resizeAgain = true;
+        return;
+    }
+
+    if (av.showSequenceFeatures)
+   {
+     fr.featureGroups = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups;
+     fr.featureColours = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours;
+   }
+
+    resizing = true;
+
+    if ( (getSize().width > 0) && (getSize().height > 0))
+    {
+      width = getSize().width;
+      sequencesHeight = getSize().height - graphHeight;
+    }
+    setSize(new Dimension(width, sequencesHeight + graphHeight));
+
+    Thread thread = new Thread(this);
+    thread.start();
+    repaint();
+  }
+
+  // This is set true if the user resizes whilst
+  // the overview is being calculated
+    boolean resizeAgain = false;
+
+  public void run()
+  {
+    miniMe = null;
+    int alwidth = av.alignment.getWidth();
+    int alheight = av.alignment.getHeight();
+
+    if (av.showSequenceFeatures)
+    {
+      fr.transferSettings( ap.seqPanel.seqCanvas.getFeatureRenderer() );
+    }
+
+    if (getSize().width > 0 && getSize().height > 0)
+    {
+      width = getSize().width;
+      sequencesHeight = getSize().height - graphHeight;
+    }
+
+    setSize(new Dimension(width, sequencesHeight + graphHeight));
+
+    int fullsizeWidth = alwidth * av.getCharWidth();
+    int fullsizeHeight = alheight * av.getCharHeight();
+
+    scalew = (float) width / (float) fullsizeWidth;
+    scaleh = (float) sequencesHeight / (float) fullsizeHeight;
+
+    miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
+    offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
+
+    Graphics mg = miniMe.getGraphics();
+    float sampleCol = (float) alwidth / (float) width;
+    float sampleRow = (float) alheight / (float) sequencesHeight;
+
+    int lastcol=0, lastrow=0;
+    int xstart=0, ystart=0;
+    Color color = Color.yellow;
+    int row, col, sameRow = 0, sameCol = 0;
+    jalview.datamodel.SequenceI seq;
+    boolean hiddenRow = false;
+    for (row = 0; row <= sequencesHeight; row++)
+    {
+      if((int)(row*sampleRow)==lastrow)
+      {
+        sameRow ++;
+        continue;
+      }
+
+      hiddenRow = false;
+      if (av.hasHiddenRows)
+      {
+        seq = av.alignment.getHiddenSequences().getHiddenSequence(lastrow);
+        if (seq == null)
+        {
+          int index =
+             av.alignment.getHiddenSequences().findIndexWithoutHiddenSeqs(lastrow);
+
+         seq = av.alignment.getSequenceAt(index);
+        }
+        else
+        {
+          hiddenRow = true;
+        }
+      }
+      else
+        seq = av.alignment.getSequenceAt(lastrow);
+
+        for (col = 0; col < width; col++)
+        {
+          if ( (int) (col * sampleCol) == lastcol && (int) (row * sampleRow) == lastrow)
+          {
+            sameCol ++;
+            continue;
+          }
+
+          lastcol = (int) (col * sampleCol);
+
+          if (seq.getLength() > lastcol)
+          {
+            color = sr.getResidueBoxColour(
+                seq, lastcol);
+
+            if (av.showSequenceFeatures)
+              color = fr.findFeatureColour(color, seq, lastcol);
+          }
+          else
+          {
+            color = Color.white; //White
+          }
+
+          if (hiddenRow ||
+              (av.hasHiddenColumns && !av.getColumnSelection().isVisible(lastcol)))
+          {
+            color = color.darker().darker();
+          }
+
+          mg.setColor(color);
+          if (sameCol == 1 && sameRow == 1)
+            mg.drawLine(xstart, ystart, xstart, ystart);
+          else
+            mg.fillRect(xstart, ystart, sameCol, sameRow);
+
+          xstart = col;
+          sameCol = 1;
+      }
+      lastrow = (int)(row*sampleRow);
+      ystart = row;
+      sameRow = 1;
+    }
+
+    if (av.conservation != null)
+    {
+      for (col = 0; col < width; col++)
+      {
+        lastcol = (int) (col * sampleCol);
+        {
+          mg.translate(col, sequencesHeight);
+          ap.annotationPanel.drawGraph(mg, av.conservation,
+                                       (int) (sampleCol) + 1,
+                                       graphHeight,
+                                       (int) (col * sampleCol),
+                                       (int) (col * sampleCol) + 1);
+          mg.translate( -col, -sequencesHeight);
+        }
+      }
+    }
+    System.gc();
+
+    resizing = false;
+
+    setBoxPosition();
+
+    if(resizeAgain)
+    {
+      resizeAgain = false;
+      updateOverviewImage();
+    }
+}
+
+  public void setBoxPosition()
+  {
+    int fullsizeWidth = av.alignment.getWidth() * av.getCharWidth();
+    int fullsizeHeight = (av.alignment.getHeight()
+                          + av.alignment.getHiddenSequences().getSize()) *
+        av.getCharHeight();
+
+    int startRes = av.getStartRes();
+    int endRes = av.getEndRes();
+
+    if (av.hasHiddenColumns)
+    {
+      startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
+      endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
+    }
+
+    int startSeq = av.startSeq;
+    int endSeq = av.endSeq;
+
+    if (av.hasHiddenRows)
+    {
+      startSeq =
+          av.alignment.getHiddenSequences().adjustForHiddenSeqs(startSeq);
+
+      endSeq =
+          av.alignment.getHiddenSequences().adjustForHiddenSeqs(endSeq);
+
+    }
+
+    scalew = (float) width / (float) fullsizeWidth;
+    scaleh = (float) sequencesHeight / (float) fullsizeHeight;
+
+    boxX = (int) (startRes * av.getCharWidth() * scalew);
+    boxY = (int) (startSeq * av.getCharHeight() * scaleh);
+
+    if (av.hasHiddenColumns)
+      boxWidth = (int) ( (endRes - startRes + 1) * av.getCharWidth() * scalew);
+    else
+      boxWidth = (int) ( (endRes - startRes + 1) * av.getCharWidth() * scalew);
+
+    boxHeight = (int) ( (endSeq - startSeq) * av.getCharHeight() * scaleh);
+
+    repaint();
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  public void paint(Graphics g)
+  {
+    Graphics og = offscreen.getGraphics();
+    if (miniMe != null)
+    {
+      og.drawImage(miniMe, 0, 0, this);
+      og.setColor(Color.red);
+      og.drawRect(boxX, boxY, boxWidth, boxHeight);
+      og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
+      g.drawImage(offscreen, 0,0, this);
+    }
+    else
+    {
+      g.setColor(Color.white);
+      g.fillRect(0, 0, getSize().width, getSize().height);
+      g.setColor(Color.black);
+      g.setFont(new Font("Verdana", Font.BOLD, 15));
+      g.drawString("Recalculating", 5, sequencesHeight / 2);
+      g.drawString("Overview.....", 5, (sequencesHeight / 2) + 20);
+    }
+  }
+
+}
index a75de06..de3fd32 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-\r
-\r
-public class PCAPanel\r
-    extends Frame implements Runnable, ActionListener, ItemListener\r
-{\r
-  PCA pca;\r
-  int top;\r
-  RotatableCanvas rc;\r
-  AlignViewport av;\r
-  SequenceI [] seqs;\r
-\r
-\r
-  public PCAPanel(AlignViewport av)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    for (int i = 1; i < 8; i++)\r
-    {\r
-      xCombobox.addItem("dim " + i);\r
-      yCombobox.addItem("dim " + i);\r
-      zCombobox.addItem("dim " + i);\r
-    }\r
-\r
-    this.av = av;\r
-    if (av.getSelectionGroup()!=null && av.getSelectionGroup().getSize() > 3)\r
-    {\r
-      seqs = new Sequence[av.getSelectionGroup().getSize()];\r
-      for (int i = 0; i < av.getSelectionGroup().getSize(); i++)\r
-      {\r
-        seqs[i] = av.getSelectionGroup().getSequenceAt(i);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      seqs = new Sequence[av.getAlignment().getHeight()];\r
-      for (int i = 0; i < av.getAlignment().getHeight(); i++)\r
-      {\r
-        seqs[i] = av.getAlignment().getSequenceAt(i);\r
-      }\r
-    }\r
-\r
-    rc = new RotatableCanvas(av);\r
-    add(rc, BorderLayout.CENTER);\r
-\r
-    jalview.bin.JalviewLite.addFrame(this, "Principal component analysis",\r
-                                       400, 400);\r
-\r
-\r
-    Thread worker = new Thread(this);\r
-    worker.start();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void run()\r
-  {\r
-              pca = new PCA(seqs);\r
-              pca.run();\r
-\r
-              // Now find the component coordinates\r
-              int ii = 0;\r
-\r
-              while ((ii < seqs.length) && (seqs[ii] != null))\r
-              {\r
-                  ii++;\r
-              }\r
-\r
-              double[][] comps = new double[ii][ii];\r
-\r
-              for (int i = 0; i < ii; i++)\r
-              {\r
-                  if (pca.getEigenvalue(i) > 1e-4)\r
-                  {\r
-                      comps[i] = pca.component(i);\r
-                  }\r
-              }\r
-\r
-              //////////////////\r
-              xCombobox.select(0);\r
-              yCombobox.select(1);\r
-              zCombobox.select(2);\r
-\r
-              top = pca.getM().rows - 1;\r
-\r
-              Vector points = new Vector();\r
-              float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);\r
-\r
-              for (int i = 0; i < pca.getM().rows; i++)\r
-              {\r
-                  SequencePoint sp = new SequencePoint(seqs[i], scores[i]);\r
-                  points.addElement(sp);\r
-              }\r
-\r
-              rc.setPoints(points, pca.getM().rows);\r
-              rc.repaint();\r
-              seqs = null;\r
-              this.repaint();\r
-  }\r
-\r
-  void doDimensionChange()\r
-  {\r
-    if (top == 0)\r
-    {\r
-      return;\r
-    }\r
-\r
-    int dim1 = top - xCombobox.getSelectedIndex();\r
-    int dim2 = top - yCombobox.getSelectedIndex();\r
-    int dim3 = top - zCombobox.getSelectedIndex();\r
-\r
-    float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);\r
-    for (int i = 0; i < pca.getM().rows; i++)\r
-    {\r
-      ( (SequencePoint) rc.points.elementAt(i)).coord = scores[i];\r
-    }\r
-\r
-    rc.img = null;\r
-    rc.rotmat.setIdentity();\r
-    rc.initAxes();\r
-    rc.paint(rc.getGraphics());\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    values_actionPerformed();\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if(evt.getSource()==xCombobox)\r
-      xCombobox_actionPerformed();\r
-    else if(evt.getSource()==yCombobox)\r
-      yCombobox_actionPerformed();\r
-    else if(evt.getSource()==zCombobox)\r
-      zCombobox_actionPerformed();\r
-  }\r
-\r
-\r
-  protected void xCombobox_actionPerformed()\r
-  {\r
-    doDimensionChange();\r
-  }\r
-\r
-  protected void yCombobox_actionPerformed()\r
-  {\r
-    doDimensionChange();\r
-  }\r
-\r
-  protected void zCombobox_actionPerformed()\r
-  {\r
-    doDimensionChange();\r
-  }\r
-\r
-  public void values_actionPerformed()\r
-  {\r
-\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);\r
-    Frame frame = new Frame();\r
-    frame.add(cap);\r
-    jalview.bin.JalviewLite.addFrame(frame, "PCA details", 500, 500);\r
-\r
-      cap.setText(pca.getDetails());\r
-  }\r
-\r
-  public void labels_itemStateChanged(ItemEvent itemEvent)\r
-  {\r
-    rc.showLabels( labels.getState() );\r
-  }\r
-  Panel jPanel2 = new Panel();\r
-  Label jLabel1 = new Label();\r
-  Label jLabel2 = new Label();\r
-  Label jLabel3 = new Label();\r
-  protected Choice xCombobox = new Choice();\r
-  protected Choice yCombobox = new Choice();\r
-  protected Choice zCombobox = new Choice();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  MenuBar menuBar1 = new MenuBar();\r
-  Menu menu1 = new Menu();\r
-  Menu menu2 = new Menu();\r
-  protected CheckboxMenuItem labels = new CheckboxMenuItem();\r
-  MenuItem values = new MenuItem();\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.setLayout(borderLayout1);\r
-    jPanel2.setLayout(flowLayout1);\r
-    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel1.setText("x=");\r
-    jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel2.setText("y=");\r
-    jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel3.setText("z=");\r
-    jPanel2.setBackground(Color.white);\r
-    zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    zCombobox.addItemListener(this);\r
-    yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    yCombobox.addItemListener(this);\r
-    xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    xCombobox.addItemListener(this);\r
-    this.setMenuBar(menuBar1);\r
-    menu1.setLabel("File");\r
-    menu2.setLabel("View");\r
-    labels.setLabel("Labels");\r
-    labels.addItemListener(this);\r
-    values.setLabel("Output Values...");\r
-    values.addActionListener(this);\r
-    this.add(jPanel2, BorderLayout.SOUTH);\r
-    jPanel2.add(jLabel1, null);\r
-    jPanel2.add(xCombobox, null);\r
-    jPanel2.add(jLabel2, null);\r
-    jPanel2.add(yCombobox, null);\r
-    jPanel2.add(jLabel3, null);\r
-    jPanel2.add(zCombobox, null);\r
-    menuBar1.add(menu1);\r
-    menuBar1.add(menu2);\r
-    menu2.add(labels);\r
-    menu1.add(values);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.analysis.*;
+import jalview.datamodel.*;
+
+
+public class PCAPanel
+    extends Frame implements Runnable, ActionListener, ItemListener
+{
+  PCA pca;
+  int top;
+  RotatableCanvas rc;
+  AlignViewport av;
+  SequenceI [] seqs;
+  AlignmentView seqstrings;
+
+
+  public PCAPanel(AlignViewport av)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    for (int i = 1; i < 8; i++)
+    {
+      xCombobox.addItem("dim " + i);
+      yCombobox.addItem("dim " + i);
+      zCombobox.addItem("dim " + i);
+    }
+
+    this.av = av;
+    seqstrings = av.getAlignmentView(av.getSelectionGroup()!=null);
+    if(av.getSelectionGroup()==null)
+    {
+      seqs = av.alignment.getSequencesArray();
+    }
+    else
+    {
+      seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+    }
+    SeqCigar sq[]=seqstrings.getSequences();
+    int length = sq[0].getWidth();
+
+    for (int i = 0; i < seqs.length; i++)
+    {
+      if (sq[i].getWidth() != length)
+      {
+        System.out.println("Sequences must be equal length for PCA analysis");
+        return;
+      }
+    }
+
+
+    rc = new RotatableCanvas(av);
+    add(rc, BorderLayout.CENTER);
+
+    jalview.bin.JalviewLite.addFrame(this, "Principal component analysis",
+                                       400, 400);
+
+
+    Thread worker = new Thread(this);
+    worker.start();
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void run()
+  {
+              pca = new PCA(seqstrings.getSequenceStrings(' '));
+              pca.run();
+
+              // Now find the component coordinates
+              int ii = 0;
+
+              while ((ii < seqs.length) && (seqs[ii] != null))
+              {
+                  ii++;
+              }
+
+              double[][] comps = new double[ii][ii];
+
+              for (int i = 0; i < ii; i++)
+              {
+                  if (pca.getEigenvalue(i) > 1e-4)
+                  {
+                      comps[i] = pca.component(i);
+                  }
+              }
+
+              //////////////////
+              xCombobox.select(0);
+              yCombobox.select(1);
+              zCombobox.select(2);
+
+              top = pca.getM().rows - 1;
+
+              Vector points = new Vector();
+              float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);
+
+              for (int i = 0; i < pca.getM().rows; i++)
+              {
+                  SequencePoint sp = new SequencePoint(seqs[i], scores[i]);
+                  points.addElement(sp);
+              }
+
+              rc.setPoints(points, pca.getM().rows);
+              rc.repaint();
+              seqs = null;
+              this.repaint();
+  }
+
+  void doDimensionChange()
+  {
+    if (top == 0)
+    {
+      return;
+    }
+
+    int dim1 = top - xCombobox.getSelectedIndex();
+    int dim2 = top - yCombobox.getSelectedIndex();
+    int dim3 = top - zCombobox.getSelectedIndex();
+
+    float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);
+    for (int i = 0; i < pca.getM().rows; i++)
+    {
+      ( (SequencePoint) rc.points.elementAt(i)).coord = scores[i];
+    }
+
+    rc.img = null;
+    rc.rotmat.setIdentity();
+    rc.initAxes();
+    rc.paint(rc.getGraphics());
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==inputData)
+      showOriginalData();
+    else
+      values_actionPerformed();
+  }
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if(evt.getSource()==xCombobox)
+      xCombobox_actionPerformed();
+    else if(evt.getSource()==yCombobox)
+      yCombobox_actionPerformed();
+    else if(evt.getSource()==zCombobox)
+      zCombobox_actionPerformed();
+  }
+
+
+  protected void xCombobox_actionPerformed()
+  {
+    doDimensionChange();
+  }
+
+  protected void yCombobox_actionPerformed()
+  {
+    doDimensionChange();
+  }
+
+  protected void zCombobox_actionPerformed()
+  {
+    doDimensionChange();
+  }
+
+  public void values_actionPerformed()
+  {
+
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);
+    Frame frame = new Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame, "PCA details", 500, 500);
+
+      cap.setText(pca.getDetails());
+  }
+
+  void showOriginalData()
+  {
+    // decide if av alignment is sufficiently different to original data to warrant a new window to be created
+    // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)
+    // or create a selection box around columns in alignment view
+    // test Alignment(SeqCigar[])
+    Object[] alAndColsel = seqstrings.getAlignmentAndColumnSelection(av.
+        getGapCharacter());
+
+
+    if (alAndColsel != null && alAndColsel[0]!=null)
+     {
+       Alignment al = new Alignment( (SequenceI[]) alAndColsel[0]);
+       AlignFrame af = new AlignFrame(al,
+             av.applet,
+             "Original Data for PCA",
+             false);
+
+      af.viewport.setHiddenColumns( (ColumnSelection) alAndColsel[1] );
+     }
+  }
+
+  public void labels_itemStateChanged(ItemEvent itemEvent)
+  {
+    rc.showLabels( labels.getState() );
+  }
+  Panel jPanel2 = new Panel();
+  Label jLabel1 = new Label();
+  Label jLabel2 = new Label();
+  Label jLabel3 = new Label();
+  protected Choice xCombobox = new Choice();
+  protected Choice yCombobox = new Choice();
+  protected Choice zCombobox = new Choice();
+  FlowLayout flowLayout1 = new FlowLayout();
+  BorderLayout borderLayout1 = new BorderLayout();
+  MenuBar menuBar1 = new MenuBar();
+  Menu menu1 = new Menu();
+  Menu menu2 = new Menu();
+  protected CheckboxMenuItem labels = new CheckboxMenuItem();
+  MenuItem values = new MenuItem();
+  MenuItem inputData = new MenuItem();
+
+  private void jbInit()
+      throws Exception
+  {
+    this.setLayout(borderLayout1);
+    jPanel2.setLayout(flowLayout1);
+    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel1.setText("x=");
+    jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel2.setText("y=");
+    jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel3.setText("z=");
+    jPanel2.setBackground(Color.white);
+    zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    zCombobox.addItemListener(this);
+    yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    yCombobox.addItemListener(this);
+    xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    xCombobox.addItemListener(this);
+    this.setMenuBar(menuBar1);
+    menu1.setLabel("File");
+    menu2.setLabel("View");
+    labels.setLabel("Labels");
+    labels.addItemListener(this);
+    values.setLabel("Output Values...");
+    values.addActionListener(this);
+    inputData.setLabel("Input Data...");
+    this.add(jPanel2, BorderLayout.SOUTH);
+    jPanel2.add(jLabel1, null);
+    jPanel2.add(xCombobox, null);
+    jPanel2.add(jLabel2, null);
+    jPanel2.add(yCombobox, null);
+    jPanel2.add(jLabel3, null);
+    jPanel2.add(zCombobox, null);
+    menuBar1.add(menu1);
+    menuBar1.add(menu2);
+    menu2.add(labels);
+    menu1.add(values);
+    menu1.add(inputData);
+    inputData.addActionListener(this);
+  }
+
+}
index 9a220a4..4a10099 100755 (executable)
@@ -1,72 +1,72 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.util.*;\r
-import jalview.datamodel.*;\r
-\r
-public class PaintRefresher\r
-{\r
-  static Hashtable components = new Hashtable();\r
-\r
-  public static void Register(Component comp, AlignmentI al)\r
-  {\r
-    if(components.containsKey(al))\r
-    {\r
-      Vector comps = (Vector)components.get(al);\r
-      comps.addElement(comp);\r
-    }\r
-    else\r
-    {\r
-      Vector vcoms = new Vector();\r
-      vcoms.addElement(comp);\r
-      components.put(al, vcoms);\r
-    }\r
-  }\r
-\r
-  public static void Refresh(AlignmentI al)\r
-  {\r
-    Refresh(null, al);\r
-  }\r
-\r
-  public static void Refresh(Component c, AlignmentI al)\r
-  {\r
-    Component temp;\r
-    Vector coms = (Vector)components.get(al);\r
-    Enumeration e = coms.elements();\r
-    while( e.hasMoreElements() )\r
-    {\r
-      temp = (Component)e.nextElement();\r
-\r
-      if(!temp.isValid())\r
-        coms.removeElement( temp );\r
-      else if( temp == c )\r
-        continue;\r
-      else\r
-        temp.repaint();\r
-    }\r
-\r
-  }\r
-\r
-}\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.util.*;
+import jalview.datamodel.*;
+
+public class PaintRefresher
+{
+  static Hashtable components = new Hashtable();
+
+  public static void Register(Component comp, AlignmentI al)
+  {
+    if(components.containsKey(al))
+    {
+      Vector comps = (Vector)components.get(al);
+      comps.addElement(comp);
+    }
+    else
+    {
+      Vector vcoms = new Vector();
+      vcoms.addElement(comp);
+      components.put(al, vcoms);
+    }
+  }
+
+  public static void Refresh(AlignmentI al)
+  {
+    Refresh(null, al);
+  }
+
+  public static void Refresh(Component c, AlignmentI al)
+  {
+    Component temp;
+    Vector coms = (Vector)components.get(al);
+    Enumeration e = coms.elements();
+    while( e.hasMoreElements() )
+    {
+      temp = (Component)e.nextElement();
+
+      if(!temp.isValid())
+        coms.removeElement( temp );
+      else if( temp == c )
+        continue;
+      else
+        temp.repaint();
+    }
+
+  }
+
+}
+
index fc2bfb7..f3fc433 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.event.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-import java.awt.*;\r
-\r
-public class PairwiseAlignPanel\r
-    extends Panel implements ActionListener\r
-{\r
-  Vector sequences = new Vector();\r
-  AlignmentPanel ap;\r
-\r
-  public PairwiseAlignPanel(AlignmentPanel ap)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-  }\r
-    this.ap = ap;\r
-    float scores[][] = new float[ap.av.alignment.getHeight()][ap.av.alignment.\r
-        getHeight()];\r
-    double totscore = 0;\r
-    int count = ap.av.getSelectionGroup().getSize();\r
-\r
-    int acount = 0;\r
-    for (int i = 1; i < count; i++)\r
-    {\r
-      for (int j = 0; j < i; j++)\r
-      {\r
-        acount++;\r
-        AlignSeq as = new AlignSeq(ap.av.getSelectionGroup().getSequenceAt(i),\r
-                                   ap.av.getSelectionGroup().getSequenceAt(j),\r
-                                   "pep");\r
-\r
-        as.calcScoreMatrix();\r
-        as.traceAlignment();\r
-        as.printAlignment(System.out);\r
-        scores[i][j] = (float) as.getMaxScore() / (float) as.getASeq1().length;\r
-        totscore = totscore + scores[i][j];\r
-\r
-        textarea.append(as.getOutput());\r
-        sequences.addElement(new Sequence(as.getS1().getName(), as.getAStr1()));\r
-        sequences.addElement(new Sequence(as.getS2().getName(), as.getAStr2()));\r
-\r
-      }\r
-    }\r
-\r
-    if (count > 2)\r
-    {\r
-      for (int i = 0; i < count; i++)\r
-      {\r
-        for (int j = 0; j < i; j++)\r
-        {\r
-          jalview.util.Format.print(System.out, "%7.3f",\r
-                                    scores[i][j] / totscore);\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==viewInEditorButton)\r
-      viewInEditorButton_actionPerformed();\r
-  }\r
-\r
-  protected void viewInEditorButton_actionPerformed()\r
-  {\r
-\r
-    Sequence[] seq = new Sequence[sequences.size()];\r
-\r
-    for (int i = 0; i < sequences.size(); i++)\r
-    {\r
-      seq[i] = (Sequence) sequences.elementAt(i);\r
-    }\r
-\r
-    new AlignFrame(new Alignment(seq),\r
-                                   ap.alignFrame.applet,\r
-                                   "Pairwise Aligned Sequences",\r
-                                   false);\r
-\r
-  }\r
-  protected ScrollPane scrollPane = new ScrollPane();\r
-  protected TextArea textarea = new TextArea();\r
-  protected Button viewInEditorButton = new Button();\r
-  Panel jPanel1 = new Panel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-\r
-  private void jbInit() throws Exception {\r
-      this.setLayout(borderLayout1);\r
-      textarea.setFont(new java.awt.Font("Monospaced", 0, 12));\r
-      textarea.setText("");\r
-      viewInEditorButton.setFont(new java.awt.Font("Verdana", 0, 12));\r
-      viewInEditorButton.setLabel("View in alignment editor");\r
-      viewInEditorButton.addActionListener(this);\r
-      this.add(scrollPane, BorderLayout.CENTER);\r
-      scrollPane.add(textarea);\r
-      this.add(jPanel1, BorderLayout.SOUTH);\r
-      jPanel1.add(viewInEditorButton, null);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.event.*;
+
+import jalview.analysis.*;
+import jalview.datamodel.*;
+import java.awt.*;
+
+public class PairwiseAlignPanel
+    extends Panel implements ActionListener
+{
+  Vector sequences = new Vector();
+  AlignmentPanel ap;
+
+  public PairwiseAlignPanel(AlignmentPanel ap)
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    this.ap = ap;
+    sequences = new Vector();
+
+    SequenceI[] seqs;
+    String[] seqStrings = ap.av.getViewAsString(true);
+
+    if (ap.av.getSelectionGroup() == null)
+    {
+      seqs = ap.av.alignment.getSequencesArray();
+    }
+    else
+    {
+      seqs = ap.av.getSelectionGroup().getSequencesInOrder(ap.av.alignment);
+    }
+
+    float scores[][] = new float[seqs.length][seqs.length];
+    double totscore = 0;
+    int count = ap.av.getSelectionGroup().getSize(false);
+
+    Sequence seq;
+
+    for (int i = 1; i < count; i++)
+    {
+      for (int j = 0; j < i; j++)
+      {
+
+        AlignSeq as = new AlignSeq(seqs[i], seqStrings[i],
+                                   seqs[j], seqStrings[j], "pep");
+
+        if (as.s1str.length() == 0 || as.s2str.length() == 0)
+        {
+          continue;
+        }
+
+        as.calcScoreMatrix();
+        as.traceAlignment();
+
+        as.printAlignment(System.out);
+        scores[i][j] = (float) as.getMaxScore() / (float) as.getASeq1().length;
+        totscore = totscore + scores[i][j];
+
+        textarea.append(as.getOutput());
+        seq = new Sequence(as.getS1().getName(),
+                           as.getAStr1(),
+                           as.getS1().getStart(),
+                           as.getS1().getEnd()
+            );
+        sequences.addElement(seq);
+
+        seq = new Sequence(as.getS2().getName(),
+                           as.getAStr2(),
+                           as.getS2().getStart(),
+                           as.getS2().getEnd());
+        sequences.addElement(seq);
+      }
+    }
+
+    if (count > 2)
+    {
+      System.out.println(
+          "Pairwise alignment scaled similarity score matrix\n");
+
+      for (int i = 0; i < count; i++)
+      {
+        jalview.util.Format.print(System.out, "%s \n",
+                                  ("" + i) + " " +
+                                  seqs[i].getName());
+      }
+
+      System.out.println("\n");
+
+      for (int i = 0; i < count; i++)
+      {
+        for (int j = 0; j < i; j++)
+        {
+          jalview.util.Format.print(System.out, "%7.3f",
+                                    scores[i][j] / totscore);
+        }
+      }
+
+      System.out.println("\n");
+    }
+  }
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==viewInEditorButton)
+      viewInEditorButton_actionPerformed();
+  }
+
+  protected void viewInEditorButton_actionPerformed()
+  {
+
+    Sequence[] seq = new Sequence[sequences.size()];
+
+    for (int i = 0; i < sequences.size(); i++)
+    {
+      seq[i] = (Sequence) sequences.elementAt(i);
+    }
+
+    new AlignFrame(new Alignment(seq),
+                                   ap.av.applet,
+                                   "Pairwise Aligned Sequences",
+                                   false);
+
+  }
+  protected ScrollPane scrollPane = new ScrollPane();
+  protected TextArea textarea = new TextArea();
+  protected Button viewInEditorButton = new Button();
+  Panel jPanel1 = new Panel();
+  BorderLayout borderLayout1 = new BorderLayout();
+
+  private void jbInit() throws Exception {
+      this.setLayout(borderLayout1);
+      textarea.setFont(new java.awt.Font("Monospaced", 0, 12));
+      textarea.setText("");
+      viewInEditorButton.setFont(new java.awt.Font("Verdana", 0, 12));
+      viewInEditorButton.setLabel("View in alignment editor");
+      viewInEditorButton.addActionListener(this);
+      this.add(scrollPane, BorderLayout.CENTER);
+      scrollPane.add(textarea);
+      this.add(jPanel1, BorderLayout.SOUTH);
+      jPanel1.add(viewInEditorButton, null);
+  }
+
+}
index 504338a..2fe3576 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class RedundancyPanel extends SliderPanel\r
-{\r
-  AlignmentPanel ap;\r
-\r
-  SequenceI[] oldAlignment;\r
-\r
-  public RedundancyPanel(AlignmentPanel ap)\r
-  {\r
-    super(ap, 0, false, null);\r
-\r
-    this.ap = ap;\r
-\r
-    label.setText("Enter the redundancy threshold");\r
-\r
-    slider.addAdjustmentListener(new AdjustmentListener()\r
-    {\r
-      public void adjustmentValueChanged(AdjustmentEvent evt)\r
-      {\r
-        valueField.setText(slider.getValue() + "");\r
-      }\r
-    });\r
-\r
-    slider.setMinimum(0);\r
-    slider.setMaximum(100);\r
-    slider.setValue(100);\r
-\r
-  }\r
-\r
-  public void applyButton_actionPerformed()\r
-  {\r
-    float threshold = slider.getValue();\r
-    Vector del;\r
-\r
-    oldAlignment = new SequenceI[ap.av.alignment.getHeight()];\r
-    for (int i = 0; i < ap.av.alignment.getHeight(); i++)\r
-    {\r
-      oldAlignment[i] = new Sequence(ap.av.alignment.getSequenceAt(i).getName(),\r
-                                     ap.av.alignment.getSequenceAt(i).\r
-                                     getSequence());\r
-    }\r
-\r
-    undoButton.setEnabled(true);\r
-\r
-    SequenceGroup sg = ap.av.getSelectionGroup();\r
-    if (sg != null && sg.getSize() > 1)\r
-    {\r
-\r
-      del = ap.av.alignment.removeRedundancy(threshold, sg.sequences);\r
-      for (int i = 0; i < del.size(); i++)\r
-      {\r
-        if (sg.sequences.contains( (SequenceI) del.elementAt(i)))\r
-        {\r
-          sg.deleteSequence( (SequenceI) del.elementAt(i), true);\r
-        }\r
-      }\r
-\r
-    }\r
-    else\r
-    {\r
-      Vector s = new Vector();\r
-      int i = 0;\r
-      while (i < ap.av.alignment.getHeight())\r
-      {\r
-        s.addElement(ap.av.alignment.getSequenceAt(i));\r
-        i++;\r
-      }\r
-      del = ap.av.alignment.removeRedundancy(threshold, s);\r
-      for (int j = 0; j < del.size(); j++)\r
-      {\r
-        if (sg.sequences.contains( (SequenceI) del.elementAt(j)))\r
-        {\r
-          sg.deleteSequence( (SequenceI) del.elementAt(j), true);\r
-        }\r
-\r
-      }\r
-    }\r
-\r
-    ap.repaint();\r
-\r
-  }\r
-\r
-  public void undoButton_actionPerformed()\r
-  {\r
-    undoButton.setEnabled(false);\r
-    ap.av.setAlignment(new Alignment(oldAlignment));\r
-    oldAlignment = null;\r
-    ap.repaint();\r
-  }\r
-\r
-  public void valueField_actionPerformed(ActionEvent e)\r
-  {\r
-    try\r
-    {\r
-      int i = Integer.parseInt(valueField.getText());\r
-      slider.setValue(i);\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      valueField.setText(slider.getValue() + "");\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.event.*;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+import jalview.appletgui.PaintRefresher;
+
+public class RedundancyPanel extends SliderPanel implements Runnable, WindowListener
+{
+  AlignmentPanel ap;
+
+  Stack historyList = new Stack(); // simpler than synching with alignFrame.
+  float [] redundancy;
+  SequenceI [] originalSequences;
+  Frame frame;
+  Vector redundantSeqs;
+
+  public RedundancyPanel(AlignmentPanel ap)
+  {
+    super(ap, 0, false, null);
+
+    redundantSeqs = new Vector();
+    this.ap = ap;
+    undoButton.setVisible(true);
+    applyButton.setVisible(true);
+    allGroupsCheck.setVisible(false);
+
+    label.setText("Enter the redundancy threshold");
+    valueField.setText("100");
+
+    slider.setVisibleAmount(1);
+    slider.setMinimum(0);
+    slider.setMaximum(100+slider.getVisibleAmount());
+    slider.setValue(100);
+
+    slider.addAdjustmentListener(new AdjustmentListener()
+    {
+      public void adjustmentValueChanged(AdjustmentEvent evt)
+      {
+        valueField.setText(slider.getValue() + "");
+        sliderValueChanged();
+      }
+    });
+
+    frame = new Frame();
+    frame.add(this);
+    jalview.bin.JalviewLite.addFrame(frame, "Redundancy threshold selection",
+                                     400, 100);
+
+    frame.addWindowListener(this);
+
+    Thread worker = new Thread(this);
+    worker.start();
+  }
+  /**
+   * This is a copy of remove redundancy in jalivew.datamodel.Alignment
+   * except we dont want to remove redundancy, just calculate once
+   * so we can use the slider to dynamically hide redundant sequences
+   *
+   * @param threshold DOCUMENT ME!
+   * @param sel DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public void run()
+  {
+      label.setText("Calculating....");
+
+      slider.setVisible(false);
+      applyButton.setEnabled(false);
+      valueField.setVisible(false);
+
+      validate();
+
+      String[] omitHidden = null;
+
+      SequenceGroup sg = ap.av.getSelectionGroup();
+      int height;
+
+      int start, end;
+
+      if ( (sg != null) && (sg.getSize(false) >= 1))
+      {
+         originalSequences = sg.getSequencesInOrder(ap.av.alignment);
+         start = sg.getStartRes();
+         end = sg.getEndRes();
+      }
+      else
+      {
+        originalSequences = ap.av.alignment.getSequencesArray();
+        start = 0;
+        end = ap.av.alignment.getWidth();
+      }
+
+      height = originalSequences.length;
+
+      redundancy = new float[height];
+      for (int i = 0; i < height; i++)
+      {
+        redundancy[i] = 0f;
+      }
+
+    //  if (ap.av.hasHiddenColumns)
+      {
+     //   omitHidden = ap.av.getSelectionAsString();
+      }
+
+
+     // long start = System.currentTimeMillis();
+
+      float pid;
+      String seqi, seqj;
+      for (int i = 0; i < height; i++)
+      {
+          for (int j = 0; j < i; j++)
+          {
+            if(i==j)
+              continue;
+
+            if(omitHidden==null)
+            {
+              seqi = originalSequences[i].getSequence(start, end);
+              seqj = originalSequences[j].getSequence(start, end);
+            }
+            else
+            {
+              seqi = omitHidden[i];
+              seqj = omitHidden[j];
+            }
+
+            pid = jalview.util.Comparison.PID( seqi,  seqj );
+
+            if(seqj.length() < seqi.length())
+              redundancy[j] = Math.max(pid, redundancy[j]);
+            else
+              redundancy[i] = Math.max(pid, redundancy[i]);
+
+          }
+      }
+
+
+      label.setText("Enter the redundancy threshold");
+      slider.setVisible(true);
+      applyButton.setEnabled(true);
+      valueField.setVisible(true);
+
+      validate();
+     // System.out.println("blob done "+ (System.currentTimeMillis()-start));
+  }
+
+  void sliderValueChanged()
+  {
+    if(redundancy==null)
+      return;
+
+    float value = slider.getValue();
+
+    for(int i=0; i<redundancy.length; i++)
+    {
+      if (value > redundancy[i])
+         redundantSeqs.removeElement(originalSequences[i]);
+      else if(!redundantSeqs.contains(originalSequences[i]))
+         redundantSeqs.addElement(originalSequences[i]);
+    }
+
+    ap.idPanel.idCanvas.setHighlighted(redundantSeqs);
+
+    PaintRefresher.Refresh(null,ap.av.alignment);
+
+    }
+  public void applyButton_actionPerformed()
+  {
+    historyList.push(new HistoryItem("Remove redundancy",
+                        ap.av.alignment, HistoryItem.HIDE));
+
+            if ((historyList.size() == 1) ||
+                    !ap.alignFrame.historyList.contains(historyList.firstElement()))
+            {
+                ap.alignFrame.addHistoryItem((HistoryItem) historyList.firstElement());
+                ap.alignFrame.updateEditMenuBar();
+            }
+
+            Vector del = new Vector();
+
+            undoButton.setEnabled(true);
+
+            float value = slider.getValue();
+            SequenceGroup sg = ap.av.getSelectionGroup();
+
+            for (int i = 0; i < redundancy.length; i++)
+            {
+              if (value <= redundancy[i])
+              {
+                SequenceI seq = originalSequences[i];
+                ap.av.alignment.deleteSequence(seq);
+                del.addElement(seq);
+                if (sg != null)
+                {
+                  sg.deleteSequence(seq, false);
+                }
+              }
+            }
+
+
+            // This has to be done before the restoreHistoryItem method of alignFrame will
+            // actually restore these sequences.
+            if (del.size() > 0)
+            {
+                for (int i = 0, j = del.size(); i < j; i++)
+                {
+                    SequenceI sq = (SequenceI) del.elementAt(i);
+                    sq.deleteChars(0, sq.getLength());
+                }
+            }
+
+        ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
+        ap.alignFrame.updateEditMenuBar();
+
+  }
+
+  public void undoButton_actionPerformed()
+  {
+    HistoryItem hi = (HistoryItem) historyList.pop();
+    ap.alignFrame.restoreHistoryItem(hi);
+
+    if (historyList.size() == 0)
+    {
+      undoButton.setEnabled(false);
+    }
+    ap.alignFrame.updateEditMenuBar();
+  }
+
+  public void valueField_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      int i = Integer.parseInt(valueField.getText());
+      slider.setValue(i);
+    }
+    catch (Exception ex)
+    {
+      valueField.setText(slider.getValue() + "");
+    }
+  }
+
+
+  public void windowOpened(WindowEvent evt)
+  {}
+
+  public void windowClosing(WindowEvent evt)
+  {
+    ap.idPanel.idCanvas.setHighlighted(null);
+  }
+
+  public void windowClosed(WindowEvent evt)
+  {}
+
+  public void windowActivated(WindowEvent evt)
+  {}
+  public void windowDeactivated(WindowEvent evt)
+  {}
+  public void windowIconified(WindowEvent evt)
+  {}
+  public void windowDeiconified(WindowEvent evt)
+  {}
+}
index 370de5f..3edf819 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.math.*;\r
-import jalview.util.*;\r
-\r
-public class RotatableCanvas\r
-    extends Panel implements MouseListener,\r
-    MouseMotionListener,\r
-    KeyListener\r
-{\r
-  RotatableMatrix idmat = new RotatableMatrix(3, 3);\r
-  RotatableMatrix objmat = new RotatableMatrix(3, 3);\r
-  RotatableMatrix rotmat = new RotatableMatrix(3, 3);\r
-  String tooltip;\r
-  int toolx, tooly;\r
-\r
-  //RubberbandRectangle rubberband;\r
-\r
-  boolean drawAxes = true;\r
-\r
-  int omx = 0;\r
-  int mx = 0;\r
-  int omy = 0;\r
-  int my = 0;\r
-\r
-  Image img;\r
-  Graphics ig;\r
-\r
-  Dimension prefsize;\r
-\r
-  float centre[] = new float[3];\r
-  float width[] = new float[3];\r
-\r
-  float max[] = new float[3];\r
-  float min[] = new float[3];\r
-\r
-  float maxwidth;\r
-  float scale;\r
-\r
-  int npoint;\r
-\r
-  Vector points;\r
-  float[][] orig;\r
-  float[][] axes;\r
-\r
-  int startx;\r
-  int starty;\r
-\r
-  int lastx;\r
-  int lasty;\r
-\r
-  int rectx1;\r
-  int recty1;\r
-  int rectx2;\r
-  int recty2;\r
-\r
-  float scalefactor = 1;\r
-\r
-  AlignViewport av;\r
-  boolean showLabels = false;\r
-\r
-  public RotatableCanvas(AlignViewport av)\r
-  {\r
-    this.av = av;\r
-  }\r
-\r
-  public void showLabels(boolean b)\r
-  {\r
-    showLabels = b;\r
-    repaint();\r
-  }\r
-\r
-  public void setPoints(Vector points, int npoint)\r
-  {\r
-    this.points = points;\r
-    this.npoint = npoint;\r
-    PaintRefresher.Register(this, av.alignment);\r
-\r
-    prefsize = getPreferredSize();\r
-    orig = new float[npoint][3];\r
-\r
-    for (int i = 0; i < npoint; i++)\r
-    {\r
-      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-      for (int j = 0; j < 3; j++)\r
-      {\r
-        orig[i][j] = sp.coord[j];\r
-      }\r
-    }\r
-    //Initialize the matrices to identity\r
-\r
-    for (int i = 0; i < 3; i++)\r
-    {\r
-      for (int j = 0; j < 3; j++)\r
-      {\r
-        if (i != j)\r
-        {\r
-          idmat.addElement(i, j, 0);\r
-          objmat.addElement(i, j, 0);\r
-          rotmat.addElement(i, j, 0);\r
-        }\r
-        else\r
-        {\r
-          idmat.addElement(i, j, 0);\r
-          objmat.addElement(i, j, 0);\r
-          rotmat.addElement(i, j, 0);\r
-        }\r
-      }\r
-    }\r
-\r
-    axes = new float[3][3];\r
-    initAxes();\r
-\r
-    findCentre();\r
-    findWidth();\r
-\r
-    scale = findScale();\r
-\r
-    //    System.out.println("Scale factor = " + scale);\r
-\r
-    addMouseListener(this);\r
-    addKeyListener(this);\r
-    // if (getParent() != null) {\r
-    //   getParent().addKeyListener(this);\r
-    //}\r
-    addMouseMotionListener(this);\r
-\r
-    // Add rubberband\r
-    //   rubberband  = new RubberbandRectangle(this);\r
-    //  rubberband.setActive(true);\r
-    //   rubberband.addListener(this);\r
-  }\r
-\r
-  /* public boolean handleSequenceSelectionEvent(SequenceSelectionEvent evt) {\r
-     redrawneeded = true;\r
-     repaint();\r
-     return true;\r
-   }\r
-\r
-   public void removeNotify() {\r
-     controller.removeListener(this);\r
-     super.removeNotify();\r
-   }*/\r
-\r
-  public void initAxes()\r
-  {\r
-    for (int i = 0; i < 3; i++)\r
-    {\r
-      for (int j = 0; j < 3; j++)\r
-      {\r
-        if (i != j)\r
-        {\r
-          axes[i][j] = 0;\r
-        }\r
-        else\r
-        {\r
-          axes[i][j] = 1;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  public void findWidth()\r
-  {\r
-    max = new float[3];\r
-    min = new float[3];\r
-\r
-    max[0] = (float) - 1e30;\r
-    max[1] = (float) - 1e30;\r
-    max[2] = (float) - 1e30;\r
-\r
-    min[0] = (float) 1e30;\r
-    min[1] = (float) 1e30;\r
-    min[2] = (float) 1e30;\r
-\r
-    for (int i = 0; i < 3; i++)\r
-    {\r
-      for (int j = 0; j < npoint; j++)\r
-      {\r
-        SequencePoint sp = (SequencePoint) points.elementAt(j);\r
-        if (sp.coord[i] >= max[i])\r
-        {\r
-          max[i] = sp.coord[i];\r
-        }\r
-        if (sp.coord[i] <= min[i])\r
-        {\r
-          min[i] = sp.coord[i];\r
-        }\r
-      }\r
-    }\r
-\r
-    //    System.out.println("xmax " + max[0] + " min " + min[0]);\r
-    //System.out.println("ymax " + max[1] + " min " + min[1]);\r
-    //System.out.println("zmax " + max[2] + " min " + min[2]);\r
-\r
-    width[0] = Math.abs(max[0] - min[0]);\r
-    width[1] = Math.abs(max[1] - min[1]);\r
-    width[2] = Math.abs(max[2] - min[2]);\r
-\r
-    maxwidth = width[0];\r
-\r
-    if (width[1] > width[0])\r
-    {\r
-      maxwidth = width[1];\r
-    }\r
-    if (width[2] > width[1])\r
-    {\r
-      maxwidth = width[2];\r
-    }\r
-\r
-    //System.out.println("Maxwidth = " + maxwidth);\r
-  }\r
-\r
-  public float findScale()\r
-  {\r
-    int dim, width, height;\r
-    if (getSize().width != 0)\r
-    {\r
-      width = getSize().width;\r
-      height = getSize().height;\r
-    }\r
-    else\r
-    {\r
-      width = prefsize.width;\r
-      height = prefsize.height;\r
-    }\r
-\r
-    if (width < height)\r
-    {\r
-      dim = width;\r
-    }\r
-    else\r
-    {\r
-      dim = height;\r
-    }\r
-\r
-    return (float) (dim * scalefactor / (2 * maxwidth));\r
-  }\r
-\r
-  public void findCentre()\r
-  {\r
-    //Find centre coordinate\r
-    findWidth();\r
-\r
-    centre[0] = (max[0] + min[0]) / 2;\r
-    centre[1] = (max[1] + min[1]) / 2;\r
-    centre[2] = (max[2] + min[2]) / 2;\r
-\r
-    //    System.out.println("Centre x " + centre[0]);\r
-    //System.out.println("Centre y " + centre[1]);\r
-    //System.out.println("Centre z " + centre[2]);\r
-  }\r
-\r
-  public Dimension getPreferredSize()\r
-  {\r
-    if (prefsize != null)\r
-    {\r
-      return prefsize;\r
-    }\r
-    else\r
-    {\r
-      return new Dimension(400, 400);\r
-    }\r
-  }\r
-\r
-  public Dimension getMinimumSize()\r
-  {\r
-    return getPreferredSize();\r
-  }\r
-\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-  public void paint(Graphics g)\r
-  {\r
-    if (points == null)\r
-    {\r
-      g.setFont(new Font("Verdana", Font.PLAIN, 18));\r
-      g.drawString("Calculating PCA....", 20, getSize().height / 2);\r
-    }\r
-    else\r
-    {\r
-\r
-      //Only create the image at the beginning -\r
-      if ( (img == null) || (prefsize.width != getSize().width) ||\r
-          (prefsize.height != getSize().height))\r
-      {\r
-        prefsize.width = getSize().width;\r
-        prefsize.height = getSize().height;\r
-\r
-        scale = findScale();\r
-\r
-        //      System.out.println("New scale = " + scale);\r
-        img = createImage(getSize().width, getSize().height);\r
-        ig = img.getGraphics();\r
-\r
-      }\r
-\r
-      drawBackground(ig, Color.black);\r
-      drawScene(ig);\r
-      if (drawAxes == true)\r
-      {\r
-        drawAxes(ig);\r
-      }\r
-\r
-      if(tooltip!=null)\r
-      {\r
-        ig.setColor(Color.red);\r
-        ig.drawString(tooltip, toolx, tooly);\r
-      }\r
-\r
-      g.drawImage(img, 0, 0, this);\r
-    }\r
-  }\r
-\r
-  public void drawAxes(Graphics g)\r
-  {\r
-\r
-    g.setColor(Color.yellow);\r
-    for (int i = 0; i < 3; i++)\r
-    {\r
-      g.drawLine(getSize().width / 2, getSize().height / 2,\r
-                 (int) (axes[i][0] * scale * max[0] + getSize().width / 2),\r
-                 (int) (axes[i][1] * scale * max[1] + getSize().height / 2));\r
-    }\r
-  }\r
-\r
-  public void drawBackground(Graphics g, Color col)\r
-  {\r
-    g.setColor(col);\r
-    g.fillRect(0, 0, prefsize.width, prefsize.height);\r
-  }\r
-\r
-  public void drawScene(Graphics g)\r
-  {\r
-    //boolean darker = false;\r
-\r
-    int halfwidth = getSize().width / 2;\r
-    int halfheight = getSize().height / 2;\r
-\r
-    for (int i = 0; i < npoint; i++)\r
-    {\r
-      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-      int x = (int) ( (float) (sp.coord[0] - centre[0]) * scale) + halfwidth;\r
-      int y = (int) ( (float) (sp.coord[1] - centre[1]) * scale) + halfheight;\r
-      float z = sp.coord[1] - centre[2];\r
-\r
-      if (sp.sequence.getColor() == Color.black)\r
-      {\r
-        g.setColor(Color.white);\r
-      }\r
-      else\r
-      {\r
-        g.setColor(sp.sequence.getColor());\r
-      }\r
-\r
-      if (av.getSelectionGroup() != null)\r
-      {\r
-        if (av.getSelectionGroup().sequences.contains( ( (SequencePoint) points.\r
-            elementAt(i)).sequence))\r
-        {\r
-          g.setColor(Color.gray);\r
-        }\r
-      }\r
-      if (z < 0)\r
-      {\r
-        g.setColor(g.getColor().darker());\r
-      }\r
-\r
-      g.fillRect(x - 3, y - 3, 6, 6);\r
-      if (showLabels)\r
-      {\r
-        g.setColor(Color.red);\r
-        g.drawString( ( (SequencePoint) points.elementAt(i)).sequence.\r
-                     getName(),\r
-                     x - 3, y - 4);\r
-      }\r
-    }\r
-  }\r
-\r
-  public Dimension minimumsize()\r
-  {\r
-    return prefsize;\r
-  }\r
-\r
-  public Dimension preferredsize()\r
-  {\r
-    return prefsize;\r
-  }\r
-\r
-  public void keyTyped(KeyEvent evt)\r
-  {}\r
-\r
-  public void keyReleased(KeyEvent evt)\r
-  {}\r
-\r
-  public void keyPressed(KeyEvent evt)\r
-  {\r
-    if (evt.getKeyCode() == KeyEvent.VK_UP)\r
-    {\r
-      scalefactor = (float) (scalefactor * 1.1);\r
-      scale = findScale();\r
-    }\r
-    else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
-    {\r
-      scalefactor = (float) (scalefactor * 0.9);\r
-      scale = findScale();\r
-    }\r
-    else if (evt.getKeyChar() == 's')\r
-    {\r
-      System.err.println("DEBUG: Rectangle selection"); // log.debug\r
-      if (rectx2 != -1 && recty2 != -1)\r
-      {\r
-        rectSelect(rectx1, recty1, rectx2, recty2);\r
-\r
-      }\r
-    }\r
-    repaint();\r
-  }\r
-\r
-  public void printPoints()\r
-  {\r
-    for (int i = 0; i < npoint; i++)\r
-    {\r
-      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-      Format.print(System.out, "%5d ", i);\r
-      for (int j = 0; j < 3; j++)\r
-      {\r
-        Format.print(System.out, "%13.3f  ", sp.coord[j]);\r
-      }\r
-      System.out.println();\r
-    }\r
-  }\r
-\r
-  public void mouseClicked(MouseEvent evt)\r
-  {}\r
-\r
-  public void mouseEntered(MouseEvent evt)\r
-  {}\r
-\r
-  public void mouseExited(MouseEvent evt)\r
-  {}\r
-\r
-  public void mouseReleased(MouseEvent evt)\r
-  {}\r
-\r
-  public void mousePressed(MouseEvent evt)\r
-  {\r
-    int x = evt.getX();\r
-    int y = evt.getY();\r
-\r
-    mx = x;\r
-    my = y;\r
-\r
-    omx = mx;\r
-    omy = my;\r
-\r
-    startx = x;\r
-    starty = y;\r
-\r
-    rectx1 = x;\r
-    recty1 = y;\r
-\r
-    rectx2 = -1;\r
-    recty2 = -1;\r
-\r
-    SequenceI found = findPoint(x, y);\r
-\r
-    if (found != null)\r
-    {\r
-      if (av.getSelectionGroup() != null)\r
-      {\r
-        av.getSelectionGroup().addOrRemove(found, true);\r
-        av.getSelectionGroup().setEndRes(av.alignment.getWidth()-1);\r
-        PaintRefresher.Refresh(this, av.alignment);\r
-      }\r
-      else\r
-      {\r
-        av.setSelectionGroup(new SequenceGroup());\r
-        av.getSelectionGroup().addOrRemove(found, true);\r
-        av.getSelectionGroup().setEndRes(av.alignment.getWidth()-1);\r
-\r
-      }\r
-    }\r
-    repaint();\r
-  }\r
-\r
-\r
-  public void mouseMoved(MouseEvent evt)\r
-  {\r
-     SequenceI found = findPoint(evt.getX(), evt.getY());\r
-     if(found==null)\r
-       tooltip = null;\r
-     else\r
-     {\r
-       tooltip = found.getName();\r
-       toolx = evt.getX();\r
-       tooly = evt.getY();\r
-     }\r
-     repaint();\r
-  }\r
-\r
-  public void mouseDragged(MouseEvent evt)\r
-  {\r
-    mx = evt.getX();\r
-    my = evt.getY();\r
-\r
-      rotmat.setIdentity();\r
-\r
-      rotmat.rotate( (float) (my - omy), 'x');\r
-      rotmat.rotate( (float) (mx - omx), 'y');\r
-\r
-      for (int i = 0; i < npoint; i++)\r
-      {\r
-        SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-        sp.coord[0] -= centre[0];\r
-        sp.coord[1] -= centre[1];\r
-        sp.coord[2] -= centre[2];\r
-\r
-        //Now apply the rotation matrix\r
-        sp.coord = rotmat.vectorMultiply(sp.coord);\r
-\r
-        //Now translate back again\r
-        sp.coord[0] += centre[0];\r
-        sp.coord[1] += centre[1];\r
-        sp.coord[2] += centre[2];\r
-      }\r
-\r
-      for (int i = 0; i < 3; i++)\r
-      {\r
-        axes[i] = rotmat.vectorMultiply(axes[i]);\r
-      }\r
-      omx = mx;\r
-      omy = my;\r
-\r
-      paint(this.getGraphics());\r
-  }\r
-\r
-  public void rectSelect(int x1, int y1, int x2, int y2)\r
-  {\r
-    //boolean changedSel = false;\r
-    for (int i = 0; i < npoint; i++)\r
-    {\r
-      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-      int tmp1 = (int) ( (sp.coord[0] - centre[0]) * scale +\r
-                        (float) getSize().width / 2.0);\r
-      int tmp2 = (int) ( (sp.coord[1] - centre[1]) * scale +\r
-                        (float) getSize().height / 2.0);\r
-\r
-      if (tmp1 > x1 && tmp1 < x2 && tmp2 > y1 && tmp2 < y2)\r
-      {\r
-        if (av != null)\r
-        {\r
-          if (!av.getSelectionGroup().sequences.contains(sp.sequence))\r
-          {\r
-            av.getSelectionGroup().addSequence(sp.sequence, true);\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  public SequenceI findPoint(int x, int y)\r
-  {\r
-\r
-    int halfwidth = getSize().width / 2;\r
-    int halfheight = getSize().height / 2;\r
-\r
-    int found = -1;\r
-\r
-    for (int i = 0; i < npoint; i++)\r
-    {\r
-\r
-      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-      int px = (int) ( (float) (sp.coord[0] - centre[0]) * scale) + halfwidth;\r
-      int py = (int) ( (float) (sp.coord[1] - centre[1]) * scale) + halfheight;\r
-\r
-      if (Math.abs(px - x) < 3 && Math.abs(py - y) < 3)\r
-      {\r
-        found = i;\r
-      }\r
-    }\r
-    if (found != -1)\r
-    {\r
-      return ( (SequencePoint) points.elementAt(found)).sequence;\r
-    }\r
-    else\r
-    {\r
-      return null;\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.math.*;
+import jalview.util.*;
+
+public class RotatableCanvas
+    extends Panel implements MouseListener,
+    MouseMotionListener,
+    KeyListener
+{
+  RotatableMatrix idmat = new RotatableMatrix(3, 3);
+  RotatableMatrix objmat = new RotatableMatrix(3, 3);
+  RotatableMatrix rotmat = new RotatableMatrix(3, 3);
+  String tooltip;
+  int toolx, tooly;
+
+  //RubberbandRectangle rubberband;
+
+  boolean drawAxes = true;
+
+  int omx = 0;
+  int mx = 0;
+  int omy = 0;
+  int my = 0;
+
+  Image img;
+  Graphics ig;
+
+  Dimension prefsize;
+
+  float centre[] = new float[3];
+  float width[] = new float[3];
+
+  float max[] = new float[3];
+  float min[] = new float[3];
+
+  float maxwidth;
+  float scale;
+
+  int npoint;
+
+  Vector points;
+  float[][] orig;
+  float[][] axes;
+
+  int startx;
+  int starty;
+
+  int lastx;
+  int lasty;
+
+  int rectx1;
+  int recty1;
+  int rectx2;
+  int recty2;
+
+  float scalefactor = 1;
+
+  AlignViewport av;
+  boolean showLabels = false;
+
+  public RotatableCanvas(AlignViewport av)
+  {
+    this.av = av;
+  }
+
+  public void showLabels(boolean b)
+  {
+    showLabels = b;
+    repaint();
+  }
+
+  public void setPoints(Vector points, int npoint)
+  {
+    this.points = points;
+    this.npoint = npoint;
+    PaintRefresher.Register(this, av.alignment);
+
+    prefsize = getPreferredSize();
+    orig = new float[npoint][3];
+
+    for (int i = 0; i < npoint; i++)
+    {
+      SequencePoint sp = (SequencePoint) points.elementAt(i);
+      for (int j = 0; j < 3; j++)
+      {
+        orig[i][j] = sp.coord[j];
+      }
+    }
+    //Initialize the matrices to identity
+
+    for (int i = 0; i < 3; i++)
+    {
+      for (int j = 0; j < 3; j++)
+      {
+        if (i != j)
+        {
+          idmat.addElement(i, j, 0);
+          objmat.addElement(i, j, 0);
+          rotmat.addElement(i, j, 0);
+        }
+        else
+        {
+          idmat.addElement(i, j, 0);
+          objmat.addElement(i, j, 0);
+          rotmat.addElement(i, j, 0);
+        }
+      }
+    }
+
+    axes = new float[3][3];
+    initAxes();
+
+    findCentre();
+    findWidth();
+
+    scale = findScale();
+
+    //    System.out.println("Scale factor = " + scale);
+
+    addMouseListener(this);
+    addKeyListener(this);
+    // if (getParent() != null) {
+    //   getParent().addKeyListener(this);
+    //}
+    addMouseMotionListener(this);
+
+    // Add rubberband
+    //   rubberband  = new RubberbandRectangle(this);
+    //  rubberband.setActive(true);
+    //   rubberband.addListener(this);
+  }
+
+  /* public boolean handleSequenceSelectionEvent(SequenceSelectionEvent evt) {
+     redrawneeded = true;
+     repaint();
+     return true;
+   }
+
+   public void removeNotify() {
+     controller.removeListener(this);
+     super.removeNotify();
+   }*/
+
+  public void initAxes()
+  {
+    for (int i = 0; i < 3; i++)
+    {
+      for (int j = 0; j < 3; j++)
+      {
+        if (i != j)
+        {
+          axes[i][j] = 0;
+        }
+        else
+        {
+          axes[i][j] = 1;
+        }
+      }
+    }
+  }
+
+  public void findWidth()
+  {
+    max = new float[3];
+    min = new float[3];
+
+    max[0] = (float) - 1e30;
+    max[1] = (float) - 1e30;
+    max[2] = (float) - 1e30;
+
+    min[0] = (float) 1e30;
+    min[1] = (float) 1e30;
+    min[2] = (float) 1e30;
+
+    for (int i = 0; i < 3; i++)
+    {
+      for (int j = 0; j < npoint; j++)
+      {
+        SequencePoint sp = (SequencePoint) points.elementAt(j);
+        if (sp.coord[i] >= max[i])
+        {
+          max[i] = sp.coord[i];
+        }
+        if (sp.coord[i] <= min[i])
+        {
+          min[i] = sp.coord[i];
+        }
+      }
+    }
+
+    //    System.out.println("xmax " + max[0] + " min " + min[0]);
+    //System.out.println("ymax " + max[1] + " min " + min[1]);
+    //System.out.println("zmax " + max[2] + " min " + 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];
+
+    if (width[1] > width[0])
+    {
+      maxwidth = width[1];
+    }
+    if (width[2] > width[1])
+    {
+      maxwidth = width[2];
+    }
+
+    //System.out.println("Maxwidth = " + maxwidth);
+  }
+
+  public float findScale()
+  {
+    int dim, width, height;
+    if (getSize().width != 0)
+    {
+      width = getSize().width;
+      height = getSize().height;
+    }
+    else
+    {
+      width = prefsize.width;
+      height = prefsize.height;
+    }
+
+    if (width < height)
+    {
+      dim = width;
+    }
+    else
+    {
+      dim = height;
+    }
+
+    return (float) (dim * scalefactor / (2 * maxwidth));
+  }
+
+  public void findCentre()
+  {
+    //Find centre coordinate
+    findWidth();
+
+    centre[0] = (max[0] + min[0]) / 2;
+    centre[1] = (max[1] + min[1]) / 2;
+    centre[2] = (max[2] + min[2]) / 2;
+
+    //    System.out.println("Centre x " + centre[0]);
+    //System.out.println("Centre y " + centre[1]);
+    //System.out.println("Centre z " + centre[2]);
+  }
+
+  public Dimension getPreferredSize()
+  {
+    if (prefsize != null)
+    {
+      return prefsize;
+    }
+    else
+    {
+      return new Dimension(400, 400);
+    }
+  }
+
+  public Dimension getMinimumSize()
+  {
+    return getPreferredSize();
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+  public void paint(Graphics g)
+  {
+    if (points == null)
+    {
+      g.setFont(new Font("Verdana", Font.PLAIN, 18));
+      g.drawString("Calculating PCA....", 20, getSize().height / 2);
+    }
+    else
+    {
+
+      //Only create the image at the beginning -
+      if ( (img == null) || (prefsize.width != getSize().width) ||
+          (prefsize.height != getSize().height))
+      {
+        prefsize.width = getSize().width;
+        prefsize.height = getSize().height;
+
+        scale = findScale();
+
+        //      System.out.println("New scale = " + scale);
+        img = createImage(getSize().width, getSize().height);
+        ig = img.getGraphics();
+
+      }
+
+      drawBackground(ig, Color.black);
+      drawScene(ig);
+      if (drawAxes == true)
+      {
+        drawAxes(ig);
+      }
+
+      if(tooltip!=null)
+      {
+        ig.setColor(Color.red);
+        ig.drawString(tooltip, toolx, tooly);
+      }
+
+      g.drawImage(img, 0, 0, this);
+    }
+  }
+
+  public void drawAxes(Graphics g)
+  {
+
+    g.setColor(Color.yellow);
+    for (int i = 0; i < 3; i++)
+    {
+      g.drawLine(getSize().width / 2, getSize().height / 2,
+                 (int) (axes[i][0] * scale * max[0] + getSize().width / 2),
+                 (int) (axes[i][1] * scale * max[1] + getSize().height / 2));
+    }
+  }
+
+  public void drawBackground(Graphics g, Color col)
+  {
+    g.setColor(col);
+    g.fillRect(0, 0, prefsize.width, prefsize.height);
+  }
+
+  public void drawScene(Graphics g)
+  {
+    //boolean darker = false;
+
+    int halfwidth = getSize().width / 2;
+    int halfheight = getSize().height / 2;
+
+    for (int i = 0; i < npoint; i++)
+    {
+      SequencePoint sp = (SequencePoint) points.elementAt(i);
+      int x = (int) ( (float) (sp.coord[0] - centre[0]) * scale) + halfwidth;
+      int y = (int) ( (float) (sp.coord[1] - centre[1]) * scale) + halfheight;
+      float z = sp.coord[1] - centre[2];
+
+      if (sp.sequence.getColor() == Color.black)
+      {
+        g.setColor(Color.white);
+      }
+      else
+      {
+        g.setColor(sp.sequence.getColor());
+      }
+
+      if (av.getSelectionGroup() != null)
+      {
+        if (av.getSelectionGroup().getSequences(false).contains( ( (SequencePoint) points.
+            elementAt(i)).sequence))
+        {
+          g.setColor(Color.gray);
+        }
+      }
+      if (z < 0)
+      {
+        g.setColor(g.getColor().darker());
+      }
+
+      g.fillRect(x - 3, y - 3, 6, 6);
+      if (showLabels)
+      {
+        g.setColor(Color.red);
+        g.drawString( ( (SequencePoint) points.elementAt(i)).sequence.
+                     getName(),
+                     x - 3, y - 4);
+      }
+    }
+  }
+
+  public Dimension minimumsize()
+  {
+    return prefsize;
+  }
+
+  public Dimension preferredsize()
+  {
+    return prefsize;
+  }
+
+  public void keyTyped(KeyEvent evt)
+  {}
+
+  public void keyReleased(KeyEvent evt)
+  {}
+
+  public void keyPressed(KeyEvent evt)
+  {
+    if (evt.getKeyCode() == KeyEvent.VK_UP)
+    {
+      scalefactor = (float) (scalefactor * 1.1);
+      scale = findScale();
+    }
+    else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
+    {
+      scalefactor = (float) (scalefactor * 0.9);
+      scale = findScale();
+    }
+    else if (evt.getKeyChar() == 's')
+    {
+      System.err.println("DEBUG: Rectangle selection"); // log.debug
+      if (rectx2 != -1 && recty2 != -1)
+      {
+        rectSelect(rectx1, recty1, rectx2, recty2);
+
+      }
+    }
+    repaint();
+  }
+
+  public void printPoints()
+  {
+    for (int i = 0; i < npoint; i++)
+    {
+      SequencePoint sp = (SequencePoint) points.elementAt(i);
+      Format.print(System.out, "%5d ", i);
+      for (int j = 0; j < 3; j++)
+      {
+        Format.print(System.out, "%13.3f  ", sp.coord[j]);
+      }
+      System.out.println();
+    }
+  }
+
+  public void mouseClicked(MouseEvent evt)
+  {}
+
+  public void mouseEntered(MouseEvent evt)
+  {}
+
+  public void mouseExited(MouseEvent evt)
+  {}
+
+  public void mouseReleased(MouseEvent evt)
+  {}
+
+  public void mousePressed(MouseEvent evt)
+  {
+    int x = evt.getX();
+    int y = evt.getY();
+
+    mx = x;
+    my = y;
+
+    omx = mx;
+    omy = my;
+
+    startx = x;
+    starty = y;
+
+    rectx1 = x;
+    recty1 = y;
+
+    rectx2 = -1;
+    recty2 = -1;
+
+    SequenceI found = findPoint(x, y);
+
+    if (found != null)
+    {
+      if (av.getSelectionGroup() != null)
+      {
+        av.getSelectionGroup().addOrRemove(found, true);
+        av.getSelectionGroup().setEndRes(av.alignment.getWidth()-1);
+        PaintRefresher.Refresh(this, av.alignment);
+      }
+      else
+      {
+        av.setSelectionGroup(new SequenceGroup());
+        av.getSelectionGroup().addOrRemove(found, true);
+        av.getSelectionGroup().setEndRes(av.alignment.getWidth()-1);
+
+      }
+    }
+    repaint();
+  }
+
+
+  public void mouseMoved(MouseEvent evt)
+  {
+     SequenceI found = findPoint(evt.getX(), evt.getY());
+     if(found==null)
+       tooltip = null;
+     else
+     {
+       tooltip = found.getName();
+       toolx = evt.getX();
+       tooly = evt.getY();
+     }
+     repaint();
+  }
+
+  public void mouseDragged(MouseEvent evt)
+  {
+    mx = evt.getX();
+    my = evt.getY();
+
+      rotmat.setIdentity();
+
+      rotmat.rotate( (float) (my - omy), 'x');
+      rotmat.rotate( (float) (mx - omx), 'y');
+
+      for (int i = 0; i < npoint; i++)
+      {
+        SequencePoint sp = (SequencePoint) points.elementAt(i);
+        sp.coord[0] -= centre[0];
+        sp.coord[1] -= centre[1];
+        sp.coord[2] -= centre[2];
+
+        //Now apply the rotation matrix
+        sp.coord = rotmat.vectorMultiply(sp.coord);
+
+        //Now translate back again
+        sp.coord[0] += centre[0];
+        sp.coord[1] += centre[1];
+        sp.coord[2] += centre[2];
+      }
+
+      for (int i = 0; i < 3; i++)
+      {
+        axes[i] = rotmat.vectorMultiply(axes[i]);
+      }
+      omx = mx;
+      omy = my;
+
+      paint(this.getGraphics());
+  }
+
+  public void rectSelect(int x1, int y1, int x2, int y2)
+  {
+    //boolean changedSel = false;
+    for (int i = 0; i < npoint; i++)
+    {
+      SequencePoint sp = (SequencePoint) points.elementAt(i);
+      int tmp1 = (int) ( (sp.coord[0] - centre[0]) * scale +
+                        (float) getSize().width / 2.0);
+      int tmp2 = (int) ( (sp.coord[1] - centre[1]) * scale +
+                        (float) getSize().height / 2.0);
+
+      if (tmp1 > x1 && tmp1 < x2 && tmp2 > y1 && tmp2 < y2)
+      {
+        if (av != null)
+        {
+          if (!av.getSelectionGroup().getSequences(false).contains(sp.sequence))
+          {
+            av.getSelectionGroup().addSequence(sp.sequence, true);
+          }
+        }
+      }
+    }
+  }
+
+  public SequenceI findPoint(int x, int y)
+  {
+
+    int halfwidth = getSize().width / 2;
+    int halfheight = getSize().height / 2;
+
+    int found = -1;
+
+    for (int i = 0; i < npoint; i++)
+    {
+
+      SequencePoint sp = (SequencePoint) points.elementAt(i);
+      int px = (int) ( (float) (sp.coord[0] - centre[0]) * scale) + halfwidth;
+      int py = (int) ( (float) (sp.coord[1] - centre[1]) * scale) + halfheight;
+
+      if (Math.abs(px - x) < 3 && Math.abs(py - y) < 3)
+      {
+        found = i;
+      }
+    }
+    if (found != -1)
+    {
+      return ( (SequencePoint) points.elementAt(found)).sequence;
+    }
+    else
+    {
+      return null;
+    }
+  }
+
+}
index af226f3..54d533e 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class ScalePanel\r
-    extends Panel\r
-{\r
-\r
-  protected int offy = 4;\r
-  public int width;\r
-\r
-  protected AlignViewport av;\r
-  AlignmentPanel ap;\r
-\r
-  boolean stretchingGroup = false;\r
-\r
-  public ScalePanel(AlignViewport av, AlignmentPanel ap)\r
-  {\r
-    setLayout(null);\r
-    this.av = av;\r
-    this.ap = ap;\r
-\r
-    addMouseListener(new MouseAdapter()\r
-    {\r
-      public void mousePressed(MouseEvent evt)\r
-      {\r
-        doMousePressed(evt);\r
-      }\r
-\r
-      public void mouseReleased(MouseEvent evt)\r
-      {\r
-        doMouseReleased(evt);\r
-      }\r
-\r
-    });\r
-    addMouseMotionListener(new MouseMotionAdapter()\r
-    {\r
-      public void mouseDragged(MouseEvent evt)\r
-      {\r
-        doMouseDragged(evt);\r
-      }\r
-    });\r
-\r
-  }\r
-\r
-  public void doMousePressed(MouseEvent evt)\r
-  {\r
-    int x = evt.getX();\r
-    int res = x / av.getCharWidth() + av.getStartRes();\r
-    SequenceGroup sg = null;\r
-\r
-    if (av.getColumnSelection().contains(res))\r
-    {\r
-      av.getColumnSelection().removeElement(res);\r
-    }\r
-    else\r
-    {\r
-      av.getColumnSelection().addElement(res);\r
-\r
-      sg = new SequenceGroup();\r
-      for (int i = 0; i < av.alignment.getSequences().size(); i++)\r
-      {\r
-        sg.addSequence(av.alignment.getSequenceAt(i), false);\r
-      }\r
-\r
-      sg.setStartRes(res);\r
-      sg.setEndRes(res);\r
-\r
-      ap.annotationPanel.addEditableColumn(res);\r
-    }\r
-    av.setSelectionGroup(sg);\r
-    ap.repaint();\r
-  }\r
-\r
-  public void doMouseReleased(MouseEvent evt)\r
-  {\r
-    if (!stretchingGroup)\r
-    {\r
-      return;\r
-    }\r
-\r
-    int x = evt.getX();\r
-    int res = x / av.getCharWidth() + av.getStartRes();\r
-\r
-    if (!av.getColumnSelection().contains(res))\r
-    {\r
-      av.getColumnSelection().addElement(res);\r
-    }\r
-\r
-    SequenceGroup sg = av.getSelectionGroup();\r
-\r
-    if (res > sg.getStartRes())\r
-    {\r
-      sg.setEndRes(res);\r
-    }\r
-    else if (res < sg.getStartRes())\r
-    {\r
-      sg.setStartRes(res);\r
-    }\r
-\r
-    stretchingGroup = false;\r
-    ap.repaint();\r
-  }\r
-\r
-  public void doMouseDragged(MouseEvent evt)\r
-  {\r
-    int x = evt.getX();\r
-    int res = x / av.getCharWidth() + av.getStartRes();\r
-\r
-    SequenceGroup sg = av.getSelectionGroup();\r
-    if (sg != null)\r
-    {\r
-      stretchingGroup = true;\r
-      if (res > sg.getStartRes())\r
-      {\r
-        sg.setEndRes(res);\r
-      }\r
-      else if (res < sg.getStartRes())\r
-      {\r
-        sg.setStartRes(res);\r
-      }\r
-\r
-      ap.annotationPanel.addEditableColumn(res);\r
-      ap.repaint();\r
-    }\r
-  }\r
-\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-    drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,\r
-              getSize().height);\r
-  }\r
-\r
-// scalewidth will normally be screenwidth,\r
-  public void drawScale(Graphics gg, int startx, int endx, int width,\r
-                        int height)\r
-  {\r
-    gg.setFont(av.getFont());\r
-\r
-    //Fill in the background\r
-    gg.setColor(Color.white);\r
-    gg.fillRect(0, 0, width, height);\r
-    gg.setColor(Color.black);\r
-\r
-    //Fill the selected columns\r
-    ColumnSelection cs = av.getColumnSelection();\r
-    gg.setColor(new Color(220, 0, 0));\r
-    for (int i = 0; i < cs.size(); i++)\r
-    {\r
-      int sel = cs.columnAt(i);\r
-      if (sel >= startx && sel <= endx)\r
-      {\r
-        gg.fillRect( (sel - startx) * av.charWidth, 0, av.charWidth,\r
-                    getSize().height);\r
-      }\r
-    }\r
-\r
-    // Draw the scale numbers\r
-    gg.setColor(Color.black);\r
-    int scalestartx = (startx / 10) * 10;\r
-\r
-    FontMetrics fm = gg.getFontMetrics(av.getFont());\r
-    int y = av.charHeight - fm.getDescent();\r
-\r
-    if (scalestartx % 10 == 0)\r
-    {\r
-      scalestartx += 5;\r
-    }\r
-\r
-    for (int i = scalestartx; i < endx; i += 5)\r
-    {\r
-      if (i % 10 == 0)\r
-      {\r
-        gg.drawString(String.valueOf(i), (i - startx - 1) * av.charWidth, y);\r
-        gg.drawLine( (int) ( (i - startx - 1) * av.charWidth + av.charWidth / 2),\r
-                    y + 2,\r
-                    (int) ( (i - startx - 1) * av.charWidth + av.charWidth / 2),\r
-                    y + fm.getDescent() * 2);\r
-      }\r
-      else\r
-      {\r
-        gg.drawLine( (int) ( (i - startx - 1) * av.charWidth + av.charWidth / 2),\r
-                    y + fm.getDescent(),\r
-                    (int) ( (i - startx - 1) * av.charWidth + av.charWidth / 2),\r
-                    y + fm.getDescent() * 2);\r
-      }\r
-\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+
+public class ScalePanel
+    extends Panel implements MouseMotionListener, MouseListener
+{
+
+  protected int offy = 4;
+  public int width;
+
+  protected AlignViewport av;
+  AlignmentPanel ap;
+
+  boolean stretchingGroup = false;
+  int min; //used by mouseDragged to see if user
+  int max; //used by mouseDragged to see if user
+  boolean mouseDragging = false;
+  int [] reveal;
+
+  public ScalePanel(AlignViewport av, AlignmentPanel ap)
+  {
+    setLayout(null);
+    this.av = av;
+    this.ap = ap;
+
+    addMouseListener(this);
+    addMouseMotionListener(this);
+
+  }
+
+  public void mousePressed(MouseEvent evt)
+  {
+    int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+    final int res;
+
+    if (av.hasHiddenColumns)
+      res = av.getColumnSelection().adjustForHiddenColumns(x);
+    else
+      res = x;
+
+    min = res;
+    max = res;
+    if ((evt.getModifiers() & InputEvent.BUTTON3_MASK)
+        == InputEvent.BUTTON3_MASK)
+    {
+      PopupMenu pop = new PopupMenu();
+      if (reveal != null)
+      {
+        MenuItem item = new MenuItem("Reveal");
+        item.addActionListener(new ActionListener()
+        {
+          public void actionPerformed(ActionEvent e)
+          {
+            av.showColumn(reveal[0]);
+            reveal = null;
+            ap.repaint();
+            if (ap.overviewPanel != null)
+              ap.overviewPanel.updateOverviewImage();
+          }
+        });
+        pop.add(item);
+
+        if (av.getColumnSelection().getHiddenColumns().size() > 1)
+        {
+          item = new MenuItem("Reveal All");
+          item.addActionListener(new ActionListener()
+          {
+            public void actionPerformed(ActionEvent e)
+            {
+              av.showAllHiddenColumns();
+              reveal = null;
+              ap.repaint();
+              if (ap.overviewPanel != null)
+                ap.overviewPanel.updateOverviewImage();
+            }
+          });
+          pop.add(item);
+        }
+        this.add(pop);
+        pop.show(this, evt.getX(), evt.getY());
+      }
+      else if (av.getColumnSelection().contains(res))
+      {
+        MenuItem item = new MenuItem("Hide Columns");
+        item.addActionListener(new ActionListener()
+        {
+          public void actionPerformed(ActionEvent e)
+          {
+            av.hideColumns(res, res);
+            if (av.getSelectionGroup() != null
+                &&
+                av.getSelectionGroup().getSize(false) == av.alignment.getHeight())
+              av.setSelectionGroup(null);
+
+            ap.repaint();
+            if (ap.overviewPanel != null)
+              ap.overviewPanel.updateOverviewImage();
+          }
+        });
+        pop.add(item);
+        this.add(pop);
+        pop.show(this, evt.getX(), evt.getY());
+      }
+    }
+    else // LEFT MOUSE TO SELECT
+    {
+      if (!evt.isControlDown() && !evt.isShiftDown())
+      {
+        av.getColumnSelection().clear();
+      }
+
+      av.getColumnSelection().addElement(res);
+      SequenceGroup sg = new SequenceGroup();
+      for (int i = 0; i < av.alignment.getSequences().size(); i++)
+      {
+        sg.addSequence(av.alignment.getSequenceAt(i), false);
+      }
+
+      sg.setStartRes(res);
+      sg.setEndRes(res);
+      av.setSelectionGroup(sg);
+
+      if(evt.isShiftDown())
+      {
+        int min = Math.min(av.getColumnSelection().getMin(), res);
+        int max = Math.max(av.getColumnSelection().getMax(), res);
+        for (int i = min; i<max; i++)
+        {
+            av.getColumnSelection().addElement(i);
+        }
+        sg.setStartRes(min);
+        sg.setEndRes(max);
+      }
+    }
+
+    ap.repaint();
+  }
+
+  public void mouseReleased(MouseEvent evt)
+  {
+    mouseDragging = false;
+
+    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+    if(res> av.alignment.getWidth())
+    {
+      res = av.alignment.getWidth()-1;
+    }
+
+    if(av.hasHiddenColumns)
+      res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+    if (!stretchingGroup)
+    {
+        ap.repaint();
+
+        return;
+    }
+
+    SequenceGroup sg = av.getSelectionGroup();
+
+    if (res > sg.getStartRes())
+    {
+        sg.setEndRes(res);
+    }
+    else if (res < sg.getStartRes())
+    {
+        sg.setStartRes(res);
+    }
+
+    stretchingGroup = false;
+    ap.repaint();
+  }
+
+  public void mouseDragged(MouseEvent evt)
+  {
+    mouseDragging = true;
+
+    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+    if (res < 0)
+      res = 0;
+
+    if (av.hasHiddenColumns)
+      res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+    if (res > av.alignment.getWidth())
+    {
+      res = av.alignment.getWidth() - 1;
+    }
+
+    if (res < min)
+    {
+      min = res;
+    }
+
+    if (res > max)
+    {
+      max = res;
+    }
+
+    SequenceGroup sg = av.getSelectionGroup();
+
+    if (sg != null)
+    {
+      stretchingGroup = true;
+
+      if (!av.getColumnSelection().contains(res))
+      {
+        av.getColumnSelection().addElement(res);
+      }
+
+      if (res > sg.getStartRes())
+      {
+        sg.setEndRes(res);
+      }
+      if (res < sg.getStartRes())
+      {
+        sg.setStartRes(res);
+      }
+
+      for (int i = min; i <= max; i++)
+      {
+        if ( (i < sg.getStartRes()) || (i > sg.getEndRes()))
+        {
+          av.getColumnSelection().removeElement(i);
+        }
+        else
+        {
+          av.getColumnSelection().addElement(i);
+        }
+      }
+
+      ap.repaint();
+    }
+  }
+
+
+  public void mouseEntered(MouseEvent evt)
+  {
+    if (mouseDragging)
+      ap.seqPanel.scrollCanvas(null);
+  }
+
+  public void mouseExited(MouseEvent evt)
+  {
+    if (mouseDragging)
+      ap.seqPanel.scrollCanvas(evt);
+  }
+
+  public void mouseClicked(MouseEvent evt)
+  {
+
+  }
+
+  public void mouseMoved(MouseEvent evt)
+  {
+    if (!av.hasHiddenColumns)
+      return;
+
+    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+    res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+    reveal = null;
+    for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
+    {
+      int[] region = (int[]) av.getColumnSelection().getHiddenColumns().
+          elementAt(i);
+      if (res + 1 == region[0] || res - 1 == region[1])
+      {
+        reveal = region;
+        break;
+      }
+    }
+
+    repaint();
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  public void paint(Graphics g)
+  {
+    drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,
+              getSize().height);
+  }
+
+// scalewidth will normally be screenwidth,
+  public void drawScale(Graphics gg, int startx, int endx, int width,
+                        int height)
+  {
+    gg.setFont(av.getFont());
+
+
+    //Fill in the background
+    gg.setColor(Color.white);
+    gg.fillRect(0, 0, width, height);
+    gg.setColor(Color.black);
+
+    //Fill the selected columns
+    ColumnSelection cs = av.getColumnSelection();
+    gg.setColor(new Color(220, 0, 0));
+
+    for (int i = 0; i < cs.size(); i++)
+    {
+        int sel = cs.columnAt(i);
+        if(av.hasHiddenColumns)
+          sel = av.getColumnSelection().findColumnPosition(sel);
+
+
+        if ((sel >= startx) && (sel <= endx))
+        {
+            gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth,
+                getSize().height);
+        }
+    }
+
+    // Draw the scale numbers
+    gg.setColor(Color.black);
+
+    int scalestartx = (startx / 10) * 10;
+
+    FontMetrics fm = gg.getFontMetrics(av.getFont());
+    int y = av.charHeight - fm.getDescent();
+
+    if ((scalestartx % 10) == 0)
+    {
+        scalestartx += 5;
+    }
+
+    String string;
+    int maxX=0;
+
+    for (int i = scalestartx; i < endx; i += 5)
+    {
+        if ((i % 10) == 0)
+        {
+            string = String.valueOf(av.getColumnSelection().adjustForHiddenColumns(i));
+            if ( (i - startx - 1) * av.charWidth > maxX)
+            {
+              gg.drawString(string,
+                            (i - startx - 1) * av.charWidth, y);
+              maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string);
+            }
+
+            gg.drawLine( (int) ( ( (i - startx - 1) * av.charWidth) +
+                                (av.charWidth / 2)), y + 2,
+                        (int) ( ( (i - startx - 1) * av.charWidth) +
+                               (av.charWidth / 2)),
+                        y + (fm.getDescent() * 2));
+
+        }
+        else
+        {
+            gg.drawLine((int) (((i - startx - 1) * av.charWidth) +
+                (av.charWidth / 2)), y + fm.getDescent(),
+                (int) (((i - startx - 1) * av.charWidth) +
+                (av.charWidth / 2)), y + (fm.getDescent() * 2));
+        }
+    }
+
+    if (av.hasHiddenColumns)
+    {
+      gg.setColor(Color.blue);
+      int res;
+      if(av.getShowHiddenMarkers())
+      {
+        for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size();
+             i++)
+        {
+
+          res = av.getColumnSelection().findHiddenRegionPosition(i) -
+              startx;
+
+          if(res < 0 || res > endx-scalestartx)
+            continue;
+
+          gg.fillPolygon(new int[]
+                         {res * av.charWidth - av.charHeight / 4,
+                         res * av.charWidth + av.charHeight / 4,
+                         res * av.charWidth},
+                         new int[]
+                         {
+                         y - av.charHeight / 2, y - av.charHeight / 2,
+                         y + 8
+          }, 3);
+
+        }
+      }
+
+      if (reveal != null && reveal[0] > startx && reveal[0] < endx)
+      {
+        gg.drawString("Reveal Columns", reveal[0] * av.charWidth, 0);
+      }
+    }
+
+  }
+
+}
index 465dd38..0cd2ae2 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class SeqCanvas\r
-    extends Panel\r
-{\r
-  FeatureRenderer fr;\r
-  SequenceRenderer sr;\r
-  Image img;\r
-  Graphics gg;\r
-  int imgWidth;\r
-  int imgHeight;\r
-\r
-  AlignViewport av;\r
-\r
-  SearchResults searchResults = null;\r
-\r
-  int chunkHeight;\r
-  int chunkWidth;\r
-\r
-  boolean fastPaint = false;\r
-\r
-\r
-  public SeqCanvas(AlignViewport av)\r
-  {\r
-    this.av = av;\r
-    fr = new FeatureRenderer(av);\r
-    sr = new SequenceRenderer(av);\r
-    PaintRefresher.Register(this, av.alignment);\r
-  }\r
-\r
-  public AlignViewport getViewport()\r
-  {\r
-    return av;\r
-  }\r
-\r
-  public FeatureRenderer getFeatureRenderer()\r
-  {\r
-    return fr;\r
-  }\r
-\r
-  MCview.AppletPDBCanvas pdbCanvas;\r
-  public SequenceRenderer getSequenceRenderer()\r
-  {\r
-    return sr;\r
-  }\r
-\r
-  public void setPDBCanvas(MCview.AppletPDBCanvas pc)\r
-  {\r
-    pdbCanvas = pc;\r
-  }\r
-\r
-\r
-  void drawNorthScale(Graphics g, int startx, int endx, int ypos)\r
-  {\r
-    int scalestartx = startx - startx % 10 + 10;\r
-\r
-    g.setColor(Color.black);\r
-\r
-    // NORTH SCALE\r
-    for (int i = scalestartx; i < endx; i += 10)\r
-    {\r
-      String string = String.valueOf(i);\r
-      g.drawString(string, (i - startx - 1) * av.charWidth,\r
-                   ypos - av.charHeight / 2);\r
-\r
-      g.drawLine( (i - startx - 1) * av.charWidth + av.charWidth / 2,\r
-                 ypos + 2 - av.charHeight / 2,\r
-                 (i - startx - 1) * av.charWidth + av.charWidth / 2, ypos - 2);\r
-\r
-    }\r
-  }\r
-\r
-  void drawWestScale(Graphics g, int startx, int endx, int ypos)\r
-  {\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-    ypos += av.charHeight;\r
-    // EAST SCALE\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
-    {\r
-      SequenceI seq = av.alignment.getSequenceAt(i);\r
-      int index = startx;\r
-      int value = -1;\r
-      while (index < endx)\r
-      {\r
-        if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
-        {\r
-          index++;\r
-          continue;\r
-        }\r
-\r
-        value = av.alignment.getSequenceAt(i).findPosition(index);\r
-        break;\r
-      }\r
-      if (value != -1)\r
-      {\r
-        int x = LABEL_WEST - fm.stringWidth(String.valueOf(value))-av.charWidth/2;\r
-        g.drawString(value + "", x,\r
-                     ypos + i * av.charHeight - av.charHeight / 5);\r
-      }\r
-    }\r
-  }\r
-\r
-  void drawEastScale(Graphics g, int startx, int endx, int ypos)\r
-  {\r
-    ypos += av.charHeight;\r
-    // EAST SCALE\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
-    {\r
-      SequenceI seq = av.alignment.getSequenceAt(i);\r
-      int index = endx;\r
-      int value = -1;\r
-      while (index > startx)\r
-      {\r
-        if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
-        {\r
-          index--;\r
-          continue;\r
-        }\r
-\r
-        value = av.alignment.getSequenceAt(i).findPosition(index);\r
-        break;\r
-      }\r
-      if (value != -1)\r
-      {\r
-        g.drawString(value + "", av.charWidth/2,\r
-                     ypos + i * av.charHeight - av.charHeight / 5);\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  int lastsr=0;\r
-  void fastPaint(int horizontal, int vertical)\r
-  {\r
-    if ( fastPaint || gg == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-\r
-    // Its possible on certain browsers that the call to fastpaint\r
-    // is faster than it can paint, so this check here catches\r
-    // this possibility\r
-    if(lastsr + horizontal != av.startRes)\r
-    {\r
-      horizontal = av.startRes - lastsr;\r
-    }\r
-\r
-    lastsr = av.startRes;\r
-\r
-    fastPaint = true;\r
-    gg.copyArea(horizontal * av.charWidth,\r
-                vertical * av.charHeight,\r
-                imgWidth - horizontal * av.charWidth,\r
-                imgHeight - vertical * av.charHeight,\r
-                -horizontal * av.charWidth,\r
-                -vertical * av.charHeight);\r
-\r
-\r
-\r
-    int sr = av.startRes, er = av.endRes, ss = av.startSeq, es = av.endSeq,\r
-        transX = 0, transY = 0;\r
-\r
-    if (horizontal > 0) // scrollbar pulled right, image to the left\r
-    {\r
-      transX = (er - sr - horizontal) * av.charWidth;\r
-      sr = er - horizontal;\r
-    }\r
-    else if (horizontal < 0)\r
-    {\r
-      er = sr - horizontal;\r
-    }\r
-\r
-    else if (vertical > 0) // scroll down\r
-    {\r
-      ss = es - vertical;\r
-      if (ss < av.startSeq) // ie scrolling too fast, more than a page at a time\r
-      {\r
-        ss = av.startSeq;\r
-      }\r
-      else\r
-      {\r
-        transY = imgHeight - vertical * av.charHeight;\r
-      }\r
-    }\r
-    else if (vertical < 0)\r
-    {\r
-      es = ss - vertical;\r
-      if (es > av.endSeq)\r
-      {\r
-        es = av.endSeq;\r
-      }\r
-    }\r
-\r
-    gg.translate(transX, transY);\r
-\r
-    drawPanel(gg, sr, er, ss, es, 0);\r
-    gg.translate( -transX, -transY);\r
-\r
-    repaint();\r
-\r
-  }\r
-\r
-  /**\r
-   * Definitions of startx and endx (hopefully):\r
-   * SMJS This is what I'm working towards!\r
-   *   startx is the first residue (starting at 0) to display.\r
-   *   endx   is the last residue to display (starting at 0).\r
-   *   starty is the first sequence to display (starting at 0).\r
-   *   endy   is the last sequence to display (starting at 0).\r
-   * NOTE 1: The av limits are set in setFont in this class and\r
-   * in the adjustment listener in SeqPanel when the scrollbars move.\r
-   */\r
-  public void update(Graphics g)\r
-  {\r
-    paint(g);\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-\r
-    if (fastPaint)\r
-    {\r
-      g.drawImage(img, 0, 0, this);\r
-      fastPaint = false;\r
-      return;\r
-    }\r
-\r
-    // this draws the whole of the alignment\r
-    imgWidth = this.getSize().width;\r
-    imgHeight = this.getSize().height;\r
-\r
-    imgWidth -= imgWidth % av.charWidth;\r
-    imgHeight -= imgHeight % av.charHeight;\r
-\r
-    if (imgWidth < 1 || imgHeight < 1)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (img == null || imgWidth != img.getWidth(this) ||\r
-        imgHeight != img.getHeight(this))\r
-    {\r
-      img = createImage(imgWidth, imgHeight);\r
-      gg = img.getGraphics();\r
-      gg.setFont(av.getFont());\r
-    }\r
-\r
-    gg.setColor(Color.white);\r
-    gg.fillRect(0, 0, imgWidth, imgHeight);\r
-\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      drawWrappedPanel(gg, imgWidth, imgHeight, av.startRes);\r
-    }\r
-    else\r
-    {\r
-      drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq, 0);\r
-    }\r
-\r
-    g.drawImage(img, 0, 0, this);\r
-\r
-    if (pdbCanvas != null)\r
-    {\r
-      pdbCanvas.updateSeqColours();\r
-    }\r
-  }\r
-\r
-  int LABEL_WEST, LABEL_EAST;\r
-  public int getWrappedCanvasWidth(int cwidth)\r
-  {\r
-      FontMetrics fm = getFontMetrics(av.getFont());\r
-\r
-      LABEL_EAST = 0;\r
-      LABEL_WEST = 0;\r
-\r
-      if (av.scaleRightWrapped)\r
-      {\r
-          LABEL_EAST = fm.stringWidth(getMask());\r
-      }\r
-\r
-      if (av.scaleLeftWrapped)\r
-      {\r
-          LABEL_WEST = fm.stringWidth(getMask());\r
-      }\r
-\r
-      return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
-  }\r
-\r
-\r
-  /**\r
-   * Generates a string of zeroes.\r
-   * @return String\r
-   */\r
-  String getMask()\r
-  {\r
-    String mask = "00";\r
-    for (int i = av.alignment.getWidth(); i > 0; i /= 10)\r
-    {\r
-      mask += "0";\r
-    }\r
-    return mask;\r
-    }\r
-\r
-  public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,\r
-                               int startRes)\r
-  {\r
-    AlignmentI al = av.getAlignment();\r
-\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-\r
-    int LABEL_EAST = 0;\r
-\r
-    if (av.scaleRightWrapped)\r
-    {\r
-        LABEL_EAST = fm.stringWidth(getMask());\r
-    }\r
-\r
-    int LABEL_WEST = 0;\r
-\r
-    if (av.scaleLeftWrapped)\r
-    {\r
-        LABEL_WEST = fm.stringWidth(getMask());\r
-    }\r
-\r
-    int hgap = av.charHeight;\r
-    if(av.scaleAboveWrapped)\r
-      hgap += av.charHeight;\r
-\r
-    int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
-    int cHeight = av.getAlignment().getHeight() * av.charHeight;\r
-\r
-    av.setWrappedWidth(cWidth);\r
-\r
-    av.endRes = av.startRes + cWidth;\r
-\r
-\r
-    int endx;\r
-    int ypos = hgap;\r
-\r
-\r
-    while ((ypos <= canvasHeight) && (startRes < av.alignment.getWidth()))\r
-    {\r
-      endx = startRes + cWidth;\r
-\r
-      if (endx > al.getWidth())\r
-      {\r
-        endx = al.getWidth();\r
-      }\r
-\r
-        g.setColor(Color.black);\r
-\r
-        if (av.scaleLeftWrapped)\r
-        {\r
-            drawWestScale(g, startRes, endx, ypos);\r
-        }\r
-\r
-        if (av.scaleRightWrapped)\r
-        {\r
-            g.translate(canvasWidth - LABEL_EAST, 0);\r
-            drawEastScale(g, startRes, endx, ypos);\r
-            g.translate(-(canvasWidth - LABEL_EAST), 0);\r
-        }\r
-\r
-        g.translate(LABEL_WEST, 0);\r
-\r
-        if (av.scaleAboveWrapped)\r
-        {\r
-            drawNorthScale(g, startRes, endx, ypos);\r
-        }\r
-\r
-        if(g.getClip()==null)\r
-          g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);\r
-\r
-        drawPanel(g, startRes, endx, 0, al.getHeight(), ypos);\r
-         g.setClip(null);\r
-\r
-\r
-        if(av.showAnnotation)\r
-        {\r
-          g.translate(0, cHeight + ypos+4);\r
-          if(annotations==null)\r
-            annotations = new AnnotationPanel(av);\r
-\r
-          annotations.drawComponent( g, startRes, endx );\r
-          g.translate(0, -cHeight - ypos-4);\r
-        }\r
-        g.translate(-LABEL_WEST, 0);\r
-\r
-        ypos += cHeight+getAnnotationHeight()+hgap;\r
-\r
-\r
-        startRes += cWidth;\r
-        }\r
-\r
-  }\r
-\r
-  AnnotationPanel annotations;\r
-  int getAnnotationHeight()\r
-  {\r
-    if(!av.showAnnotation)\r
-      return 0;\r
-\r
-    if(annotations==null)\r
-      annotations = new AnnotationPanel(av);\r
-\r
-    return annotations.adjustPanelHeight();\r
-    }\r
-\r
-  void drawPanel(Graphics g, int startRes, int endRes, int startSeq, int endSeq, int offset)\r
-  {\r
-\r
-    g.setFont(av.getFont());\r
-    sr.renderGaps(av.renderGaps);\r
-\r
-    SequenceI nextSeq;\r
-    /// First draw the sequences\r
-  /////////////////////////////\r
-  for (int i = startSeq; i < endSeq; i++)\r
-  {\r
-    nextSeq = av.alignment.getSequenceAt(i);\r
-\r
-    sr.drawSequence(g, nextSeq, av.alignment.findAllGroups(nextSeq), startRes, endRes,\r
-                    offset + ( (i - startSeq) * av.charHeight));\r
-\r
-    if (av.showSequenceFeatures)\r
-    {\r
-      fr.drawSequence(g, nextSeq, startRes, endRes,\r
-                      offset + ((i - startSeq) * av.charHeight),\r
-                      av.charWidth, av.charHeight);\r
-    }\r
-    /// Highlight search Results once all sequences have been drawn\r
-   //////////////////////////////////////////////////////////\r
-   if (searchResults != null)\r
-   {\r
-     int[] visibleResults = searchResults.getResults(nextSeq, startRes, endRes);\r
-     if (visibleResults != null)\r
-       for (int r = 0; r < visibleResults.length; r += 2)\r
-       {\r
-         sr.drawHighlightedText(nextSeq, visibleResults[r],\r
-                                visibleResults[r + 1],\r
-                                (visibleResults[r] - startRes) * av.charWidth,\r
-                                offset + ( (i - startSeq) * av.charHeight),\r
-                                av.charWidth, av.charHeight);\r
-       }\r
-   }\r
-  }\r
-\r
-  //\r
-  /////////////////////////////////////\r
-  // Now outline any areas if necessary\r
-  /////////////////////////////////////\r
-  SequenceGroup group = av.getSelectionGroup();\r
-\r
-  int sx = -1;\r
-  int sy = -1;\r
-  int ex = -1;\r
-  int groupIndex = -1;\r
-\r
-  if ((group == null) && (av.alignment.getGroups().size() > 0))\r
-  {\r
-      group = (SequenceGroup) av.alignment.getGroups().elementAt(0);\r
-      groupIndex = 0;\r
-  }\r
-\r
-  if ( group != null)\r
-  {\r
-      do\r
-      {\r
-          int oldY = -1;\r
-          int i = 0;\r
-          boolean inGroup = false;\r
-          int top = -1;\r
-          int bottom = -1;\r
-\r
-          for (i = startSeq; i < endSeq; i++)\r
-          {\r
-              sx = (group.getStartRes() - startRes) * av.charWidth;\r
-              sy = offset + ((i - startSeq) * av.charHeight);\r
-              ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) -\r
-                  1;\r
-\r
-              if(sx+ex<0 || sx>imgWidth)\r
-              {\r
-                continue;\r
-              }\r
-\r
-              if ( (sx <= (endRes-startRes)*av.charWidth) &&\r
-                      group.sequences.contains(av.alignment.getSequenceAt(\r
-                              i)))\r
-              {\r
-                if (bottom == -1)\r
-                {\r
-                 if(i == endSeq-1 || // Dont check for i+1 if on the bottom row\r
-                  !group.sequences.contains(av.alignment.getSequenceAt(i+1 )))\r
-\r
-                    bottom = sy + av.charHeight;\r
-                }\r
-\r
-                  if (!inGroup)\r
-                  {\r
-                      if (((top == -1) && (i == 0)) ||\r
-                              !group.sequences.contains(\r
-                                  av.alignment.getSequenceAt(i - 1)))\r
-                      {\r
-                          top = sy;\r
-                      }\r
-\r
-                      oldY = sy;\r
-                      inGroup = true;\r
-\r
-                      if (group == av.getSelectionGroup())\r
-                      {\r
-                          g.setColor(Color.red);\r
-                      }\r
-                      else\r
-                      {\r
-                          g.setColor(group.getOutlineColour());\r
-                      }\r
-                  }\r
-              }\r
-              else\r
-              {\r
-                if (inGroup)\r
-                {\r
-                  if (sx >= 0 && sx < imgWidth)\r
-                    g.drawLine(sx, oldY, sx, sy);\r
-\r
-                  if (sx + ex < imgWidth)\r
-                    g.drawLine(sx + ex, oldY, sx + ex, sy);\r
-\r
-                  if (sx < 0)\r
-                  {\r
-                    ex += sx;\r
-                    sx = 0;\r
-                  }\r
-\r
-                  if (sx + ex > imgWidth)\r
-                    ex = imgWidth;\r
-\r
-                  else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)\r
-                    ex = (endRes - startRes + 1) * av.charWidth;\r
-\r
-                  if (top != -1)\r
-                  {\r
-                    g.drawLine(sx, top, sx + ex, top);\r
-                    top = -1;\r
-                  }\r
-\r
-                  if (bottom != -1)\r
-                  {\r
-                    g.drawLine(sx, bottom, sx + ex, bottom);\r
-                    bottom = -1;\r
-                  }\r
-\r
-                  inGroup = false;\r
-                  }\r
-              }\r
-          }\r
-\r
-          if (inGroup)\r
-          {\r
-            sy = offset + ( (i - startSeq) * av.charHeight);\r
-            if (sx >= 0 && sx < imgWidth)\r
-              g.drawLine(sx, oldY, sx, sy);\r
-\r
-            if (sx + ex < imgWidth)\r
-              g.drawLine(sx + ex, oldY, sx + ex, sy);\r
-\r
-            if (sx < 0)\r
-            {\r
-              ex += sx;\r
-              sx = 0;\r
-            }\r
-\r
-            if (sx + ex > imgWidth)\r
-              ex = imgWidth;\r
-            else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)\r
-              ex = (endRes - startRes + 1) * av.charWidth;\r
-\r
-            if (top != -1)\r
-            {\r
-              g.drawLine(sx, top, sx + ex, top);\r
-              top = -1;\r
-            }\r
-\r
-            if (bottom != -1)\r
-            {\r
-              g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);\r
-              bottom = -1;\r
-            }\r
-\r
-              inGroup = false;\r
-          }\r
-\r
-          groupIndex++;\r
-\r
-          if (groupIndex >= av.alignment.getGroups().size())\r
-          {\r
-              break;\r
-          }\r
-\r
-          group = (SequenceGroup) av.alignment.getGroups().elementAt(groupIndex);\r
-      }\r
-      while (groupIndex < av.alignment.getGroups().size());\r
-    }\r
-  }\r
-\r
-  public void highlightSearchResults(SearchResults results)\r
-  {\r
-    searchResults = results;\r
-\r
-    repaint();\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+
+public class SeqCanvas
+    extends Panel
+{
+  FeatureRenderer fr;
+  SequenceRenderer sr;
+  Image img;
+  Graphics gg;
+  int imgWidth;
+  int imgHeight;
+
+  AlignViewport av;
+
+  SearchResults searchResults = null;
+
+  boolean fastPaint = false;
+
+
+  int cursorX = 0;
+  int cursorY = 0;
+
+
+  public SeqCanvas(AlignViewport av)
+  {
+    this.av = av;
+    fr = new FeatureRenderer(av);
+    sr = new SequenceRenderer(av);
+    PaintRefresher.Register(this, av.alignment);
+  }
+
+  public AlignViewport getViewport()
+  {
+    return av;
+  }
+
+  public FeatureRenderer getFeatureRenderer()
+  {
+    return fr;
+  }
+
+  MCview.AppletPDBCanvas pdbCanvas;
+  public SequenceRenderer getSequenceRenderer()
+  {
+    return sr;
+  }
+
+  public void setPDBCanvas(MCview.AppletPDBCanvas pc)
+  {
+    pdbCanvas = pc;
+  }
+
+
+  void drawNorthScale(Graphics g, int startx, int endx, int ypos)
+  {
+    int scalestartx = startx - startx % 10 + 10;
+
+    g.setColor(Color.black);
+
+    // NORTH SCALE
+    for (int i = scalestartx; i < endx; i += 10)
+    {
+      int value = i;
+      if(av.hasHiddenColumns)
+          value = av.getColumnSelection().adjustForHiddenColumns(value);
+
+      g.drawString( String.valueOf(value), (i - startx - 1) * av.charWidth,
+          ypos - (av.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), ypos -
+                2);
+    }
+  }
+
+  void drawWestScale(Graphics g, int startx, int endx, int ypos)
+  {
+    FontMetrics fm = getFontMetrics(av.getFont());
+    ypos += av.charHeight;
+    if (av.hasHiddenColumns)
+    {
+      startx = av.getColumnSelection().adjustForHiddenColumns(startx);
+      endx = av.getColumnSelection().adjustForHiddenColumns(endx);
+    }
+
+    int maxwidth = av.alignment.getWidth();
+    if (av.hasHiddenColumns)
+        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+      // WEST SCALE
+      for (int i = 0; i < av.alignment.getHeight(); i++)
+      {
+        SequenceI seq = av.alignment.getSequenceAt(i);
+        int index = startx;
+        int value = -1;
+
+        while (index < endx)
+        {
+          if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+          {
+            index++;
+
+            continue;
+          }
+
+          value = av.alignment.getSequenceAt(i).findPosition(index);
+
+          break;
+        }
+
+        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));
+        }
+      }
+    }
+  void drawEastScale(Graphics g, int startx, int endx, int ypos)
+  {
+        ypos += av.charHeight;
+
+        if(av.hasHiddenColumns)
+                endx = av.getColumnSelection().adjustForHiddenColumns(endx);
+
+        SequenceI seq;
+        // EAST SCALE
+        for (int i = 0; i < av.alignment.getHeight(); i++)
+        {
+            seq = av.alignment.getSequenceAt(i);
+            int index = endx;
+            int value = -1;
+
+            while (index > startx)
+            {
+                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+                {
+                    index--;
+
+                    continue;
+                }
+
+                value = seq.findPosition(index);
+
+                break;
+            }
+
+            if (value != -1)
+            {
+                g.drawString(String.valueOf(value), 0,
+                    (ypos + (i * av.charHeight)) - (av.charHeight / 5));
+            }
+        }
+    }
+
+  int lastsr=0;
+  void fastPaint(int horizontal, int vertical)
+  {
+    if ( fastPaint || gg == null)
+    {
+      return;
+    }
+
+
+    // Its possible on certain browsers that the call to fastpaint
+    // is faster than it can paint, so this check here catches
+    // this possibility
+    if(lastsr + horizontal != av.startRes)
+    {
+      horizontal = av.startRes - lastsr;
+    }
+
+    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);
+
+
+
+    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;
+      sr = er - horizontal;
+    }
+    else if (horizontal < 0)
+    {
+      er = sr - horizontal;
+    }
+
+    else if (vertical > 0) // scroll down
+    {
+      ss = es - vertical;
+      if (ss < av.startSeq) // ie scrolling too fast, more than a page at a time
+      {
+        ss = av.startSeq;
+      }
+      else
+      {
+        transY = imgHeight - vertical * av.charHeight;
+      }
+    }
+    else if (vertical < 0)
+    {
+      es = ss - vertical;
+      if (es > av.endSeq)
+      {
+        es = av.endSeq;
+      }
+    }
+
+    gg.translate(transX, transY);
+
+    drawPanel(gg, sr, er, ss, es, 0);
+    gg.translate( -transX, -transY);
+
+    repaint();
+
+  }
+
+  /**
+   * Definitions of startx and endx (hopefully):
+   * SMJS This is what I'm working towards!
+   *   startx is the first residue (starting at 0) to display.
+   *   endx   is the last residue to display (starting at 0).
+   *   starty is the first sequence to display (starting at 0).
+   *   endy   is the last sequence to display (starting at 0).
+   * NOTE 1: The av limits are set in setFont in this class and
+   * in the adjustment listener in SeqPanel when the scrollbars move.
+   */
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  public void paint(Graphics g)
+  {
+
+    if (img != null && (fastPaint
+                        || (getSize().width != g.getClipBounds().width)
+                        || (getSize().height != g.getClipBounds().height)))
+    {
+      g.drawImage(img, 0, 0, this);
+      fastPaint = false;
+      return;
+    }
+
+    if (fastPaint)
+    {
+      g.drawImage(img, 0, 0, this);
+      fastPaint = false;
+      return;
+    }
+
+    // this draws the whole of the alignment
+    imgWidth = this.getSize().width;
+    imgHeight = this.getSize().height;
+
+    imgWidth -= imgWidth % av.charWidth;
+    imgHeight -= imgHeight % av.charHeight;
+
+    if (imgWidth < 1 || imgHeight < 1)
+    {
+      return;
+    }
+
+    if (img == null || imgWidth != img.getWidth(this) ||
+        imgHeight != img.getHeight(this))
+    {
+      img = createImage(imgWidth, imgHeight);
+      gg = img.getGraphics();
+      gg.setFont(av.getFont());
+    }
+
+    gg.setColor(Color.white);
+    gg.fillRect(0, 0, imgWidth, imgHeight);
+
+
+    if (av.getWrapAlignment())
+    {
+      drawWrappedPanel(gg, imgWidth, imgHeight, av.startRes);
+    }
+    else
+    {
+      drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq, 0);
+    }
+
+    g.drawImage(img, 0, 0, this);
+
+    if (pdbCanvas != null)
+    {
+      pdbCanvas.updateSeqColours();
+    }
+  }
+
+  int LABEL_WEST, LABEL_EAST;
+  public int getWrappedCanvasWidth(int cwidth)
+  {
+      cwidth -= cwidth % av.charWidth;
+
+      FontMetrics fm = getFontMetrics(av.getFont());
+
+      LABEL_EAST = 0;
+      LABEL_WEST = 0;
+
+      if (av.scaleRightWrapped)
+      {
+          LABEL_EAST = fm.stringWidth(getMask());
+      }
+
+      if (av.scaleLeftWrapped)
+      {
+          LABEL_WEST = fm.stringWidth(getMask());
+      }
+
+      return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;
+  }
+
+
+  /**
+   * Generates a string of zeroes.
+   * @return String
+   */
+  String getMask()
+  {
+    String mask = "00";
+    for (int i = av.alignment.getWidth(); i > 0; i /= 10)
+    {
+      mask += "0";
+    }
+    return mask;
+    }
+
+  public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,
+                               int startRes)
+  {
+    AlignmentI al = av.getAlignment();
+
+    FontMetrics fm = getFontMetrics(av.getFont());
+
+
+    if (av.scaleRightWrapped)
+    {
+        LABEL_EAST = fm.stringWidth(getMask());
+    }
+
+    if (av.scaleLeftWrapped)
+    {
+        LABEL_WEST = fm.stringWidth(getMask());
+    }
+
+    int hgap = av.charHeight;
+    if(av.scaleAboveWrapped)
+      hgap += av.charHeight;
+
+    int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;
+    int cHeight = av.getAlignment().getHeight() * av.charHeight;
+
+    av.setWrappedWidth(cWidth);
+
+    av.endRes = av.startRes + cWidth;
+
+
+    int endx;
+    int ypos = hgap;
+
+    int maxwidth = av.alignment.getWidth();
+
+    if(av.hasHiddenColumns)
+          maxwidth = av.getColumnSelection().findColumnPosition(maxwidth)-1;
+
+    while ((ypos <= canvasHeight) && (startRes < maxwidth))
+    {
+      endx = startRes + cWidth -1;
+
+      if (endx > maxwidth)
+      {
+        endx = maxwidth;
+      }
+
+        g.setColor(Color.black);
+
+        if (av.scaleLeftWrapped)
+        {
+            drawWestScale(g, startRes, endx, ypos);
+        }
+
+        if (av.scaleRightWrapped)
+        {
+            g.translate(canvasWidth - LABEL_EAST, 0);
+            drawEastScale(g, startRes, endx, ypos);
+            g.translate(-(canvasWidth - LABEL_EAST), 0);
+        }
+
+        g.translate(LABEL_WEST, 0);
+
+        if (av.scaleAboveWrapped)
+        {
+          drawNorthScale(g, startRes, endx, ypos);
+        }
+        if (av.hasHiddenColumns && av.showHiddenMarkers)
+        {
+          g.setColor(Color.blue);
+          int res;
+          for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size();
+               i++)
+          {
+            res = av.getColumnSelection().findHiddenRegionPosition(i) -
+                startRes;
+
+            if (res < 0 || res > endx - startRes)
+              continue;
+
+            gg.fillPolygon(new int[]
+                           {res * av.charWidth - av.charHeight / 4,
+                           res * av.charWidth + av.charHeight / 4,
+                           res * av.charWidth},
+                           new int[]
+                           {
+                           ypos - (av.charHeight / 2),
+                           ypos - (av.charHeight / 2),
+                           ypos - (av.charHeight / 2) + 8
+            }, 3);
+
+          }
+        }
+
+        if(g.getClip()==null)
+          g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);
+
+        drawPanel(g, startRes, endx, 0, al.getHeight(), ypos);
+         g.setClip(null);
+
+
+        if(av.showAnnotation)
+        {
+          g.translate(0, cHeight + ypos+4);
+          if(annotations==null)
+            annotations = new AnnotationPanel(av);
+
+          annotations.drawComponent( g, startRes, endx+1 );
+          g.translate(0, -cHeight - ypos-4);
+        }
+        g.translate(-LABEL_WEST, 0);
+
+        ypos += cHeight+getAnnotationHeight()+hgap;
+
+
+        startRes += cWidth;
+        }
+
+  }
+
+  AnnotationPanel annotations;
+  int getAnnotationHeight()
+  {
+    if(!av.showAnnotation)
+      return 0;
+
+    if(annotations==null)
+      annotations = new AnnotationPanel(av);
+
+    return annotations.adjustPanelHeight();
+    }
+
+    void drawPanel(Graphics g1, int startRes, int endRes,
+                    int startSeq, int endSeq, int offset)
+    {
+      if(!av.hasHiddenColumns)
+      {
+        draw(g1, startRes, endRes, startSeq, endSeq, offset);
+      }
+      else
+      {
+        java.util.Vector regions = av.getColumnSelection().getHiddenColumns();
+
+        int screenY = 0;
+        int blockStart = startRes;
+        int blockEnd = endRes;
+
+        for (int i = 0; i < regions.size(); i++)
+        {
+          int[] region = (int[]) regions.elementAt(i);
+          int hideStart = region[0];
+          int hideEnd = region[1];
+
+          if (hideStart <= blockStart)
+          {
+            blockStart += (hideEnd - hideStart) + 1;
+            continue;
+          }
+
+          blockEnd = hideStart - 1;
+
+          g1.translate(screenY * av.charWidth, 0);
+
+          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+
+          if(av.getShowHiddenMarkers())
+          {
+            g1.setColor(Color.blue);
+            g1.drawLine( (blockEnd - blockStart + 1) * av.charWidth - 1,
+                        startSeq + offset,
+                        (blockEnd - blockStart + 1) * av.charWidth - 1,
+                        startSeq + (endSeq - startSeq) * av.charHeight + offset);
+          }
+
+          g1.translate( -screenY * av.charWidth, 0);
+          screenY += blockEnd - blockStart + 1;
+          blockStart = hideEnd + 1;
+        }
+
+        if (screenY <= (endRes - startRes))
+        {
+          blockEnd = blockStart + (endRes - startRes) - screenY;
+          g1.translate(screenY * av.charWidth, 0);
+          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+
+          g1.translate( -screenY * av.charWidth, 0);
+        }
+      }
+
+    }
+
+
+
+
+    //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,
+                   int offset)
+   {
+      g.setFont(av.getFont());
+      sr.prepare(g, av.renderGaps);
+
+      SequenceI nextSeq;
+
+        /// First draw the sequences
+        /////////////////////////////
+        for (int i = startSeq; i < endSeq; i++)
+        {
+            nextSeq = av.alignment.getSequenceAt(i);
+
+            sr.drawSequence(nextSeq, av.alignment.findAllGroups(nextSeq),
+                            startRes, endRes,
+                            offset + ( (i - startSeq) * av.charHeight));
+
+            if (av.showSequenceFeatures)
+            {
+                fr.drawSequence(g, nextSeq, startRes, endRes,
+                    offset + ((i - startSeq) * av.charHeight));
+            }
+
+            /// Highlight search Results once all sequences have been drawn
+            //////////////////////////////////////////////////////////
+            if (searchResults != null)
+            {
+              int[] visibleResults = searchResults.getResults(nextSeq, startRes, endRes);
+              if (visibleResults != null)
+                for (int r = 0; r < visibleResults.length; r += 2)
+                {
+                  sr.drawHighlightedText(nextSeq, visibleResults[r],
+                                         visibleResults[r + 1],
+                                         (visibleResults[r] - startRes) * av.charWidth,
+                                         offset + ( (i - startSeq) * av.charHeight));
+                }
+            }
+
+            if(av.cursorMode && cursorY==i
+               && cursorX>=startRes && cursorX<=endRes)
+            {
+              sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * av.charWidth,
+                            offset + ( (i - startSeq) * av.charHeight));
+            }
+          }
+
+          if(av.getSelectionGroup()!=null || av.alignment.getGroups().size()>0)
+            drawGroupsBoundaries(g, startRes, endRes, startSeq, endSeq, offset);
+
+   }
+
+   void drawGroupsBoundaries(Graphics g,
+                   int startRes, int endRes,
+                   int startSeq, int endSeq,
+                   int offset)
+   {
+     //
+     /////////////////////////////////////
+     // Now outline any areas if necessary
+     /////////////////////////////////////
+     SequenceGroup group = av.getSelectionGroup();
+
+     int sx = -1;
+     int sy = -1;
+     int ex = -1;
+     int groupIndex = -1;
+
+     if ( (group == null) && (av.alignment.getGroups().size() > 0))
+     {
+       group = (SequenceGroup) av.alignment.getGroups().elementAt(0);
+       groupIndex = 0;
+     }
+
+     if (group != null)
+     {
+       do
+       {
+         int oldY = -1;
+         int i = 0;
+         boolean inGroup = false;
+         int top = -1;
+         int bottom = -1;
+         int alHeight = av.alignment.getHeight()-1;
+
+         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;
+
+           if (sx + ex < 0 || sx > imgWidth)
+           {
+             continue;
+           }
+
+           if ( (sx <= (endRes - startRes) * av.charWidth) &&
+               group.getSequences(false).
+               contains(av.alignment.getSequenceAt(i)))
+           {
+             if ( (bottom == -1) &&
+             (i >= alHeight ||
+                 !group.getSequences(false).contains(
+                     av.alignment.getSequenceAt(i + 1))))
+             {
+               bottom = sy + av.charHeight;
+             }
+
+             if (!inGroup)
+             {
+               if ( ( (top == -1) && (i == 0)) ||
+                   !group.getSequences(false).contains(
+                       av.alignment.getSequenceAt(i - 1)))
+               {
+                 top = sy;
+               }
+
+               oldY = sy;
+               inGroup = true;
+
+               if (group == av.getSelectionGroup())
+               {
+                 g.setColor(Color.red);
+               }
+               else
+               {
+                 g.setColor(group.getOutlineColour());
+               }
+             }
+           }
+           else
+           {
+             if (inGroup)
+             {
+               if (sx >= 0 && sx < imgWidth)
+                 g.drawLine(sx, oldY, sx, sy);
+
+               if (sx + ex < imgWidth)
+                 g.drawLine(sx + ex, oldY, sx + ex, sy);
+
+               if (sx < 0)
+               {
+                 ex += sx;
+                 sx = 0;
+               }
+
+               if (sx + ex > imgWidth)
+                 ex = imgWidth;
+
+               else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)
+                 ex = (endRes - startRes + 1) * av.charWidth;
+
+               if (top != -1)
+               {
+                 g.drawLine(sx, top, sx + ex, top);
+                 top = -1;
+               }
+
+               if (bottom != -1)
+               {
+                 g.drawLine(sx, bottom, sx + ex, bottom);
+                 bottom = -1;
+               }
+
+               inGroup = false;
+             }
+           }
+         }
+
+         if (inGroup)
+         {
+           sy = offset + ( (i - startSeq) * av.charHeight);
+           if (sx >= 0 && sx < imgWidth)
+             g.drawLine(sx, oldY, sx, sy);
+
+           if (sx + ex < imgWidth)
+             g.drawLine(sx + ex, oldY, sx + ex, sy);
+
+           if (sx < 0)
+           {
+             ex += sx;
+             sx = 0;
+           }
+
+           if (sx + ex > imgWidth)
+             ex = imgWidth;
+           else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)
+             ex = (endRes - startRes + 1) * av.charWidth;
+
+           if (top != -1)
+           {
+             g.drawLine(sx, top, sx + ex, top);
+             top = -1;
+           }
+
+           if (bottom != -1)
+           {
+             g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);
+             bottom = -1;
+           }
+
+           inGroup = false;
+         }
+
+         groupIndex++;
+
+         if (groupIndex >= av.alignment.getGroups().size())
+         {
+           break;
+         }
+
+         group = (SequenceGroup) av.alignment.getGroups().elementAt(groupIndex);
+       }
+       while (groupIndex < av.alignment.getGroups().size());
+
+     }
+   }
+
+  public void highlightSearchResults(SearchResults results)
+  {
+    searchResults = results;
+
+    repaint();
+  }
+
+}
index e29f4e1..9439dba 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-\r
-public class SeqPanel\r
-    extends Panel implements MouseMotionListener, MouseListener\r
-{\r
-\r
-  public SeqCanvas seqCanvas;\r
-  public AlignmentPanel ap;\r
-\r
-  protected int lastres;\r
-  protected int startseq;\r
-  int startEdit = -1;\r
-  int endEdit = -1;\r
-\r
-  protected AlignViewport av;\r
-\r
-  // if character is inserted or deleted, we will need to recalculate the conservation\r
-  int seqEditOccurred = -1;\r
-\r
-  ScrollThread scrollThread = null;\r
-  boolean mouseDragging = false;\r
-\r
-  boolean editingSeqs = false;\r
-  boolean groupEditing = false;\r
-\r
-  public SeqPanel(AlignViewport avp, AlignmentPanel p)\r
-  {\r
-    this.av = avp;\r
-\r
-    seqCanvas = new SeqCanvas(avp);\r
-    setLayout(new BorderLayout());\r
-    add(seqCanvas);\r
-\r
-    ap = p;\r
-\r
-    seqCanvas.addMouseMotionListener(this);\r
-    seqCanvas.addMouseListener(this);\r
-\r
-    seqCanvas.repaint();\r
-  }\r
-\r
-\r
-     public void mousePressed(MouseEvent evt)\r
-     {\r
-       if (evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
-       {\r
-         if (evt.isAltDown() || evt.isControlDown())\r
-         {\r
-           groupEditing = true;\r
-         }\r
-\r
-         editingSeqs = true;\r
-         doMousePressed(evt);\r
-       }\r
-       else\r
-       {\r
-         doMousePressedDefineMode(evt);\r
-       }\r
-     }\r
-\r
-     public void mouseClicked(MouseEvent evt){}\r
-\r
-\r
-  public void mouseReleased(MouseEvent evt)\r
-  {\r
-    if (!editingSeqs)\r
-    {\r
-      doMouseReleasedDefineMode(evt);\r
-      return;\r
-    }\r
-\r
-\r
-    if (seqEditOccurred > -1)\r
-    {\r
-      editOccurred(seqEditOccurred);\r
-    }\r
-\r
-    startseq = -1;\r
-    lastres = -1;\r
-    seqEditOccurred = -1;\r
-    editingSeqs = false;\r
-    groupEditing = false;\r
-    ap.repaint();\r
-  }\r
-\r
-  int startWrapBlock=-1;\r
-  int wrappedBlock=-1;\r
-  int findRes(MouseEvent evt)\r
- {\r
-   int res = 0;\r
-   int x = evt.getX();\r
-\r
-  if (av.wrapAlignment)\r
-  {\r
-\r
-    int hgap = av.charHeight;\r
-    if (av.scaleAboveWrapped)\r
-      hgap += av.charHeight;\r
-\r
-    int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-        + hgap + seqCanvas.getAnnotationHeight();\r
-\r
-      int y = evt.getY();\r
-      y -= hgap;\r
-      x -= seqCanvas.LABEL_WEST;\r
-\r
-\r
-      int cwidth = seqCanvas.getWrappedCanvasWidth(getSize().width);\r
-\r
-      wrappedBlock = y / cHeight;\r
-      wrappedBlock += av.getStartRes() / cwidth;\r
-\r
-      res = wrappedBlock * cwidth + x / av.getCharWidth();\r
-\r
-  }\r
-  else\r
-  {\r
-      res = (x / av.getCharWidth()) + av.getStartRes();\r
-  }\r
-\r
-  return res;\r
-\r
- }\r
-\r
- int findSeq(MouseEvent evt)\r
- {\r
-\r
-   int seq = 0;\r
-   int y = evt.getY();\r
-\r
-   if (av.wrapAlignment)\r
-   {\r
-     int hgap = av.charHeight;\r
-     if (av.scaleAboveWrapped)\r
-       hgap += av.charHeight;\r
-\r
-     int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-         + hgap + seqCanvas.getAnnotationHeight();\r
-\r
-       y -= hgap;\r
-\r
-     seq = ( (y % cHeight) / av.getCharHeight());\r
-   }\r
-   else\r
-   {\r
-     seq = (y / av.getCharHeight()) + av.getStartSeq();\r
-   }\r
-\r
-   return seq;\r
- }\r
-\r
-\r
-  public void doMousePressed(MouseEvent evt)\r
-  {\r
-    ap.alignFrame.addHistoryItem(new HistoryItem(\r
-        "Edit Sequence", av.alignment, HistoryItem.EDIT));\r
-\r
-    int seq = findSeq(evt);\r
-    int res = findRes(evt);\r
-\r
-    if (seq < av.getAlignment().getHeight() &&\r
-        res < av.getAlignment().getSequenceAt(seq).getLength())\r
-    {\r
-      //char resstr = align.getSequenceAt(seq).getSequence().charAt(res);\r
-      // Find the residue's position in the sequence (res is the position\r
-      // in the alignment\r
-\r
-      startseq = seq;\r
-      lastres = res;\r
-    }\r
-    else\r
-    {\r
-      startseq = -1;\r
-      lastres = -1;\r
-    }\r
-\r
-    return;\r
-  }\r
-\r
-  public void mouseMoved(MouseEvent evt)\r
-  {\r
-    int res = findRes(evt);\r
-    int seq = findSeq(evt);\r
-\r
-    if (seq >= av.getAlignment().getHeight() || seq<0 || res<0)\r
-    {\r
-      return;\r
-    }\r
-\r
-    SequenceI sequence = av.getAlignment().getSequenceAt(seq);\r
-    if (res > sequence.getLength())\r
-    {\r
-      return;\r
-    }\r
-\r
-    StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " +\r
-            sequence.getName());\r
-\r
-    Object obj = null;\r
-    if (av.alignment.isNucleotide())\r
-    {\r
-      obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) +\r
-          "");\r
-      if(obj!=null)\r
-        text.append(" Nucleotide: ");\r
-    }\r
-    else\r
-    {\r
-      obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + "");\r
-      if(obj!=null)\r
-        text.append("  Residue: ");\r
-    }\r
-\r
-    if (obj != null)\r
-    {\r
-\r
-      if (obj != "")\r
-      {\r
-        text.append(obj + " (" +\r
-                    av.getAlignment().getSequenceAt(seq).findPosition(res) + ")");\r
-      }\r
-    }\r
-\r
-    if(seqCanvas.pdbCanvas!=null && sequence==seqCanvas.pdbCanvas.sequence)\r
-    {\r
-      seqCanvas.pdbCanvas.highlightRes(sequence.findPosition(res));\r
-    }\r
-\r
-\r
-    // use aa to see if the mouse pointer is on a\r
-    if (av.showSequenceFeatures\r
-        && sequence.getSequenceFeatures()!=null\r
-        && av.featuresDisplayed!=null)\r
-    {\r
-      int index = 0;\r
-      sequence.getSequenceFeatures();\r
-      boolean first = true;\r
-      while (index < sequence.getSequenceFeatures().length)\r
-      {\r
-        SequenceFeature sf = sequence.getSequenceFeatures()[index];\r
-        if (sf.getBegin() <= sequence.findPosition(res) &&\r
-            sf.getEnd() >= sequence.findPosition(res))\r
-        {\r
-          if(!av.featuresDisplayed.containsKey(sf.getType()))\r
-           {\r
-             index++;\r
-             continue;\r
-           }\r
-\r
-          if(first)\r
-          {\r
-            text.append(" Sequence Feature:");\r
-            first = false;\r
-          }\r
-\r
-          text.append(" "+sf.getType());\r
-\r
-          if(sf.getDescription()!=null)\r
-            text.append(" "+sf.getDescription());\r
-\r
-          if (sf.getStatus()!=null && sf.getStatus().length() > 0)\r
-          {\r
-            text.append(" (" + sf.getStatus() + ")");\r
-          }\r
-          text.append("; ");\r
-        }\r
-\r
-        index++;\r
-\r
-      }\r
-    }\r
-\r
-     ap.alignFrame.statusBar.setText(text.toString());\r
-\r
-  }\r
-\r
-  public void mouseDragged(MouseEvent evt)\r
-  {\r
-    if (!editingSeqs)\r
-    {\r
-      doMouseDraggedDefineMode(evt);\r
-      return;\r
-    }\r
-\r
-    // If we're dragging we're editing\r
-    int res = findRes(evt);\r
-    if (res < 0)\r
-    {\r
-      res = 0;\r
-    }\r
-\r
-    if (lastres == -1 || lastres == res)\r
-    {\r
-      return;\r
-    }\r
-\r
-    boolean dragRight = true;\r
-    if (res < av.getAlignment().getWidth() && res < lastres)\r
-    {\r
-      dragRight = false;\r
-    }\r
-\r
-    if (res != lastres)\r
-    {\r
-      // Group editing\r
-      if (groupEditing)\r
-      {\r
-        SequenceGroup sg = av.getSelectionGroup();\r
-        if (sg == null)\r
-        {\r
-          lastres = -1;\r
-          return;\r
-        }\r
-\r
-        // drag to right\r
-        if (dragRight)\r
-        {\r
-          sg.setEndRes(sg.getEndRes() + (res - lastres));\r
-        }\r
-\r
-        // drag to left\r
-        else\r
-        {\r
-          /// Are we able to delete?\r
-          // ie are all columns blank?\r
-          boolean deleteAllowed = false;\r
-          for (int s = 0; s < sg.getSize(); s++)\r
-          {\r
-            SequenceI seq = sg.getSequenceAt(s);\r
-            for (int j = res; j < lastres; j++)\r
-            {\r
-              if (seq.getSequence().length() <= j)\r
-              {\r
-                continue;\r
-              }\r
-\r
-              if (!jalview.util.Comparison.isGap(seq.getSequence().charAt(j)))\r
-              {\r
-                // Not a gap, block edit not valid\r
-                res = j + 1;\r
-                deleteAllowed = false;\r
-                continue;\r
-              }\r
-              deleteAllowed = true;\r
-            }\r
-          }\r
-\r
-          if (!deleteAllowed)\r
-          {\r
-            lastres = -1;\r
-            return;\r
-          }\r
-\r
-          sg.setEndRes(sg.getEndRes() - (lastres - res));\r
-        }\r
-\r
-        for (int i = 0; i < sg.getSize(); i++)\r
-        {\r
-          SequenceI s = sg.getSequenceAt(i);\r
-          int k = av.alignment.findIndex(s);\r
-\r
-          // drag to right\r
-          if (dragRight)\r
-          {\r
-            for (int j = lastres; j < res; j++)\r
-            {\r
-              insertChar(j, k);\r
-            }\r
-          }\r
-\r
-          // drag to left\r
-          else\r
-          {\r
-            for (int j = res; j < lastres; j++)\r
-            {\r
-              if (s.getLength() > j)\r
-              {\r
-                deleteChar(res, k);\r
-              }\r
-            }\r
-          }\r
-        }\r
-      }\r
-      else /////Editing a single sequence///////////\r
-      {\r
-        if (res < av.getAlignment().getWidth() && res > lastres)\r
-        {\r
-          // dragging to the right\r
-          for (int j = lastres; j < res; j++)\r
-          {\r
-            insertChar(j, startseq);\r
-          }\r
-        }\r
-        else if (res < av.getAlignment().getWidth() && res < lastres)\r
-        {\r
-          // dragging to the left\r
-          for (int j = lastres; j > res; j--)\r
-          {\r
-            if (jalview.util.Comparison.isGap(\r
-                av.alignment.getSequenceAt(startseq).getSequence().charAt(res)))\r
-            {\r
-\r
-              deleteChar(res, startseq);\r
-            }\r
-            else\r
-            {\r
-              if(scrollThread!=null)\r
-              {\r
-                scrollThread.running = false;\r
-                scrollThread = null;\r
-              }\r
-              break;\r
-            }\r
-          }\r
-        }\r
-\r
-      }\r
-    }\r
-\r
-    mouseDragging = true;\r
-    if (res > av.endRes || res < av.startRes)\r
-    {\r
-      mouseExited(evt);\r
-    }\r
-\r
-    if (scrollThread != null)\r
-      scrollThread.setEvent(evt);\r
-\r
-\r
-    endEdit = res;\r
-    lastres = res;\r
-    seqCanvas.repaint();\r
-  }\r
-\r
-  public void insertChar(int j, int seq)\r
-  {\r
-    av.alignment.getSequenceAt(seq).insertCharAt(j, av.getGapCharacter());\r
-    seqEditOccurred = seq;\r
-  }\r
-\r
-  public void deleteChar(int j, int seq)\r
-  {\r
-\r
-    av.alignment.getSequenceAt(seq).deleteCharAt(j);\r
-    seqEditOccurred = seq;\r
-    av.alignment.getWidth();\r
-    repaint();\r
-  }\r
-\r
-  void editOccurred(int i)\r
-  {\r
-    if (endEdit == startEdit)\r
-    {\r
-        ap.alignFrame.historyList.pop();\r
-        ap.alignFrame.updateEditMenuBar();\r
-    }\r
-\r
-    av.firePropertyChange("alignment", null,av.getAlignment().getSequences());\r
-  }\r
-\r
-//////////////////////////////////////////\r
-/////Everything below this is for defining the boundary of the rubberband\r
-//////////////////////////////////////////\r
-  int oldSeq = -1;\r
-  public void doMousePressedDefineMode(MouseEvent evt)\r
-  {\r
-    if (scrollThread != null)\r
-    {\r
-      scrollThread.running = false;\r
-      scrollThread = null;\r
-    }\r
-\r
-    int res = findRes(evt);\r
-    int seq = findSeq(evt);\r
-    oldSeq = seq;\r
-    startWrapBlock=wrappedBlock;\r
-\r
-    if(seq==-1)\r
-      return;\r
-\r
-    SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq);\r
-\r
-    if (sequence == null || res > sequence.getLength())\r
-    {\r
-      return;\r
-    }\r
-\r
-    stretchGroup = av.getSelectionGroup();\r
-\r
-    if (stretchGroup == null)\r
-    {\r
-      stretchGroup = av.alignment.findGroup(sequence);\r
-      if (stretchGroup != null && res > stretchGroup.getStartRes() &&\r
-          res < stretchGroup.getEndRes())\r
-      {\r
-        av.setSelectionGroup(stretchGroup);\r
-      }\r
-      else\r
-      {\r
-        stretchGroup = null;\r
-      }\r
-    }\r
-\r
-    else if (!stretchGroup.sequences.contains(sequence)\r
-             || stretchGroup.getStartRes() > res\r
-             || stretchGroup.getEndRes() < res)\r
-    {\r
-      stretchGroup = null;\r
-\r
-      SequenceGroup[] allGroups = av.alignment.findAllGroups(sequence);\r
-\r
-      if (allGroups != null)\r
-      {\r
-        for (int i = 0; i < allGroups.length; i++)\r
-        {\r
-          if (allGroups[i].getStartRes() <= res &&\r
-              allGroups[i].getEndRes() >= res)\r
-          {\r
-            stretchGroup = allGroups[i];\r
-            av.setSelectionGroup(stretchGroup);\r
-            break;\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    if (stretchGroup == null)\r
-    {\r
-      // define a new group here\r
-      SequenceGroup sg = new SequenceGroup();\r
-      sg.setStartRes(res);\r
-      sg.setEndRes(res);\r
-      sg.addSequence(sequence, false);\r
-      av.setSelectionGroup(sg);\r
-      stretchGroup = sg;\r
-\r
-      if (av.getConservationSelected())\r
-      {\r
-        SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(),\r
-                                          "Background");\r
-      }\r
-      if (av.getAbovePIDThreshold())\r
-      {\r
-        SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),\r
-                                       "Background");\r
-      }\r
-\r
-    }\r
-\r
-    // DETECT RIGHT MOUSE BUTTON IN AWT\r
-    else if ( (evt.getModifiers() & InputEvent.BUTTON3_MASK) ==\r
-             InputEvent.BUTTON3_MASK)\r
-    {\r
-      APopupMenu popup = new APopupMenu(ap, null, null);\r
-      this.add(popup);\r
-      popup.show(this, evt.getX(), evt.getY());\r
-    }\r
-\r
-    if (stretchGroup != null && stretchGroup.getEndRes() == res)\r
-    {\r
-      // Edit end res position of selected group\r
-      changeEndRes = true;\r
-    }\r
-\r
-    else if (stretchGroup != null && stretchGroup.getStartRes() == res)\r
-    {\r
-      // Edit end res position of selected group\r
-      changeStartRes = true;\r
-    }\r
-\r
-  }\r
-\r
-  boolean changeEndSeq = false;\r
-  boolean changeStartSeq = false;\r
-  boolean changeEndRes = false;\r
-  boolean changeStartRes = false;\r
-  SequenceGroup stretchGroup = null;\r
-\r
-  public void doMouseReleasedDefineMode(MouseEvent evt)\r
-  {\r
-    if (stretchGroup == null)\r
-    {\r
-        return;\r
-    }\r
-\r
-    if(stretchGroup.cs!=null)\r
-    {\r
-      if (stretchGroup.cs instanceof ClustalxColourScheme)\r
-      {\r
-        ( (ClustalxColourScheme) stretchGroup.cs).resetClustalX(stretchGroup.\r
-            sequences,\r
-            stretchGroup.getWidth());\r
-      }\r
-\r
-      if (stretchGroup.cs.conservationApplied())\r
-      {\r
-        SliderPanel.setConservationSlider(ap, stretchGroup.cs,\r
-                                          stretchGroup.getName());\r
-        stretchGroup.recalcConservation();\r
-      }\r
-      else\r
-      {\r
-        SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,\r
-                                       stretchGroup.getName());\r
-      }\r
-    }\r
-    changeEndRes = false;\r
-    changeStartRes = false;\r
-    stretchGroup = null;\r
-    PaintRefresher.Refresh(av.alignment);\r
-    ap.repaint();\r
-  }\r
-\r
-  public void doMouseDraggedDefineMode(MouseEvent evt)\r
-  {\r
-    int res = findRes(evt);\r
-    int y = findSeq(evt);\r
-\r
-    if(wrappedBlock!=startWrapBlock)\r
-      return;\r
-\r
-     if (stretchGroup == null)\r
-     {\r
-          return;\r
-     }\r
-\r
-     mouseDragging = true;\r
-\r
-\r
-      if(y > av.alignment.getHeight())\r
-      {\r
-        y = av.alignment.getHeight() -1;\r
-      }\r
-\r
-      if(res>av.alignment.getWidth())\r
-        res = av.alignment.getWidth()-1;\r
-\r
-      if (stretchGroup.getEndRes() == res)\r
-      {\r
-          // Edit end res position of selected group\r
-          changeEndRes = true;\r
-      }\r
-      else if (stretchGroup.getStartRes() == res)\r
-      {\r
-          // Edit start res position of selected group\r
-          changeStartRes = true;\r
-      }\r
-\r
-      if (res < 0)\r
-      {\r
-          res = 0;\r
-      }\r
-\r
-      if (changeEndRes)\r
-      {\r
-          if (res > (stretchGroup.getStartRes() - 1))\r
-          {\r
-              stretchGroup.setEndRes(res);\r
-          }\r
-      }\r
-      else if (changeStartRes)\r
-      {\r
-          if (res < (stretchGroup.getEndRes() + 1))\r
-          {\r
-              stretchGroup.setStartRes(res);\r
-          }\r
-      }\r
-\r
-      int dragDirection = 0;\r
-\r
-      if (y > oldSeq)\r
-      {\r
-          dragDirection = 1;\r
-      }\r
-      else if (y < oldSeq)\r
-      {\r
-          dragDirection = -1;\r
-      }\r
-\r
-\r
-      while ((y != oldSeq) && (oldSeq > -1) && (y < av.alignment.getHeight()))\r
-      {\r
-          // This routine ensures we don't skip any sequences, as the\r
-          // selection is quite slow.\r
-          Sequence seq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);\r
-\r
-          oldSeq += dragDirection;\r
-\r
-          if(oldSeq<0)\r
-            break;\r
-\r
-          Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);\r
-\r
-          if (stretchGroup.sequences.contains(nextSeq))\r
-          {\r
-              stretchGroup.deleteSequence(seq, false);\r
-          }\r
-          else\r
-          {\r
-              if (seq != null)\r
-              {\r
-                  stretchGroup.addSequence(seq, false);\r
-              }\r
-\r
-              stretchGroup.addSequence(nextSeq, false);\r
-          }\r
-      }\r
-\r
-      if(oldSeq < 0)\r
-        oldSeq = -1;\r
-\r
-\r
-      if(res>av.endRes || res<av.startRes\r
-          || y<av.startSeq || y>av.endSeq)\r
-      {\r
-        mouseExited(evt);\r
-      }\r
-\r
-      if (scrollThread != null)\r
-      {\r
-        scrollThread.setEvent(evt);\r
-      }\r
-\r
-      seqCanvas.repaint();\r
-    }\r
-\r
-    public void mouseEntered(MouseEvent e)\r
-    {\r
-      if (oldSeq < 0)\r
-        oldSeq = 0;\r
-\r
-      if (scrollThread != null)\r
-      {\r
-        scrollThread.running = false;\r
-        scrollThread = null;\r
-      }\r
-    }\r
-\r
-  public void mouseExited(MouseEvent e)\r
-  {\r
-    if (av.getWrapAlignment())\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (mouseDragging && scrollThread==null)\r
-    {\r
-      scrollThread = new ScrollThread();\r
-    }\r
-  }\r
-\r
-  // this class allows scrolling off the bottom of the visible alignment\r
-  class ScrollThread\r
-      extends Thread\r
-  {\r
-    MouseEvent evt;\r
-    boolean running = false;\r
-    public ScrollThread()\r
-    {\r
-      start();\r
-    }\r
-\r
-    public void setEvent(MouseEvent e)\r
-    {\r
-      evt = e;\r
-    }\r
-\r
-    public void stopScrolling()\r
-    {\r
-      running = false;\r
-    }\r
-\r
-    public void run()\r
-    {\r
-      running = true;\r
-      while (running)\r
-      {\r
-\r
-        if (evt != null)\r
-        {\r
-\r
-          if (mouseDragging && evt.getY() < 0 && av.getStartSeq() > 0)\r
-          {\r
-            running = ap.scrollUp(true);\r
-          }\r
-\r
-          if (mouseDragging && evt.getY() >= getSize().height &&\r
-              av.alignment.getHeight() > av.getEndSeq())\r
-          {\r
-            running = ap.scrollUp(false);\r
-          }\r
-\r
-          if (mouseDragging && evt.getX() < 0)\r
-          {\r
-            running = ap.scrollRight(true);\r
-          }\r
-\r
-          else if (mouseDragging && evt.getX() >= getSize().width)\r
-          {\r
-            running = ap.scrollRight(false);\r
-          }\r
-        }\r
-\r
-        try\r
-        {\r
-          Thread.sleep(75);\r
-        }\r
-        catch (Exception ex)\r
-        {}\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+import java.util.Vector;
+
+public class SeqPanel
+    extends Panel implements MouseMotionListener, MouseListener
+{
+
+  public SeqCanvas seqCanvas;
+  public AlignmentPanel ap;
+
+  protected int lastres;
+  protected int startseq;
+
+  protected AlignViewport av;
+
+  // if character is inserted or deleted, we will need to recalculate the conservation
+  boolean seqEditOccurred = false;
+
+  ScrollThread scrollThread = null;
+  boolean mouseDragging = false;
+  boolean editingSeqs = false;
+  boolean groupEditing = false;
+
+  int oldSeq = -1;
+  boolean changeEndSeq = false;
+  boolean changeStartSeq = false;
+  boolean changeEndRes = false;
+  boolean changeStartRes = false;
+  SequenceGroup stretchGroup = null;
+
+  StringBuffer keyboardNo1;
+  StringBuffer keyboardNo2;
+
+  boolean mouseWheelPressed = false;
+  Point lastMousePress;
+
+  public SeqPanel(AlignViewport avp, AlignmentPanel p)
+  {
+    this.av = avp;
+
+    seqCanvas = new SeqCanvas(avp);
+    setLayout(new BorderLayout());
+    add(seqCanvas);
+
+    ap = p;
+
+    seqCanvas.addMouseMotionListener(this);
+    seqCanvas.addMouseListener(this);
+
+    seqCanvas.repaint();
+  }
+
+  void endEditing()
+  {
+    startseq = -1;
+    lastres = -1;
+    seqEditOccurred = false;
+    editingSeqs = false;
+    groupEditing = false;
+    keyboardNo1 = null;
+    keyboardNo2 = null;
+   }
+
+   void setCursorRow()
+   {
+     seqCanvas.cursorY = getKeyboardNo(keyboardNo1)-1;
+     scrollToVisible();
+   }
+
+   void setCursorColumn()
+   {
+     seqCanvas.cursorX = getKeyboardNo(keyboardNo1)-1;
+     scrollToVisible();
+   }
+
+   void setCursorRowAndColumn()
+   {
+     if(keyboardNo2==null)
+     {
+       keyboardNo2 = new StringBuffer();
+     }
+     else
+     {
+       seqCanvas.cursorX = getKeyboardNo(keyboardNo1) - 1;
+       seqCanvas.cursorY = getKeyboardNo(keyboardNo2) - 1;
+       scrollToVisible();
+     }
+   }
+
+   void setCursorPosition()
+   {
+     SequenceI sequence =
+         (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY);
+
+     seqCanvas.cursorX = sequence.findIndex(
+         getKeyboardNo(keyboardNo1)-1
+         );
+     scrollToVisible();
+   }
+
+   void moveCursor(int dx, int dy)
+   {
+     seqCanvas.cursorX += dx;
+     seqCanvas.cursorY += dy;
+     scrollToVisible();
+   }
+
+   void scrollToVisible()
+   {
+     if (seqCanvas.cursorX < 0)
+       seqCanvas.cursorX = 0;
+     else if (seqCanvas.cursorX > av.alignment.getWidth() - 1)
+       seqCanvas.cursorX = av.alignment.getWidth() - 1;
+
+     if (seqCanvas.cursorY < 0)
+       seqCanvas.cursorY = 0;
+     else if (seqCanvas.cursorY > av.alignment.getHeight() - 1)
+       seqCanvas.cursorY = av.alignment.getHeight() - 1;
+
+
+     endEditing();
+     if (av.wrapAlignment)
+     {
+       ap.scrollToWrappedVisible(seqCanvas.cursorX);
+     }
+     else
+     {
+       while (seqCanvas.cursorY < av.startSeq)
+       {
+         ap.scrollUp(true);
+       }
+       while (seqCanvas.cursorY + 1 > av.endSeq)
+       {
+         ap.scrollUp(false);
+       }
+       while (seqCanvas.cursorX < av.startRes)
+       {
+
+         if (!ap.scrollRight(false))
+           break;
+       }
+       while (seqCanvas.cursorX > av.endRes)
+       {
+         if (!ap.scrollRight(true))
+           break;
+       }
+     }
+     setStatusMessage(av.alignment.getSequenceAt(seqCanvas.cursorY),
+                      seqCanvas.cursorX, seqCanvas.cursorY);
+
+     seqCanvas.repaint();
+   }
+
+   void setSelectionAreaAtCursor(boolean topLeft)
+   {
+     SequenceI sequence =
+         (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY);
+
+     if(av.getSelectionGroup()!=null)
+     {
+       SequenceGroup sg = av.selectionGroup;
+       //Find the top and bottom of this group
+       int min = av.alignment.getHeight(), max = 0;
+       for(int i=0; i<sg.getSize(false); i++)
+       {
+         int index = av.alignment.findIndex( sg.getSequenceAt(i) );
+         if(index > max)
+           max = index;
+         if(index < min)
+           min = index;
+       }
+
+       max ++;
+
+       if(topLeft)
+       {
+         sg.setStartRes(seqCanvas.cursorX);
+         if(sg.getEndRes()<seqCanvas.cursorX)
+           sg.setEndRes(seqCanvas.cursorX);
+
+         min = seqCanvas.cursorY;
+       }
+       else
+       {
+         sg.setEndRes(seqCanvas.cursorX);
+         if(sg.getStartRes()>seqCanvas.cursorX)
+           sg.setStartRes(seqCanvas.cursorX);
+
+         max = seqCanvas.cursorY+1;
+       }
+
+       if(min>max)
+       {
+         // Only the user can do this
+         av.setSelectionGroup(null);
+       }
+       else
+       {
+         // Now add any sequences between min and max
+         sg.getSequences(false).removeAllElements();
+         for (int i = min; i < max; i++)
+         {
+           sg.addSequence(av.alignment.getSequenceAt(i), false);
+         }
+       }
+     }
+
+     if (av.getSelectionGroup() == null)
+     {
+       SequenceGroup sg = new SequenceGroup();
+       sg.setStartRes(seqCanvas.cursorX);
+       sg.setEndRes(seqCanvas.cursorX);
+       sg.addSequence(sequence, false);
+       av.setSelectionGroup(sg);
+     }
+
+
+     ap.repaint();
+   }
+
+   void insertGapAtCursor(boolean group)
+   {
+     ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",
+                                                  av.alignment, HistoryItem.EDIT));
+     groupEditing = group;
+     startseq = seqCanvas.cursorY;
+     lastres = seqCanvas.cursorX;
+     editSequence(true, seqCanvas.cursorX+getKeyboardNo(keyboardNo1));
+     editOccurred();
+   }
+
+   void deleteGapAtCursor(boolean group)
+   {
+     ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",
+                                                  av.alignment, HistoryItem.EDIT));
+     groupEditing = group;
+     startseq = seqCanvas.cursorY;
+     lastres = seqCanvas.cursorX+getKeyboardNo(keyboardNo1);
+     editSequence(false, seqCanvas.cursorX);
+     editOccurred();
+   }
+
+   void numberPressed(char value)
+   {
+     if(keyboardNo1==null)
+       keyboardNo1 = new StringBuffer();
+
+     if(keyboardNo2!=null)
+       keyboardNo2.append(value);
+     else
+       keyboardNo1.append(value);
+   }
+
+   int getKeyboardNo(StringBuffer kb)
+   {
+     if(kb==null)
+       return 1;
+     else
+       return Integer.parseInt(kb.toString());
+   }
+
+   void setStatusMessage(SequenceI sequence, int res, int seq)
+   {
+     StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " +
+                                          sequence.getName());
+
+     Object obj = null;
+     if (av.alignment.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) +
+                     ")");
+       }
+     }
+
+     ap.alignFrame.statusBar.setText(text.toString());
+
+    }
+     public void mousePressed(MouseEvent evt)
+     {
+       lastMousePress = evt.getPoint();
+
+       if ( (evt.getModifiers() & InputEvent.BUTTON2_MASK) ==
+         InputEvent.BUTTON2_MASK && !av.MAC)
+       {
+         mouseWheelPressed = true;
+         return;
+       }
+
+       if (evt.isShiftDown() || evt.isControlDown())
+       {
+         if (evt.isControlDown())
+         {
+           groupEditing = true;
+         }
+         editingSeqs = true;
+       }
+       else
+       {
+         doMousePressedDefineMode(evt);
+         return;
+       }
+
+
+       int seq = findSeq(evt);
+       int res = findRes(evt);
+
+       if(seq<0 || res<0)
+         return;
+
+       ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",
+                                                          av.alignment, HistoryItem.EDIT));
+
+         if ((seq < av.getAlignment().getHeight()) &&
+                 (res < av.getAlignment().getSequenceAt(seq).getLength()))
+         {
+             startseq = seq;
+             lastres = res;
+         }
+         else
+         {
+             startseq = -1;
+             lastres = -1;
+         }
+
+        return;
+     }
+
+     public void mouseClicked(MouseEvent evt){}
+
+
+  public void mouseReleased(MouseEvent evt)
+  {
+    mouseDragging = false;
+    mouseWheelPressed = false;
+
+    if (!editingSeqs)
+    {
+       doMouseReleasedDefineMode(evt);
+       return;
+    }
+
+     editOccurred();
+
+     endEditing();
+     ap.repaint();
+  }
+
+  int startWrapBlock=-1;
+  int wrappedBlock=-1;
+  int findRes(MouseEvent evt)
+ {
+   int res = 0;
+   int x = evt.getX();
+
+  if (av.wrapAlignment)
+  {
+
+    int hgap = av.charHeight;
+    if (av.scaleAboveWrapped)
+      hgap += av.charHeight;
+
+    int cHeight = av.getAlignment().getHeight() * av.charHeight
+        + hgap + seqCanvas.getAnnotationHeight();
+
+      int y = evt.getY();
+      y -= hgap;
+      x -= seqCanvas.LABEL_WEST;
+
+
+      int cwidth = seqCanvas.getWrappedCanvasWidth(getSize().width);
+
+      wrappedBlock = y / cHeight;
+      wrappedBlock += av.getStartRes() / cwidth;
+
+      res = wrappedBlock * cwidth + x / av.getCharWidth();
+
+  }
+  else
+  {
+      res = (x / av.getCharWidth()) + av.getStartRes();
+  }
+
+  if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+  return res;
+
+ }
+
+ int findSeq(MouseEvent evt)
+ {
+
+   int seq = 0;
+   int y = evt.getY();
+
+   if (av.wrapAlignment)
+   {
+     int hgap = av.charHeight;
+     if (av.scaleAboveWrapped)
+       hgap += av.charHeight;
+
+     int cHeight = av.getAlignment().getHeight() * av.charHeight
+         + hgap + seqCanvas.getAnnotationHeight();
+
+       y -= hgap;
+
+     seq = Math.min( (y % cHeight) / av.getCharHeight(),
+                     av.alignment.getHeight() -1);
+     if(seq<0)
+       seq = 0;
+   }
+   else
+   {
+     seq = Math.min( (y / av.getCharHeight()) + av.getStartSeq(),
+                     av.alignment.getHeight() -1);
+     if(seq<0)
+       seq = 0;
+   }
+
+   return seq;
+ }
+
+
+  public void doMousePressed(MouseEvent evt)
+  {
+    ap.alignFrame.addHistoryItem(new HistoryItem(
+        "Edit Sequence", av.alignment, HistoryItem.EDIT));
+
+    int seq = findSeq(evt);
+    int res = findRes(evt);
+
+    if (seq < av.getAlignment().getHeight() &&
+        res < av.getAlignment().getSequenceAt(seq).getLength())
+    {
+      //char resstr = align.getSequenceAt(seq).getSequence().charAt(res);
+      // Find the residue's position in the sequence (res is the position
+      // in the alignment
+
+      startseq = seq;
+      lastres = res;
+    }
+    else
+    {
+      startseq = -1;
+      lastres = -1;
+    }
+
+    return;
+  }
+
+  public void mouseMoved(MouseEvent evt)
+  {
+    int res = findRes(evt);
+    int seq = findSeq(evt);
+
+    if (seq >= av.getAlignment().getHeight() || seq<0 || res<0)
+    {
+      return;
+    }
+
+    SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+    if (res > sequence.getLength())
+    {
+      return;
+    }
+
+    StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " +
+            sequence.getName());
+
+    Object obj = null;
+    if (av.alignment.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(seqCanvas.pdbCanvas!=null && sequence==seqCanvas.pdbCanvas.sequence)
+    {
+      seqCanvas.pdbCanvas.highlightRes(sequence.findPosition(res));
+    }
+
+    ap.alignFrame.statusBar.setText(text.toString());
+
+
+    // use aa to see if the mouse pointer is on a
+    if (av.showSequenceFeatures
+        && sequence.getSequenceFeatures()!=null
+        && av.featuresDisplayed!=null)
+    {
+      StringBuffer featureText = new StringBuffer();
+      Vector allFeatures = getAllFeaturesAtRes(sequence, sequence.findPosition(res));
+
+      int index = 0;
+      while (index < allFeatures.size())
+      {
+        SequenceFeature sf = (SequenceFeature) allFeatures.elementAt(index);
+
+        featureText.append(sf.getType()+" "+sf.begin+":"+sf.end);
+
+        if (sf.getDescription() != null)
+          featureText.append(" " + sf.getDescription());
+
+        if (sf.getValue("status") != null )
+        {
+          featureText.append(" (" + sf.getValue("status") + ")");
+        }
+        featureText.append("\n");
+
+        index++;
+      }
+
+
+        if (tooltip == null)
+          tooltip = new Tooltip(featureText.toString(), seqCanvas);
+        else
+          tooltip.setTip(featureText.toString());
+
+        tooltip.repaint();
+
+    }
+  }
+
+  Vector getAllFeaturesAtRes(SequenceI seq, int res)
+  {
+    Vector allFeatures = new Vector();
+    int index = 0;
+    if(seq.getSequenceFeatures()!=null)
+    {
+      while (index < seq.getSequenceFeatures().length)
+      {
+        SequenceFeature sf = seq.getSequenceFeatures()[index];
+        if (sf.getBegin() <= res &&
+            sf.getEnd() >= res)
+        {
+          if (av.featuresDisplayed.containsKey(sf.getType()))
+          {
+            allFeatures.addElement(sf);
+          }
+        }
+        index++;
+      }
+    }
+    return allFeatures;
+  }
+
+  Tooltip tooltip;
+
+  public void mouseDragged(MouseEvent evt)
+  {
+    if (mouseWheelPressed)
+    {
+      int oldWidth = av.charWidth;
+
+      //Which is bigger, left-right or up-down?
+      if (Math.abs(evt.getY() - lastMousePress.y)
+          > Math.abs(evt.getX() - lastMousePress.x))
+      {
+        int fontSize = av.font.getSize();
+
+        if (evt.getY() < lastMousePress.y && av.charHeight > 1)
+        {
+          fontSize--;
+        }
+        else if (evt.getY() > lastMousePress.y)
+        {
+          fontSize++;
+        }
+
+
+        if(fontSize<1)
+          fontSize = 1;
+
+        av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize));
+        av.charWidth = oldWidth;
+      }
+      else
+      {
+        if (evt.getX() < lastMousePress.x && av.charWidth > 1)
+        {
+          av.charWidth--;
+        }
+        else if (evt.getX() > lastMousePress.x)
+        {
+          av.charWidth++;
+        }
+
+        if(av.charWidth<1)
+        {
+          av.charWidth = 1;
+        }
+      }
+
+      ap.fontChanged();
+
+      FontMetrics fm = getFontMetrics(av.getFont());
+      av.validCharWidth = fm.charWidth('M') <= av.charWidth;
+
+      lastMousePress = evt.getPoint();
+
+      ap.repaint();
+      ap.annotationPanel.image = null;
+      return;
+      }
+
+      if (!editingSeqs)
+      {
+        doMouseDraggedDefineMode(evt);
+        return;
+      }
+
+  int res = findRes(evt);
+
+  if (res < 0)
+  {
+      res = 0;
+  }
+
+  if ((lastres == -1) || (lastres == res))
+  {
+      return;
+  }
+
+  if ( (res < av.getAlignment().getWidth()) && (res < lastres))
+  {
+    // dragLeft, delete gap
+    editSequence(false, res);
+  }
+  else
+    editSequence(true, res);
+
+  mouseDragging = true;
+  if(scrollThread!=null)
+    scrollThread.setEvent(evt);
+
+  }
+
+  synchronized void editSequence(boolean insertGap, int startres)
+  {
+    int fixedLeft = -1;
+    int fixedRight = -1;
+    boolean fixedColumns = false;
+    SequenceGroup sg = av.getSelectionGroup();
+
+
+      if (!groupEditing && av.hasHiddenRows)
+      {
+        if (av.alignment.getSequenceAt(startseq).getHiddenSequences() != null)
+        {
+          groupEditing = true;
+        }
+      }
+
+      //No group, but the sequence may represent a group
+      if (groupEditing
+          && sg == null
+          && av.alignment.getSequenceAt(startseq).getHiddenSequences() == null)
+      {
+        groupEditing = false;
+      }
+
+      SequenceI seq = av.alignment.getSequenceAt(startseq);
+      StringBuffer message = new StringBuffer();
+      if (groupEditing)
+         message.append("Edit group:");
+      else
+         message.append("Edit sequence: "+seq.getName());
+
+     if(insertGap)
+       message.append(" insert ");
+     else
+       message.append(" delete ");
+
+     message.append(Math.abs(startres-lastres)+" gaps.");
+     ap.alignFrame.statusBar.setText(message.toString());
+
+
+      //Are we editing within a selection group?
+      if (groupEditing
+          || (sg != null && sg.getSequences(true).contains(seq)))
+      {
+        fixedColumns = true;
+
+        //sg might be null as the user may only see 1 sequence,
+        //but the sequence represents a group
+        if (sg == null)
+        {
+          sg = new SequenceGroup(null, null, false, false, false, 0,
+                                 av.alignment.getWidth()-1);
+          sg.addSequence(av.alignment.getSequenceAt(startseq), false);
+        }
+
+        fixedLeft = sg.getStartRes();
+        fixedRight = sg.getEndRes();
+
+        if (   (startres < fixedLeft && lastres >= fixedLeft)
+            || (startres >= fixedLeft && lastres < fixedLeft)
+            || (startres > fixedRight && lastres <=fixedRight)
+            || (startres <= fixedRight && lastres > fixedRight))
+        {
+          endEditing();
+          return;
+        }
+
+        if (fixedLeft > startres)
+        {
+          fixedRight = fixedLeft - 1;
+          fixedLeft = 0;
+        }
+        else if (fixedRight < startres)
+        {
+          fixedLeft = fixedRight;
+          fixedRight = -1;
+        }
+      }
+
+
+      if(av.hasHiddenColumns )
+      {
+          fixedColumns = true;
+          int y1 = av.getColumnSelection().getHiddenBoundaryLeft(startres);
+          int y2 = av.getColumnSelection().getHiddenBoundaryRight(startres);
+
+          if ( (insertGap && startres > y1 && lastres < y1)
+              || (!insertGap && startres < y2 && lastres > y2))
+          {
+            endEditing();
+            return;
+          }
+
+          //System.out.print(y1+" "+y2+" "+fixedLeft+" "+fixedRight+"~~");
+          //Selection spans a hidden region
+          if(fixedLeft<y1 && (fixedRight>y2 || fixedRight==-1))
+          {
+            if(startres>=y2)
+            {
+              fixedLeft = y2;
+            }
+            else
+            {
+             fixedRight = y2 - 1;
+           }
+          }
+      }
+
+
+      if (groupEditing)
+      {
+        // drag to right
+        if (insertGap)
+        {
+            //If the user has selected the whole sequence, and is dragging to
+            // the right, we can still extend the alignment and selectionGroup
+            if(   sg.getStartRes() == 0
+                  && sg.getEndRes() == fixedRight
+                  && sg.getEndRes() == av.alignment.getWidth()-1
+               )
+            {
+              sg.setEndRes(av.alignment.getWidth() + startres - lastres);
+              fixedRight = sg.getEndRes();
+            }
+
+          // Is it valid with fixed columns??
+          // Find the next gap before the end
+          // of the visible region boundary
+          boolean blank = false;
+          for (fixedRight = fixedRight;
+               fixedRight > lastres;
+               fixedRight--)
+          {
+            blank = true;
+            for (int s = 0; s < sg.getSize(true); s++)
+            {
+              seq = (SequenceI)sg.getSequences(true).elementAt(s);
+              for (int j = 0; j < startres - lastres; j++)
+              {
+                if (!jalview.util.Comparison.isGap(
+                    seq.getCharAt(fixedRight - j)))
+                {
+                  blank = false;
+                  break;
+                }
+              }
+            }
+            if (blank)
+              break;
+          }
+
+          if (!blank)
+          {
+            if(sg.getSize(false) == av.alignment.getHeight()  )
+            {
+              if((av.hasHiddenColumns
+                  && startres<av.getColumnSelection().getHiddenBoundaryRight(startres)))
+              {
+                endEditing();
+                return;
+              }
+
+              int alWidth = av.alignment.getWidth();
+              if(av.hasHiddenRows)
+              {
+                int hwidth = av.alignment.getHiddenSequences().getWidth();
+                if(hwidth>alWidth)
+                  alWidth = hwidth;
+              }
+              //We can still insert gaps if the selectionGroup
+              //contains all the sequences
+              sg.setEndRes(sg.getEndRes()+startres-lastres);
+              fixedRight = alWidth+startres-lastres;
+            }
+            else
+            {
+              endEditing();
+              return;
+            }
+          }
+        }
+
+
+        // drag to left
+        else if(!insertGap)
+        {
+          /// Are we able to delete?
+          // ie are all columns blank?
+
+          for (int s = 0; s < sg.getSize(true); s++)
+          {
+            seq = (SequenceI)sg.getSequences(true).elementAt(s);
+
+            for (int j = startres; j < lastres; j++)
+            {
+              if (seq.getSequence().length() <= j)
+              {
+                continue;
+              }
+
+              if (!jalview.util.Comparison.isGap(
+                  seq.getSequence().charAt(j)))
+              {
+                // Not a gap, block edit not valid
+                endEditing();
+                return;
+              }
+            }
+          }
+        }
+
+
+        for (int i = 0; i < sg.getSize(true); i++)
+        {
+          seq = (SequenceI) sg.getSequences(true).elementAt(i);
+
+          if (insertGap)
+          {
+            // dragging to the right
+            for (int j = lastres; j < startres; j++)
+            {
+              if (fixedColumns && fixedRight != -1)
+              {
+                insertChar(j, seq, fixedRight);
+              }
+              else
+                insertChar(j, seq);
+            }
+          }
+          else
+          {
+            // dragging to the left
+            for (int j = lastres; j > startres; j--)
+            {
+              if (fixedColumns && fixedRight != -1)
+              {
+                deleteChar(startres, seq, fixedRight);
+              }
+              else
+              {
+                deleteChar(startres, seq);
+              }
+            }
+          }
+        }
+      }
+      else /////Editing a single sequence///////////
+      {
+        if (insertGap)
+        {
+          // dragging to the right
+          for (int j = lastres; j < startres; j++)
+          {
+            if (fixedColumns && fixedRight != -1)
+            {
+                insertChar(j, seq, fixedRight);
+            }
+            else
+              insertChar(j, seq);
+          }
+        }
+        else
+        {
+          // dragging to the left
+          for (int j = lastres; j > startres; j--)
+          {
+            if (fixedColumns && fixedRight != -1)
+            {
+              deleteChar(startres, seq, fixedRight);
+            }
+            else
+            {
+              deleteChar(startres, seq);
+            }
+          }
+        }
+      }
+
+      lastres = startres;
+      seqCanvas.repaint();
+  }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param j DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     */
+    void insertChar(int j, SequenceI seq)
+    {
+        seq.insertCharAt(j, av.getGapCharacter());
+        seqEditOccurred = true;
+    }
+
+    void insertChar(int j, SequenceI seq, int fixedColumn)
+    {
+      //Find the next gap before the end of the visible region boundary
+      //If lastCol > j, theres a boundary after the gap insertion
+      int blankColumn = fixedColumn;
+      for (blankColumn = fixedColumn; blankColumn > j; blankColumn--)
+      {
+        if (jalview.util.Comparison.isGap(seq.getCharAt(blankColumn)))
+        {
+          //Theres a space, so break and insert the gap
+          break;
+        }
+      }
+
+      if (blankColumn <= j)
+      {
+        endEditing();
+        return;
+      }
+
+      if (!jalview.util.Comparison.isGap(seq.getCharAt(blankColumn)))
+      {
+        //Just Checking
+        System.out.println("Tried removing residue (INSERT)"+seq.getCharAt(fixedColumn));
+        return;
+      }
+
+      seq.deleteCharAt(blankColumn);
+      seq.insertCharAt(j, av.getGapCharacter());
+      seqEditOccurred = true;
+    }
+
+    void deleteChar(int j, SequenceI seq, int fixedColumn)
+    {
+      if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))
+      {
+        ap.alignFrame.statusBar.setText(
+            "End editing: Tried removing residue " + seq.getCharAt(j));
+        return;
+      }
+
+      seq.deleteCharAt(j);
+      seq.insertCharAt(fixedColumn, av.getGapCharacter());
+      seqEditOccurred = true;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param j DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     */
+    void deleteChar(int j, SequenceI seq)
+    {
+      if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))
+      {
+        ap.alignFrame.statusBar.setText(
+            "End editing: Tried removing residue " + seq.getCharAt(j));
+        return;
+      }
+
+        seq.deleteCharAt(j);
+        seqEditOccurred = true;
+        seqCanvas.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    void editOccurred()
+    {
+      if (!seqEditOccurred)
+      {
+        ap.alignFrame.historyList.pop();
+        ap.alignFrame.updateEditMenuBar();
+      }
+
+      endEditing();
+
+      av.firePropertyChange("alignment", null,av.getAlignment().getSequences());
+
+    }
+
+//////////////////////////////////////////
+/////Everything below this is for defining the boundary of the rubberband
+//////////////////////////////////////////
+  public void doMousePressedDefineMode(MouseEvent evt)
+  {
+
+
+    if (scrollThread != null)
+    {
+      scrollThread.running = false;
+      scrollThread = null;
+    }
+
+    int res = findRes(evt);
+    int seq = findSeq(evt);
+    oldSeq = seq;
+    startWrapBlock=wrappedBlock;
+
+    if(seq==-1)
+      return;
+
+    SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq);
+
+    if (sequence == null || res > sequence.getLength())
+    {
+      return;
+    }
+
+    stretchGroup = av.getSelectionGroup();
+
+    if (stretchGroup == null)
+    {
+      stretchGroup = av.alignment.findGroup(sequence);
+      if (stretchGroup != null && res > stretchGroup.getStartRes() &&
+          res < stretchGroup.getEndRes())
+      {
+        av.setSelectionGroup(stretchGroup);
+      }
+      else
+      {
+        stretchGroup = null;
+      }
+    }
+
+    else if (!stretchGroup.getSequences(false).contains(sequence)
+             || stretchGroup.getStartRes() > res
+             || stretchGroup.getEndRes() < res)
+    {
+      stretchGroup = null;
+
+      SequenceGroup[] allGroups = av.alignment.findAllGroups(sequence);
+
+      if (allGroups != null)
+      {
+        for (int i = 0; i < allGroups.length; i++)
+        {
+          if (allGroups[i].getStartRes() <= res &&
+              allGroups[i].getEndRes() >= res)
+          {
+            stretchGroup = allGroups[i];
+            break;
+          }
+        }
+      }
+      av.setSelectionGroup(stretchGroup);
+    }
+
+
+    // DETECT RIGHT MOUSE BUTTON IN AWT
+    if ( (evt.getModifiers() & InputEvent.BUTTON3_MASK) ==
+             InputEvent.BUTTON3_MASK)
+    {
+      Vector allFeatures = getAllFeaturesAtRes(sequence,
+                                               sequence.findPosition(res));
+
+      Vector links = null;
+      if(allFeatures!=null)
+      {
+        for (int i = 0; i < allFeatures.size(); i++)
+        {
+          SequenceFeature sf = (SequenceFeature) allFeatures.elementAt(i);
+          if (sf.links != null)
+          {
+            links = new Vector();
+            for (int j = 0; j < sf.links.size(); j++)
+            {
+              links.addElement(sf.links.elementAt(j));
+            }
+          }
+        }
+      }
+      APopupMenu popup = new APopupMenu(ap, null, links);
+      this.add(popup);
+      popup.show(this, evt.getX(), evt.getY());
+      ap.repaint();
+      return;
+    }
+
+    if (av.cursorMode)
+    {
+      seqCanvas.cursorX = findRes(evt);
+      seqCanvas.cursorY = findSeq(evt);
+      seqCanvas.repaint();
+      return;
+    }
+
+      //Only if left mouse button do we want to change group sizes
+
+      if (stretchGroup == null)
+      {
+        // define a new group here
+        SequenceGroup sg = new SequenceGroup();
+        sg.setStartRes(res);
+        sg.setEndRes(res);
+        sg.addSequence(sequence, false);
+        av.setSelectionGroup(sg);
+        stretchGroup = sg;
+
+        if (av.getConservationSelected())
+        {
+          SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(),
+                                            "Background");
+        }
+        if (av.getAbovePIDThreshold())
+        {
+          SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),
+                                         "Background");
+        }
+
+      }
+  }
+
+  public void doMouseReleasedDefineMode(MouseEvent evt)
+  {
+    if (stretchGroup == null)
+    {
+        return;
+    }
+
+    if(stretchGroup.cs!=null)
+    {
+      if (stretchGroup.cs instanceof ClustalxColourScheme)
+      {
+        ( (ClustalxColourScheme) stretchGroup.cs).resetClustalX(
+            stretchGroup.getSequences(true),
+            stretchGroup.getWidth());
+      }
+
+      if (stretchGroup.cs.conservationApplied())
+      {
+        SliderPanel.setConservationSlider(ap, stretchGroup.cs,
+                                          stretchGroup.getName());
+        stretchGroup.recalcConservation();
+      }
+      else
+      {
+        SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,
+                                       stretchGroup.getName());
+      }
+    }
+    changeEndRes = false;
+    changeStartRes = false;
+    stretchGroup = null;
+    PaintRefresher.Refresh(av.alignment);
+    ap.repaint();
+  }
+
+  public void doMouseDraggedDefineMode(MouseEvent evt)
+  {
+    int res = findRes(evt);
+    int y = findSeq(evt);
+
+    if(wrappedBlock!=startWrapBlock)
+      return;
+
+     if (stretchGroup == null)
+     {
+          return;
+     }
+
+     mouseDragging = true;
+
+
+      if(y > av.alignment.getHeight())
+      {
+        y = av.alignment.getHeight() -1;
+      }
+
+      if(res>av.alignment.getWidth())
+        res = av.alignment.getWidth()-1;
+
+      if (stretchGroup.getEndRes() == res)
+      {
+          // Edit end res position of selected group
+          changeEndRes = true;
+      }
+      else if (stretchGroup.getStartRes() == res)
+      {
+          // Edit start res position of selected group
+          changeStartRes = true;
+      }
+
+      if (res < 0)
+      {
+          res = 0;
+      }
+
+      if (changeEndRes)
+      {
+          if (res > (stretchGroup.getStartRes() - 1))
+          {
+              stretchGroup.setEndRes(res);
+          }
+      }
+      else if (changeStartRes)
+      {
+          if (res < (stretchGroup.getEndRes() + 1))
+          {
+              stretchGroup.setStartRes(res);
+          }
+      }
+
+      int dragDirection = 0;
+
+      if (y > oldSeq)
+      {
+          dragDirection = 1;
+      }
+      else if (y < oldSeq)
+      {
+          dragDirection = -1;
+      }
+
+
+      while ((y != oldSeq) && (oldSeq > -1) && (y < av.alignment.getHeight()))
+      {
+          // This routine ensures we don't skip any sequences, as the
+          // selection is quite slow.
+          Sequence seq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);
+
+          oldSeq += dragDirection;
+
+          if(oldSeq<0)
+            break;
+
+          Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);
+
+          if (stretchGroup.getSequences(false).contains(nextSeq))
+          {
+              stretchGroup.deleteSequence(seq, false);
+          }
+          else
+          {
+              if (seq != null)
+              {
+                  stretchGroup.addSequence(seq, false);
+              }
+
+              stretchGroup.addSequence(nextSeq, false);
+          }
+      }
+
+      if(oldSeq < 0)
+        oldSeq = -1;
+
+
+      if(res>av.endRes || res<av.startRes
+          || y<av.startSeq || y>av.endSeq)
+      {
+        mouseExited(evt);
+      }
+
+      if (scrollThread != null)
+      {
+        scrollThread.setEvent(evt);
+      }
+
+      seqCanvas.repaint();
+    }
+
+    public void mouseEntered(MouseEvent e)
+    {
+      if (oldSeq < 0)
+        oldSeq = 0;
+
+      if (scrollThread != null)
+      {
+        scrollThread.running = false;
+        scrollThread = null;
+      }
+    }
+
+  public void mouseExited(MouseEvent e)
+  {
+    if (av.getWrapAlignment())
+    {
+      return;
+    }
+
+    if (mouseDragging && scrollThread==null)
+    {
+      scrollThread = new ScrollThread();
+    }
+  }
+
+  void scrollCanvas(MouseEvent evt)
+  {
+    if(evt==null)
+    {
+      if(scrollThread!=null)
+      {
+        scrollThread.running = false;
+        scrollThread = null;
+      }
+      mouseDragging = false;
+    }
+    else
+    {
+      if (scrollThread == null)
+        scrollThread = new ScrollThread();
+
+      mouseDragging = true;
+      scrollThread.setEvent(evt);
+    }
+
+    }
+
+  // this class allows scrolling off the bottom of the visible alignment
+  class ScrollThread
+      extends Thread
+  {
+    MouseEvent evt;
+    boolean running = false;
+    public ScrollThread()
+    {
+      start();
+    }
+
+    public void setEvent(MouseEvent e)
+    {
+      evt = e;
+    }
+
+    public void stopScrolling()
+    {
+      running = false;
+    }
+
+    public void run()
+    {
+      running = true;
+      while (running)
+      {
+
+        if (evt != null)
+        {
+
+          if (mouseDragging && evt.getY() < 0 && av.getStartSeq() > 0)
+          {
+            running = ap.scrollUp(true);
+          }
+
+          if (mouseDragging && evt.getY() >= getSize().height &&
+              av.alignment.getHeight() > av.getEndSeq())
+          {
+            running = ap.scrollUp(false);
+          }
+
+          if (mouseDragging && evt.getX() < 0)
+          {
+            running = ap.scrollRight(false);
+          }
+
+          else if (mouseDragging && evt.getX() >= getSize().width)
+          {
+            running = ap.scrollRight(true);
+          }
+        }
+
+        try
+        {
+          Thread.sleep(75);
+        }
+        catch (Exception ex)
+        {}
+      }
+    }
+  }
+
+}
index 3f87b02..9546dcb 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-\r
-public class SequenceRenderer\r
-{\r
-  AlignViewport av;\r
-  FontMetrics fm;\r
-  boolean renderGaps = true;\r
-  SequenceGroup currentSequenceGroup = null;\r
-  SequenceGroup[] allGroups = null;\r
-  Color resBoxColour;\r
-  Graphics graphics;\r
-  boolean forOverview = false;\r
-\r
-  public SequenceRenderer(AlignViewport av)\r
-  {\r
-    this.av = av;\r
-  }\r
-\r
-  public void renderGaps(boolean b)\r
-  {\r
-    renderGaps = b;\r
-  }\r
-\r
-  public Color getResidueBoxColour(SequenceI seq, int i)\r
-  {\r
-    allGroups = av.alignment.findAllGroups(seq);\r
-\r
-    if (inCurrentSequenceGroup(i))\r
-    {\r
-      if (currentSequenceGroup.getDisplayBoxes())\r
-      {\r
-        getBoxColour(currentSequenceGroup.cs, seq, i);\r
-      }\r
-    }\r
-    else if (av.getShowBoxes())\r
-    {\r
-        getBoxColour(av.globalColourScheme, seq, i);\r
-    }\r
-\r
-    return resBoxColour;\r
-    }\r
-\r
-  void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)\r
-  {\r
-    if (cs != null)\r
-    {\r
-      resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);\r
-    }\r
-    else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))\r
-    {\r
-        resBoxColour = Color.lightGray;\r
-    }\r
-    else\r
-    {\r
-      resBoxColour = Color.white;\r
-    }\r
-\r
-  }\r
-\r
-  public Color findSequenceColour(SequenceI seq, int i)\r
-  {\r
-    allGroups = av.alignment.findAllGroups(seq);\r
-    drawBoxes(seq, i,i, 0);\r
-    return resBoxColour;\r
-  }\r
-\r
-  public void drawSequence(Graphics g, SequenceI seq, SequenceGroup[] sg,\r
-                           int start, int end,  int y1)\r
-  {\r
-    allGroups = sg;\r
-\r
-    graphics = g;\r
-\r
-    drawBoxes(seq, start, end,  y1);\r
-\r
-    fm = g.getFontMetrics();\r
-    drawText(seq, start, end, y1);\r
-\r
-  }\r
-\r
-  public void drawBoxes(SequenceI seq, int start, int end,  int y1)\r
-  {\r
-    int i = start;\r
-    int length = seq.getLength();\r
-\r
-    int curStart = -1;\r
-    int curWidth = av.charWidth;\r
-\r
-    Color tempColour = null;\r
-    while (i <= end)\r
-    {\r
-      resBoxColour = Color.white;\r
-      if(i < length)\r
-      {\r
-        if (inCurrentSequenceGroup(i))\r
-        {\r
-          if (currentSequenceGroup.getDisplayBoxes())\r
-          {\r
-            getBoxColour(currentSequenceGroup.cs, seq, i);\r
-          }\r
-        }\r
-        else if (av.getShowBoxes())\r
-        {\r
-          getBoxColour(av.getGlobalColourScheme(), seq, i);\r
-        }\r
-      }\r
-\r
-\r
-      if (resBoxColour != tempColour)\r
-      {\r
-        if (tempColour != null)\r
-        {\r
-          graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,\r
-                            av.charHeight);\r
-        }\r
-        graphics.setColor(resBoxColour);\r
-\r
-        curStart = i;\r
-        curWidth = av.charWidth;\r
-        tempColour = resBoxColour;\r
-\r
-      }\r
-      else\r
-      {\r
-        curWidth += av.charWidth;\r
-      }\r
-\r
-      i++;\r
-    }\r
-\r
-    graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, av.charHeight);\r
-  }\r
-\r
-  public void drawText(SequenceI seq, int start, int end, int y1)\r
-  {\r
-\r
-    y1 += av.charHeight - av.charHeight / 5;  // height/5 replaces pady\r
-\r
-    int charOffset = 0;\r
-\r
-    // Need to find the sequence position here.\r
-    if(end+1>=seq.getLength())\r
-          end = seq.getLength()-1;\r
-\r
-    char s = ' ';\r
-\r
-    for (int i = start; i <= end; i++)\r
-    {\r
-      graphics.setColor(Color.black);\r
-\r
-      s = seq.getCharAt(i);\r
-      if (!renderGaps && jalview.util.Comparison.isGap(s))\r
-      {\r
-        continue;\r
-      }\r
-\r
-      if (inCurrentSequenceGroup(i))\r
-      {\r
-        if (!currentSequenceGroup.getDisplayText())\r
-        {\r
-          continue;\r
-        }\r
-\r
-        if (currentSequenceGroup.getColourText())\r
-        {\r
-          getBoxColour(currentSequenceGroup.cs, seq, i);\r
-          graphics.setColor(resBoxColour.darker());\r
-        }\r
-      }\r
-      else\r
-      {\r
-        if (!av.getShowText())\r
-        {\r
-          continue;\r
-        }\r
-\r
-        if (av.getColourText())\r
-        {\r
-          getBoxColour(av.getGlobalColourScheme(), seq, i);\r
-          if (av.getShowBoxes())\r
-          {\r
-            graphics.setColor(resBoxColour.darker());\r
-          }\r
-          else\r
-          {\r
-            graphics.setColor(resBoxColour);\r
-          }\r
-        }\r
-      }\r
-\r
-      charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
-      graphics.drawString(String.valueOf(s),\r
-                         charOffset + av.charWidth * (i - start),\r
-                        y1 );\r
-    }\r
-\r
-  }\r
-\r
-  boolean inCurrentSequenceGroup(int res)\r
-  {\r
-    if (allGroups == null)\r
-    {\r
-      return false;\r
-    }\r
-\r
-    for (int i = 0; i < allGroups.length; i++)\r
-    {\r
-      if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)\r
-      {\r
-        currentSequenceGroup = allGroups[i];\r
-        return true;\r
-      }\r
-    }\r
-\r
-    return false;\r
-  }\r
-\r
-  public void drawHighlightedText(SequenceI seq, int start, int end, int x1,\r
-                                  int y1, int width, int height)\r
-  {\r
-    int pady = height / 5;\r
-    int charOffset = 0;\r
-    graphics.setColor(Color.black);\r
-    graphics.fillRect(x1, y1, width * (end - start + 1), height);\r
-    graphics.setColor(Color.white);\r
-\r
-    char s = '~';\r
-    // Need to find the sequence position here.\r
-    for (int i = start; i <= end; i++)\r
-    {\r
-      if (i < seq.getLength())\r
-      {\r
-        s = seq.getSequence().charAt(i);\r
-      }\r
-\r
-      charOffset = (width - fm.charWidth(s)) / 2;\r
-      graphics.drawString(String.valueOf(s),\r
-                          charOffset + x1 + width * (i - start),\r
-                          y1 + height - pady);\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+public class SequenceRenderer
+{
+  AlignViewport av;
+  FontMetrics fm;
+  boolean renderGaps = true;
+  SequenceGroup currentSequenceGroup = null;
+  SequenceGroup[] allGroups = null;
+  Color resBoxColour;
+  Graphics graphics;
+  boolean forOverview = false;
+
+  public SequenceRenderer(AlignViewport av)
+  {
+    this.av = av;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  public void prepare(Graphics g, boolean renderGaps)
+  {
+      graphics = g;
+      fm = g.getFontMetrics();
+
+      this.renderGaps = renderGaps;
+    }
+
+  public Color getResidueBoxColour(SequenceI seq, int i)
+  {
+    allGroups = av.alignment.findAllGroups(seq);
+
+    if (inCurrentSequenceGroup(i))
+    {
+      if (currentSequenceGroup.getDisplayBoxes())
+      {
+        getBoxColour(currentSequenceGroup.cs, seq, i);
+      }
+    }
+    else if (av.getShowBoxes())
+    {
+        getBoxColour(av.globalColourScheme, seq, i);
+    }
+
+    return resBoxColour;
+    }
+
+  void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)
+  {
+    if (cs != null)
+    {
+      resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);
+    }
+    else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))
+    {
+        resBoxColour = Color.lightGray;
+    }
+    else
+    {
+      resBoxColour = Color.white;
+    }
+
+  }
+
+  public Color findSequenceColour(SequenceI seq, int i)
+  {
+    allGroups = av.alignment.findAllGroups(seq);
+    drawBoxes(seq, i,i, 0);
+    return resBoxColour;
+  }
+
+  public void drawSequence(SequenceI seq, SequenceGroup[] sg,
+                           int start, int end,  int y1)
+  {
+    allGroups = sg;
+
+    drawBoxes(seq, start, end,  y1);
+
+    if(av.validCharWidth)
+    {
+      drawText(seq, start, end, y1);
+    }
+  }
+
+  public void drawBoxes(SequenceI seq, int start, int end,  int y1)
+  {
+    int i = start;
+    int length = seq.getLength();
+
+    int curStart = -1;
+    int curWidth = av.charWidth;
+
+    Color tempColour = null;
+    while (i <= end)
+    {
+      resBoxColour = Color.white;
+      if(i < length)
+      {
+        if (inCurrentSequenceGroup(i))
+        {
+          if (currentSequenceGroup.getDisplayBoxes())
+          {
+            getBoxColour(currentSequenceGroup.cs, seq, i);
+          }
+        }
+        else if (av.getShowBoxes())
+        {
+          getBoxColour(av.getGlobalColourScheme(), seq, i);
+        }
+      }
+
+
+      if (resBoxColour != tempColour)
+      {
+        if (tempColour != null)
+        {
+          graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,
+                            av.charHeight);
+        }
+        graphics.setColor(resBoxColour);
+
+        curStart = i;
+        curWidth = av.charWidth;
+        tempColour = resBoxColour;
+
+      }
+      else
+      {
+        curWidth += av.charWidth;
+      }
+
+      i++;
+    }
+
+    graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, av.charHeight);
+  }
+
+  public void drawText(SequenceI seq, int start, int end, int y1)
+  {
+
+    y1 += av.charHeight - av.charHeight / 5;  // height/5 replaces pady
+
+    int charOffset = 0;
+
+    // Need to find the sequence position here.
+    if(end+1>=seq.getLength())
+          end = seq.getLength()-1;
+
+    char s = ' ';
+
+    for (int i = start; i <= end; i++)
+    {
+      graphics.setColor(Color.black);
+
+      s = seq.getCharAt(i);
+      if (!renderGaps && jalview.util.Comparison.isGap(s))
+      {
+        continue;
+      }
+
+      if (inCurrentSequenceGroup(i))
+      {
+        if (!currentSequenceGroup.getDisplayText())
+        {
+          continue;
+        }
+
+        if (currentSequenceGroup.getColourText())
+        {
+          getBoxColour(currentSequenceGroup.cs, seq, i);
+          graphics.setColor(resBoxColour.darker());
+        }
+      }
+      else
+      {
+        if (!av.getShowText())
+        {
+          continue;
+        }
+
+        if (av.getColourText())
+        {
+          getBoxColour(av.getGlobalColourScheme(), seq, i);
+          if (av.getShowBoxes())
+          {
+            graphics.setColor(resBoxColour.darker());
+          }
+          else
+          {
+            graphics.setColor(resBoxColour);
+          }
+        }
+      }
+
+      charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+      graphics.drawString(String.valueOf(s),
+                         charOffset + av.charWidth * (i - start),
+                        y1 );
+    }
+
+  }
+
+  boolean inCurrentSequenceGroup(int res)
+  {
+    if (allGroups == null)
+    {
+      return false;
+    }
+
+    for (int i = 0; i < allGroups.length; i++)
+    {
+      if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)
+      {
+        currentSequenceGroup = allGroups[i];
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1)
+  {
+    int pady = av.charHeight / 5;
+    int charOffset = 0;
+    graphics.setColor(Color.black);
+    graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), av.charHeight);
+    graphics.setColor(Color.white);
+
+    char s = '~';
+    // Need to find the sequence position here.
+    if(av.validCharWidth)
+    {
+      for (int i = start; i <= end; i++)
+      {
+        if (i < seq.getLength())
+        {
+          s = seq.getSequence().charAt(i);
+        }
+
+        charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+        graphics.drawString(String.valueOf(s),
+                            charOffset + x1 + av.charWidth * (i - start),
+                            y1 + av.charHeight - pady);
+      }
+    }
+  }
+
+  public void drawCursor(SequenceI seq, int res, int x1, int y1)
+  {
+    int pady = av.charHeight / 5;
+    int charOffset = 0;
+    graphics.setColor(Color.black);
+    graphics.fillRect(x1, y1, av.charWidth, av.charHeight);
+    graphics.setColor(Color.white);
+
+    graphics.setColor(Color.white);
+
+    char s = seq.getCharAt(res);
+    if (av.validCharWidth)
+    {
+
+      charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+      graphics.drawString(String.valueOf(s),
+                          charOffset + x1,
+                          (y1 + av.charHeight) - pady);
+    }
+    }
+
+}
index c343df9..450bf29 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-\r
-public class SliderPanel extends Panel implements ActionListener, AdjustmentListener\r
-{\r
-  AlignmentPanel ap;\r
-  boolean forConservation = true;\r
-  ColourSchemeI cs;\r
-\r
-  static Frame conservationSlider;\r
-  static Frame PIDSlider;\r
-\r
-  public static int setConservationSlider(AlignmentPanel ap, ColourSchemeI cs,\r
-                                          String source)\r
-  {\r
-    SliderPanel sp = null;\r
-\r
-    if (conservationSlider == null)\r
-    {\r
-      sp = new SliderPanel(ap, cs.getConservationInc(), true, cs);\r
-      conservationSlider = new Frame();\r
-      conservationSlider.add(sp);\r
-    }\r
-    else\r
-    {\r
-      sp = (SliderPanel) conservationSlider.getComponent(0);\r
-      sp.cs = cs;\r
-    }\r
-\r
-    conservationSlider.setTitle("Conservation Colour Increment  (" + source +\r
-                                ")");\r
-    if (ap.av.alignment.getGroups() != null)\r
-    {\r
-      sp.setAllGroupsCheckEnabled(true);\r
-    }\r
-    else\r
-    {\r
-      sp.setAllGroupsCheckEnabled(false);\r
-    }\r
-\r
-    return sp.getValue();\r
-  }\r
-\r
-  public static void showConservationSlider()\r
-  {\r
-    try\r
-    {\r
-      PIDSlider.setVisible(false);\r
-      PIDSlider = null;\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-\r
-    if (!conservationSlider.isVisible())\r
-    {\r
-      jalview.bin.JalviewLite.addFrame(conservationSlider,\r
-                                       conservationSlider.getTitle(), 420, 100);\r
-      conservationSlider.addWindowListener(new WindowAdapter()\r
-      {\r
-        public void windowClosing(WindowEvent e)\r
-        {\r
-          conservationSlider = null;\r
-        }\r
-      });\r
-\r
-    }\r
-\r
-  }\r
-\r
-  public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs,\r
-                                       String source)\r
-  {\r
-    SliderPanel pid = null;\r
-    if (PIDSlider == null)\r
-    {\r
-      pid = new SliderPanel(ap, 50, false, cs);\r
-      PIDSlider = new Frame();\r
-      PIDSlider.add(pid);\r
-    }\r
-    else\r
-    {\r
-      pid = (SliderPanel) PIDSlider.getComponent(0);\r
-      pid.cs = cs;\r
-    }\r
-    PIDSlider.setTitle("Percentage Identity Threshold (" + source + ")");\r
-\r
-    if (ap.av.alignment.getGroups() != null)\r
-    {\r
-      pid.setAllGroupsCheckEnabled(true);\r
-    }\r
-    else\r
-    {\r
-      pid.setAllGroupsCheckEnabled(false);\r
-    }\r
-\r
-    return pid.getValue();\r
-\r
-  }\r
-\r
-  public static void showPIDSlider()\r
-  {\r
-    try\r
-    {\r
-      conservationSlider.setVisible(false);\r
-      conservationSlider = null;\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-\r
-    if (!PIDSlider.isVisible())\r
-    {\r
-      jalview.bin.JalviewLite.addFrame(PIDSlider, PIDSlider.getTitle(), 420,\r
-                                       100);\r
-      PIDSlider.addWindowListener(new WindowAdapter()\r
-      {\r
-        public void windowClosing(WindowEvent e)\r
-        {\r
-          PIDSlider = null;\r
-        }\r
-      });\r
-    }\r
-\r
-  }\r
-\r
-  public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,\r
-                     ColourSchemeI cs)\r
-  {\r
-    try {\r
-        jbInit();\r
-    } catch (Exception e) {\r
-        e.printStackTrace();\r
-      }\r
-    this.ap = ap;\r
-    this.cs = cs;\r
-    forConservation = forConserve;\r
-    undoButton.setVisible(false);\r
-    applyButton.setVisible(false);\r
-    if (forConservation)\r
-    {\r
-      label.setText("Modify conservation visibility");\r
-      slider.setMinimum(0);\r
-      slider.setMaximum(50 + slider.getVisibleAmount());\r
-      slider.setUnitIncrement(1);\r
-    }\r
-    else\r
-    {\r
-      label.setText("Colour residues above % occurence");\r
-      slider.setMinimum(0);\r
-      slider.setMaximum(100 + slider.getVisibleAmount());\r
-      slider.setBlockIncrement(1);\r
-    }\r
-\r
-    slider.addAdjustmentListener(this);\r
-\r
-    slider.setValue(value);\r
-    valueField.setText(value + "");\r
-  }\r
-\r
-  public void valueChanged(int i)\r
-  {\r
-    if (cs == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    ColourSchemeI toChange = null;\r
-    Vector allGroups = null;\r
-    int groupIndex = 0;\r
-\r
-    if (allGroupsCheck.getState())\r
-    {\r
-      allGroups = ap.av.alignment.getGroups();\r
-      groupIndex = allGroups.size() - 1;\r
-    }\r
-    else\r
-    {\r
-      toChange = cs;\r
-    }\r
-\r
-    while (groupIndex > -1)\r
-    {\r
-      if (allGroups != null)\r
-      {\r
-        toChange = ( (SequenceGroup) allGroups.elementAt(groupIndex)).cs;\r
-      }\r
-\r
-      if (forConservation)\r
-      {\r
-        toChange.setConservationInc(i);\r
-      }\r
-      else\r
-      {\r
-        toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus());\r
-      }\r
-\r
-      groupIndex--;\r
-    }\r
-\r
-    ap.seqPanel.seqCanvas.repaint();\r
-\r
-  }\r
-\r
-  public void setAllGroupsCheckEnabled(boolean b)\r
-  {\r
-    allGroupsCheck.setEnabled(b);\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==applyButton)\r
-      applyButton_actionPerformed();\r
-    else if(evt.getSource()==undoButton)\r
-      undoButton_actionPerformed();\r
-    else if(evt.getSource()==valueField)\r
-      valueField_actionPerformed();\r
-  }\r
-\r
-  public void adjustmentValueChanged(AdjustmentEvent evt)\r
-  {\r
-    valueField.setText(slider.getValue() + "");\r
-    valueChanged(slider.getValue());\r
-  }\r
-\r
-\r
-  public void valueField_actionPerformed()\r
-  {\r
-    try\r
-    {\r
-      int i = Integer.parseInt(valueField.getText());\r
-      slider.setValue(i);\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      valueField.setText(slider.getValue() + "");\r
-    }\r
-  }\r
-\r
-  public void setValue(int value)\r
-  {\r
-    slider.setValue(value);\r
-  }\r
-\r
-  public int getValue()\r
-  {\r
-    return Integer.parseInt(valueField.getText());\r
-  }\r
-\r
-  // this is used for conservation colours, PID colours and redundancy threshold\r
-  protected Scrollbar slider = new Scrollbar();\r
-  protected TextField valueField = new TextField();\r
-  protected Label label = new Label();\r
-  Panel jPanel1 = new Panel();\r
-  Panel jPanel2 = new Panel();\r
-  protected Button applyButton = new Button();\r
-  protected Button undoButton = new Button();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  protected Checkbox allGroupsCheck = new Checkbox();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  BorderLayout borderLayout2 = new BorderLayout();\r
-  FlowLayout flowLayout2 = new FlowLayout();\r
-\r
-  private void jbInit() throws Exception {\r
-      this.setLayout(borderLayout2);\r
-\r
-      // slider.setMajorTickSpacing(10);\r
-      //  slider.setMinorTickSpacing(1);\r
-      //  slider.setPaintTicks(true);\r
-      slider.setBackground(Color.white);\r
-      slider.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      slider.setOrientation(0);\r
-      valueField.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      valueField.setText("      ");\r
-      valueField.addActionListener(this);\r
-      label.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      label.setText("set this label text");\r
-      jPanel1.setLayout(borderLayout1);\r
-      jPanel2.setLayout(flowLayout1);\r
-      applyButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      applyButton.setLabel("Apply");\r
-      applyButton.addActionListener(this);\r
-      undoButton.setEnabled(false);\r
-      undoButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      undoButton.setLabel("Undo");\r
-      undoButton.addActionListener(this);\r
-      allGroupsCheck.setEnabled(false);\r
-      allGroupsCheck.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      allGroupsCheck.setLabel("Apply threshold to all groups");\r
-      allGroupsCheck.setName("Apply to all Groups");\r
-      this.setBackground(Color.white);\r
-      this.setForeground(Color.black);\r
-      jPanel2.add(label, null);\r
-      jPanel2.add(applyButton, null);\r
-      jPanel2.add(undoButton, null);\r
-      jPanel2.add(allGroupsCheck);\r
-      jPanel1.add(valueField, java.awt.BorderLayout.EAST);\r
-      jPanel1.add(slider, java.awt.BorderLayout.CENTER);\r
-      this.add(jPanel1, java.awt.BorderLayout.SOUTH);\r
-      this.add(jPanel2, java.awt.BorderLayout.CENTER);\r
-  }\r
-\r
-  protected void applyButton_actionPerformed()\r
-  {\r
-  }\r
-\r
-  protected void undoButton_actionPerformed()\r
-  {\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+public class SliderPanel extends Panel
+    implements ActionListener,
+    AdjustmentListener,
+    MouseListener
+{
+  AlignmentPanel ap;
+  boolean forConservation = true;
+  ColourSchemeI cs;
+
+  static Frame conservationSlider;
+  static Frame PIDSlider;
+
+  public static int setConservationSlider(AlignmentPanel ap, ColourSchemeI cs,
+                                          String source)
+  {
+    SliderPanel sp = null;
+
+    if (conservationSlider == null)
+    {
+      sp = new SliderPanel(ap, cs.getConservationInc(), true, cs);
+      conservationSlider = new Frame();
+      conservationSlider.add(sp);
+    }
+    else
+    {
+      sp = (SliderPanel) conservationSlider.getComponent(0);
+      sp.cs = cs;
+    }
+
+    conservationSlider.setTitle("Conservation Colour Increment  (" + source +
+                                ")");
+    if (ap.av.alignment.getGroups() != null)
+    {
+      sp.setAllGroupsCheckEnabled(true);
+    }
+    else
+    {
+      sp.setAllGroupsCheckEnabled(false);
+    }
+
+    return sp.getValue();
+  }
+
+  public static void showConservationSlider()
+  {
+    try
+    {
+      PIDSlider.setVisible(false);
+      PIDSlider = null;
+    }
+    catch (Exception ex)
+    {}
+
+    if (!conservationSlider.isVisible())
+    {
+      jalview.bin.JalviewLite.addFrame(conservationSlider,
+                                       conservationSlider.getTitle(), 420, 100);
+      conservationSlider.addWindowListener(new WindowAdapter()
+      {
+        public void windowClosing(WindowEvent e)
+        {
+          conservationSlider = null;
+        }
+      });
+
+    }
+
+  }
+
+  public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs,
+                                       String source)
+  {
+    SliderPanel pid = null;
+    if (PIDSlider == null)
+    {
+      pid = new SliderPanel(ap, 50, false, cs);
+      PIDSlider = new Frame();
+      PIDSlider.add(pid);
+    }
+    else
+    {
+      pid = (SliderPanel) PIDSlider.getComponent(0);
+      pid.cs = cs;
+    }
+    PIDSlider.setTitle("Percentage Identity Threshold (" + source + ")");
+
+    if (ap.av.alignment.getGroups() != null)
+    {
+      pid.setAllGroupsCheckEnabled(true);
+    }
+    else
+    {
+      pid.setAllGroupsCheckEnabled(false);
+    }
+
+    return pid.getValue();
+
+  }
+
+  public static void showPIDSlider()
+  {
+    try
+    {
+      conservationSlider.setVisible(false);
+      conservationSlider = null;
+    }
+    catch (Exception ex)
+    {}
+
+    if (!PIDSlider.isVisible())
+    {
+      jalview.bin.JalviewLite.addFrame(PIDSlider, PIDSlider.getTitle(), 420,
+                                       100);
+      PIDSlider.addWindowListener(new WindowAdapter()
+      {
+        public void windowClosing(WindowEvent e)
+        {
+          PIDSlider = null;
+        }
+      });
+    }
+
+  }
+
+  public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,
+                     ColourSchemeI cs)
+  {
+    try {
+        jbInit();
+    } catch (Exception e) {
+        e.printStackTrace();
+      }
+    this.ap = ap;
+    this.cs = cs;
+    forConservation = forConserve;
+    undoButton.setVisible(false);
+    applyButton.setVisible(false);
+    if (forConservation)
+    {
+      label.setText("Modify conservation visibility");
+      slider.setMinimum(0);
+      slider.setMaximum(50 + slider.getVisibleAmount());
+      slider.setUnitIncrement(1);
+    }
+    else
+    {
+      label.setText("Colour residues above % occurence");
+      slider.setMinimum(0);
+      slider.setMaximum(100 + slider.getVisibleAmount());
+      slider.setBlockIncrement(1);
+    }
+
+    slider.addAdjustmentListener(this);
+    slider.addMouseListener(this);
+
+    slider.setValue(value);
+    valueField.setText(value + "");
+  }
+
+  public void valueChanged(int i)
+  {
+    if (cs == null)
+    {
+      return;
+    }
+
+    ColourSchemeI toChange = null;
+    Vector allGroups = null;
+    int groupIndex = 0;
+
+    if (allGroupsCheck.getState())
+    {
+      allGroups = ap.av.alignment.getGroups();
+      groupIndex = allGroups.size() - 1;
+    }
+    else
+    {
+      toChange = cs;
+    }
+
+    while (groupIndex > -1)
+    {
+      if (allGroups != null)
+      {
+        toChange = ( (SequenceGroup) allGroups.elementAt(groupIndex)).cs;
+      }
+
+      if (forConservation)
+      {
+        toChange.setConservationInc(i);
+      }
+      else
+      {
+        toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus());
+      }
+
+      groupIndex--;
+    }
+
+    ap.seqPanel.seqCanvas.repaint();
+
+  }
+
+  public void setAllGroupsCheckEnabled(boolean b)
+  {
+    allGroupsCheck.setEnabled(b);
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==applyButton)
+      applyButton_actionPerformed();
+    else if(evt.getSource()==undoButton)
+      undoButton_actionPerformed();
+    else if(evt.getSource()==valueField)
+      valueField_actionPerformed();
+  }
+
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+    valueField.setText(slider.getValue() + "");
+    valueChanged(slider.getValue());
+  }
+
+
+  public void valueField_actionPerformed()
+  {
+    try
+    {
+      int i = Integer.parseInt(valueField.getText());
+      slider.setValue(i);
+    }
+    catch (Exception ex)
+    {
+      valueField.setText(slider.getValue() + "");
+    }
+  }
+
+  public void setValue(int value)
+  {
+    slider.setValue(value);
+  }
+
+  public int getValue()
+  {
+    return Integer.parseInt(valueField.getText());
+  }
+
+  // this is used for conservation colours, PID colours and redundancy threshold
+  protected Scrollbar slider = new Scrollbar();
+  protected TextField valueField = new TextField();
+  protected Label label = new Label();
+  Panel jPanel1 = new Panel();
+  Panel jPanel2 = new Panel();
+  protected Button applyButton = new Button();
+  protected Button undoButton = new Button();
+  FlowLayout flowLayout1 = new FlowLayout();
+  protected Checkbox allGroupsCheck = new Checkbox();
+  BorderLayout borderLayout1 = new BorderLayout();
+  BorderLayout borderLayout2 = new BorderLayout();
+  FlowLayout flowLayout2 = new FlowLayout();
+
+  private void jbInit() throws Exception {
+      this.setLayout(borderLayout2);
+
+      // slider.setMajorTickSpacing(10);
+      //  slider.setMinorTickSpacing(1);
+      //  slider.setPaintTicks(true);
+      slider.setBackground(Color.white);
+      slider.setFont(new java.awt.Font("Verdana", 0, 11));
+      slider.setOrientation(0);
+      valueField.setFont(new java.awt.Font("Verdana", 0, 11));
+      valueField.setText("      ");
+      valueField.addActionListener(this);
+      label.setFont(new java.awt.Font("Verdana", 0, 11));
+      label.setText("set this label text");
+      jPanel1.setLayout(borderLayout1);
+      jPanel2.setLayout(flowLayout1);
+      applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
+      applyButton.setLabel("Apply");
+      applyButton.addActionListener(this);
+      undoButton.setEnabled(false);
+      undoButton.setFont(new java.awt.Font("Verdana", 0, 11));
+      undoButton.setLabel("Undo");
+      undoButton.addActionListener(this);
+      allGroupsCheck.setEnabled(false);
+      allGroupsCheck.setFont(new java.awt.Font("Verdana", 0, 11));
+      allGroupsCheck.setLabel("Apply threshold to all groups");
+      allGroupsCheck.setName("Apply to all Groups");
+      this.setBackground(Color.white);
+      this.setForeground(Color.black);
+      jPanel2.add(label, null);
+      jPanel2.add(applyButton, null);
+      jPanel2.add(undoButton, null);
+      jPanel2.add(allGroupsCheck);
+      jPanel1.add(valueField, java.awt.BorderLayout.EAST);
+      jPanel1.add(slider, java.awt.BorderLayout.CENTER);
+      this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+      this.add(jPanel2, java.awt.BorderLayout.CENTER);
+  }
+
+  protected void applyButton_actionPerformed()
+  { }
+
+  protected void undoButton_actionPerformed()
+  { }
+
+  public void mousePressed(MouseEvent evt)
+  { }
+
+  public void mouseReleased(MouseEvent evt)
+  {
+    if (ap.overviewPanel != null)
+      ap.overviewPanel.updateOverviewImage();
+  }
+  public void mouseClicked(MouseEvent evt)
+  {}
+  public void mouseEntered(MouseEvent evt)
+  {}
+  public void mouseExited(MouseEvent evt)
+  {}
+}
index e3f6c3c..23a5021 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-import jalview.util.*;\r
-\r
-public class TreeCanvas\r
-    extends Panel implements MouseListener\r
-{\r
-  NJTree tree;\r
-  ScrollPane scrollPane;\r
-  AlignViewport av;\r
-  public static final String PLACEHOLDER = " * ";\r
-  Font font;\r
-  boolean fitToWindow = true;\r
-  boolean showDistances = false;\r
-  boolean showBootstrap = false;\r
-  boolean markPlaceholders = false;\r
-\r
-  int offx = 20;\r
-  int offy;\r
-\r
-  float threshold;\r
-\r
-  String longestName;\r
-  int labelLength = -1;\r
-\r
-  //RubberbandRectangle rubberband;\r
-\r
-  Vector listeners;\r
-\r
-  Hashtable nameHash = new Hashtable();\r
-  Hashtable nodeHash = new Hashtable();\r
-\r
-  public TreeCanvas(AlignViewport av, ScrollPane scroller)\r
-  {\r
-    this.av = av;\r
-    font = av.getFont();\r
-    scrollPane = scroller;\r
-    addMouseListener(this);\r
-    setLayout(null);\r
-\r
-    PaintRefresher.Register(this, av.alignment);\r
-  }\r
-\r
-  public void TreeSelectionChanged(Sequence sequence)\r
-  {\r
-    SequenceGroup selected = av.getSelectionGroup();\r
-    if (selected == null)\r
-    {\r
-      selected = new SequenceGroup();\r
-      av.setSelectionGroup(selected);\r
-    }\r
-\r
-    selected.setEndRes(av.alignment.getWidth()-1);\r
-    selected.addOrRemove(sequence, true);\r
-\r
-    PaintRefresher.Refresh(this, av.alignment);\r
-    repaint();\r
-  }\r
-\r
-  public void setTree(NJTree tree)\r
-  {\r
-    this.tree = tree;\r
-    tree.findHeight(tree.getTopNode());\r
-\r
-    // Now have to calculate longest name based on the leaves\r
-    Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());\r
-    boolean has_placeholders = false;\r
-    longestName = "";\r
-\r
-    for (int i = 0; i < leaves.size(); i++)\r
-    {\r
-      SequenceNode lf = (SequenceNode) leaves.elementAt(i);\r
-\r
-      if (lf.isPlaceholder())\r
-      {\r
-        has_placeholders = true;\r
-      }\r
-\r
-      if (longestName.length() < ( (Sequence) lf.element()).getName()\r
-          .length())\r
-      {\r
-        longestName = TreeCanvas.PLACEHOLDER +\r
-            ( (Sequence) lf.element()).getName();\r
-      }\r
-    }\r
-\r
-    setMarkPlaceholders(has_placeholders);\r
-  }\r
-\r
-  public void drawNode(Graphics g, SequenceNode node, float chunk, float scale,\r
-                       int width, int offx, int offy)\r
-  {\r
-    if (node == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (node.left() == null && node.right() == null)\r
-    {\r
-      // Drawing leaf node\r
-\r
-      float height = node.height;\r
-      float dist = node.dist;\r
-\r
-      int xstart = (int) ( (height - dist) * scale) + offx;\r
-      int xend = (int) (height * scale) + offx;\r
-\r
-      int ypos = (int) (node.ycount * chunk) + offy;\r
-\r
-      if (node.element() instanceof SequenceI)\r
-      {\r
-        if ( ( (SequenceI) ( (SequenceNode) node).element()).getColor() ==\r
-            Color.white)\r
-        {\r
-          g.setColor(Color.black);\r
-        }\r
-        else\r
-        {\r
-          g.setColor( ( (SequenceI) ( (SequenceNode) node).element()).getColor().\r
-                     darker());\r
-        }\r
-\r
-      }\r
-      else\r
-      {\r
-        g.setColor(Color.black);\r
-      }\r
-\r
-      // Draw horizontal line\r
-      g.drawLine(xstart, ypos, xend, ypos);\r
-\r
-      String nodeLabel = "";\r
-      if (showDistances && node.dist > 0)\r
-      {\r
-        nodeLabel = new Format("%-.2f").form(node.dist);\r
-      }\r
-      if (showBootstrap)\r
-      {\r
-        if (showDistances)\r
-        {\r
-          nodeLabel = nodeLabel + " : ";\r
-        }\r
-        nodeLabel = nodeLabel + String.valueOf(node.getBootstrap());\r
-      }\r
-      if (!nodeLabel.equals(""))\r
-      {\r
-        g.drawString(nodeLabel, xstart+2, ypos - 2);\r
-      }\r
-\r
-      String name = (markPlaceholders && node.isPlaceholder()) ?\r
-          (PLACEHOLDER + node.getName()) : node.getName();\r
-      FontMetrics fm = g.getFontMetrics(font);\r
-      int charWidth = fm.stringWidth(name) + 3;\r
-      int charHeight = fm.getHeight();\r
-\r
-      Rectangle rect = new Rectangle(xend + 10, ypos - charHeight,\r
-                                     charWidth, charHeight);\r
-\r
-      nameHash.put( (SequenceI) node.element(), rect);\r
-\r
-      // Colour selected leaves differently\r
-      SequenceGroup selected = av.getSelectionGroup();\r
-      if (selected != null &&\r
-          selected.sequences.contains( (SequenceI) node.element()))\r
-      {\r
-        g.setColor(Color.gray);\r
-\r
-        g.fillRect(xend + 10, ypos - charHeight + 3, charWidth, charHeight);\r
-        g.setColor(Color.white);\r
-      }\r
-      g.drawString(name, xend + 10, ypos);\r
-      g.setColor(Color.black);\r
-    }\r
-    else\r
-    {\r
-      drawNode(g, (SequenceNode) node.left(), chunk, scale, width, offx, offy);\r
-      drawNode(g, (SequenceNode) node.right(), chunk, scale, width, offx, offy);\r
-\r
-      float height = node.height;\r
-      float dist = node.dist;\r
-\r
-      int xstart = (int) ( (height - dist) * scale) + offx;\r
-      int xend = (int) (height * scale) + offx;\r
-      int ypos = (int) (node.ycount * chunk) + offy;\r
-\r
-      g.setColor( ( (SequenceNode) node).color.darker());\r
-\r
-      // Draw horizontal line\r
-      g.drawLine(xstart, ypos, xend, ypos);\r
-      g.fillRect(xend - 2, ypos - 2, 4, 4);\r
-\r
-      int ystart = (int) ( ( (SequenceNode) node.left()).ycount * chunk) + offy;\r
-      int yend = (int) ( ( (SequenceNode) node.right()).ycount * chunk) + offy;\r
-\r
-      Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);\r
-      nodeHash.put(node, pos);\r
-\r
-      g.drawLine( (int) (height * scale) + offx, ystart,\r
-                 (int) (height * scale) + offx, yend);\r
-\r
-      if (showDistances && node.dist > 0)\r
-      {\r
-        g.drawString(new Format("%-.2f").form(node.dist), xstart+2, ypos - 2);\r
-      }\r
-\r
-    }\r
-  }\r
-\r
-  public Object findElement(int x, int y)\r
-  {\r
-    Enumeration keys = nameHash.keys();\r
-\r
-    while (keys.hasMoreElements())\r
-    {\r
-      Object ob = keys.nextElement();\r
-      Rectangle rect = (Rectangle) nameHash.get(ob);\r
-\r
-      if (x >= rect.x && x <= (rect.x + rect.width) &&\r
-          y >= rect.y && y <= (rect.y + rect.height))\r
-      {\r
-        return ob;\r
-      }\r
-    }\r
-    keys = nodeHash.keys();\r
-\r
-    while (keys.hasMoreElements())\r
-    {\r
-      Object ob = keys.nextElement();\r
-      Rectangle rect = (Rectangle) nodeHash.get(ob);\r
-\r
-      if (x >= rect.x && x <= (rect.x + rect.width) &&\r
-          y >= rect.y && y <= (rect.y + rect.height))\r
-      {\r
-        return ob;\r
-      }\r
-    }\r
-    return null;\r
-\r
-  }\r
-\r
-  public void pickNodes(Rectangle pickBox)\r
-  {\r
-    int width = getSize().width;\r
-    int height = getSize().height;\r
-\r
-    SequenceNode top = tree.getTopNode();\r
-\r
-    float wscale = (float) (width * .8 - offx * 2) / tree.getMaxHeight()\r
-        ;\r
-    if (top.count == 0)\r
-    {\r
-      top.count = ( (SequenceNode) top.left()).count +\r
-          ( (SequenceNode) top.right()).count;\r
-    }\r
-    float chunk = (float) (height - offy) / top.count;\r
-\r
-    pickNode(pickBox, top, chunk, wscale, width, offx, offy);\r
-  }\r
-\r
-  public void pickNode(Rectangle pickBox, SequenceNode node, float chunk,\r
-                       float scale, int width, int offx, int offy)\r
-  {\r
-    if (node == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (node.left() == null && node.right() == null)\r
-    {\r
-      float height = node.height;\r
-      //float dist = node.dist;\r
-\r
-      //int xstart = (int) ( (height - dist) * scale) + offx;\r
-      int xend = (int) (height * scale) + offx;\r
-\r
-      int ypos = (int) (node.ycount * chunk) + offy;\r
-\r
-      if (pickBox.contains(new Point(xend, ypos)))\r
-      {\r
-        if (node.element() instanceof SequenceI)\r
-        {\r
-          SequenceI seq = (SequenceI) node.element();\r
-          SequenceGroup sg = av.getSelectionGroup();\r
-          if (sg != null)\r
-          {\r
-            sg.addOrRemove(seq, true);\r
-          }\r
-        }\r
-      }\r
-    }\r
-    else\r
-    {\r
-      pickNode(pickBox, (SequenceNode) node.left(), chunk, scale, width, offx,\r
-               offy);\r
-      pickNode(pickBox, (SequenceNode) node.right(), chunk, scale, width, offx,\r
-               offy);\r
-    }\r
-  }\r
-\r
-  public void setColor(SequenceNode node, Color c)\r
-  {\r
-    if (node == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (node.left() == null && node.right() == null)\r
-    {\r
-      node.color = c;\r
-\r
-      if (node.element() instanceof SequenceI)\r
-      {\r
-        ( (SequenceI) node.element()).setColor(c);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      node.color = c;\r
-      setColor( (SequenceNode) node.left(), c);\r
-      setColor( (SequenceNode) node.right(), c);\r
-    }\r
-  }\r
-\r
-  public void paint(Graphics g)\r
-  {\r
-\r
-    if(tree==null)\r
-      return;\r
-\r
-    g.setFont(font);\r
-\r
-\r
-    FontMetrics fm = g.getFontMetrics(font);\r
-\r
-    if (nameHash.size() == 0)\r
-    {\r
-      repaint();\r
-    }\r
-\r
-    if (fitToWindow ||\r
-        (!fitToWindow &&\r
-         scrollPane.getSize().height > fm.getHeight() * nameHash.size() + offy))\r
-    {\r
-      draw(g, scrollPane.getSize().width, scrollPane.getSize().height);\r
-    }\r
-    else\r
-    {\r
-      setSize(new Dimension(scrollPane.getSize().width,\r
-                            fm.getHeight() * nameHash.size()));\r
-      draw(g, scrollPane.getSize().width, fm.getHeight() * nameHash.size());\r
-    }\r
-\r
-    scrollPane.validate();\r
-  }\r
-\r
-\r
-  public void draw(Graphics g, int width, int height)\r
-  {\r
-    offy = font.getSize()+10;\r
-\r
-    g.setColor(Color.white);\r
-    g.fillRect(0, 0, width, height);\r
-\r
-    labelLength = g.getFontMetrics(font).stringWidth(longestName) + 20; //20 allows for scrollbar\r
-\r
-    float wscale = (float) (width - labelLength - offx * 2) / tree.getMaxHeight();\r
-\r
-    SequenceNode top = tree.getTopNode();\r
-\r
-    if (top.count == 0)\r
-    {\r
-      top.count = ( (SequenceNode) top.left()).count +\r
-          ( (SequenceNode) top.right()).count;\r
-    }\r
-    float chunk = (float) (height - offy) / top.count;\r
-\r
-    drawNode(g, tree.getTopNode(), chunk, wscale, width, offx, offy);\r
-\r
-    if (threshold != 0)\r
-    {\r
-      if (av.getCurrentTree() == tree)\r
-      {\r
-        g.setColor(Color.red);\r
-      }\r
-      else\r
-      {\r
-        g.setColor(Color.gray);\r
-      }\r
-\r
-      int x = (int) (threshold *\r
-                     (float) (getSize().width - labelLength - 2 * offx) + offx);\r
-\r
-      g.drawLine(x, 0, x, getSize().height);\r
-    }\r
-\r
-  }\r
-\r
-  public void mouseReleased(MouseEvent e)\r
-  {}\r
-\r
-  public void mouseEntered(MouseEvent e)\r
-  {}\r
-\r
-  public void mouseExited(MouseEvent e)\r
-  {}\r
-\r
-  public void mouseClicked(MouseEvent e)\r
-  {\r
-  }\r
-\r
-  public void mousePressed(MouseEvent e)\r
-  {\r
-    av.setCurrentTree(tree);\r
-\r
-    int x = e.getX();\r
-    int y = e.getY();\r
-\r
-    Object ob = findElement(x, y);\r
-\r
-    if (ob instanceof SequenceI)\r
-    {\r
-      TreeSelectionChanged( (Sequence) ob);\r
-      repaint();\r
-      return;\r
-\r
-    }\r
-    else if (ob instanceof SequenceNode)\r
-    {\r
-      SequenceNode tmpnode = (SequenceNode) ob;\r
-      tree.swapNodes(tmpnode);\r
-      tree.reCount(tree.getTopNode());\r
-      tree.findHeight(tree.getTopNode());\r
-    }\r
-    else\r
-    {\r
-      // Find threshold\r
-\r
-      if (tree.getMaxHeight() != 0)\r
-      {\r
-        threshold = (float) (x - offx) /\r
-            (float) (getSize().width - labelLength - 2 * offx);\r
-\r
-        tree.getGroups().removeAllElements();\r
-        tree.groupNodes(tree.getTopNode(), threshold);\r
-        setColor(tree.getTopNode(), Color.black);\r
-\r
-        av.setSelectionGroup(null);\r
-        av.alignment.deleteAllGroups();\r
-\r
-        for (int i = 0; i < tree.getGroups().size(); i++)\r
-        {\r
-\r
-          Color col = new Color( (int) (Math.random() * 255),\r
-                                (int) (Math.random() * 255),\r
-                                (int) (Math.random() * 255));\r
-          setColor( (SequenceNode) tree.getGroups().elementAt(i), col.brighter());\r
-\r
-          Vector l = tree.findLeaves( (SequenceNode) tree.getGroups().elementAt(\r
-              i), new Vector());\r
-\r
-          Vector sequences = new Vector();\r
-          for (int j = 0; j < l.size(); j++)\r
-          {\r
-            SequenceI s1 = (SequenceI) ( (SequenceNode) l.elementAt(j)).element();\r
-            if(!sequences.contains(s1))\r
-              sequences.addElement(s1);\r
-          }\r
-\r
-          ColourSchemeI cs = null;\r
-\r
-          if (av.getGlobalColourScheme() != null)\r
-          {\r
-            if (av.getGlobalColourScheme() instanceof UserColourScheme)\r
-            {\r
-              cs = new UserColourScheme(\r
-                  ( (UserColourScheme) av.getGlobalColourScheme()).getColours());\r
-\r
-            }\r
-            else\r
-              cs = ColourSchemeProperty.getColour(sequences,\r
-                                                  av.alignment.getWidth(),\r
-                                                  ColourSchemeProperty.getColourName(\r
-                                                      av.getGlobalColourScheme()));\r
-\r
-              cs.setThreshold(av.getGlobalColourScheme().getThreshold(),\r
-                                                   av.getIgnoreGapsConsensus());\r
-          }\r
-\r
-          SequenceGroup sg = new SequenceGroup(sequences, "TreeGroup",\r
-                                               cs, true, true,\r
-                                               false, 0, av.alignment.getWidth()-1);\r
-\r
-\r
-          if (  av.getGlobalColourScheme()!=null\r
-             && av.getGlobalColourScheme().conservationApplied())\r
-            {\r
-            Conservation c = new Conservation("Group",\r
-                                              ResidueProperties.propHash, 3,\r
-                                              sg.sequences, sg.getStartRes(),\r
-                                              sg.getEndRes());\r
-\r
-            c.calculate();\r
-            c.verdict(false, av.ConsPercGaps);\r
-            cs.setConservation(c);\r
-\r
-            sg.cs = cs;\r
-\r
-          }\r
-\r
-          av.alignment.addGroup(sg);\r
-\r
-        }\r
-      }\r
-    }\r
-\r
-    PaintRefresher.Refresh(this, av.alignment);\r
-    repaint();\r
-\r
-  }\r
-\r
-  public void setShowDistances(boolean state)\r
-  {\r
-    this.showDistances = state;\r
-    repaint();\r
-  }\r
-\r
-  public void setShowBootstrap(boolean state)\r
-  {\r
-    this.showBootstrap = state;\r
-    repaint();\r
-  }\r
-\r
-  public void setMarkPlaceholders(boolean state)\r
-  {\r
-    this.markPlaceholders = state;\r
-    repaint();\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+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.*;
+
+public class TreeCanvas
+    extends Panel implements MouseListener
+{
+  NJTree tree;
+  ScrollPane scrollPane;
+  AlignViewport av;
+  public static final String PLACEHOLDER = " * ";
+  Font font;
+  boolean fitToWindow = true;
+  boolean showDistances = false;
+  boolean showBootstrap = false;
+  boolean markPlaceholders = false;
+
+  int offx = 20;
+  int offy;
+
+  float threshold;
+
+  String longestName;
+  int labelLength = -1;
+
+  //RubberbandRectangle rubberband;
+
+  Vector listeners;
+
+  Hashtable nameHash = new Hashtable();
+  Hashtable nodeHash = new Hashtable();
+
+  public TreeCanvas(AlignViewport av, ScrollPane scroller)
+  {
+    this.av = av;
+    font = av.getFont();
+    scrollPane = scroller;
+    addMouseListener(this);
+    setLayout(null);
+
+    PaintRefresher.Register(this, av.alignment);
+  }
+
+  public void TreeSelectionChanged(Sequence sequence)
+  {
+    SequenceGroup selected = av.getSelectionGroup();
+    if (selected == null)
+    {
+      selected = new SequenceGroup();
+      av.setSelectionGroup(selected);
+    }
+
+    selected.setEndRes(av.alignment.getWidth()-1);
+    selected.addOrRemove(sequence, true);
+
+    PaintRefresher.Refresh(this, av.alignment);
+    repaint();
+  }
+
+  public void setTree(NJTree tree)
+  {
+    this.tree = tree;
+    tree.findHeight(tree.getTopNode());
+
+    // Now have to calculate longest name based on the leaves
+    Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());
+    boolean has_placeholders = false;
+    longestName = "";
+
+    for (int i = 0; i < leaves.size(); i++)
+    {
+      SequenceNode lf = (SequenceNode) leaves.elementAt(i);
+
+      if (lf.isPlaceholder())
+      {
+        has_placeholders = true;
+      }
+
+      if (longestName.length() < ( (Sequence) lf.element()).getName()
+          .length())
+      {
+        longestName = TreeCanvas.PLACEHOLDER +
+            ( (Sequence) lf.element()).getName();
+      }
+    }
+
+    setMarkPlaceholders(has_placeholders);
+  }
+
+  public void drawNode(Graphics g, SequenceNode node, float chunk, float scale,
+                       int width, int offx, int offy)
+  {
+    if (node == null)
+    {
+      return;
+    }
+
+    if (node.left() == null && node.right() == null)
+    {
+      // Drawing leaf node
+
+      float height = node.height;
+      float dist = node.dist;
+
+      int xstart = (int) ( (height - dist) * scale) + offx;
+      int xend = (int) (height * scale) + offx;
+
+      int ypos = (int) (node.ycount * chunk) + offy;
+
+      if (node.element() instanceof SequenceI)
+      {
+        if ( ( (SequenceI) ( (SequenceNode) node).element()).getColor() ==
+            Color.white)
+        {
+          g.setColor(Color.black);
+        }
+        else
+        {
+          g.setColor( ( (SequenceI) ( (SequenceNode) node).element()).getColor().
+                     darker());
+        }
+
+      }
+      else
+      {
+        g.setColor(Color.black);
+      }
+
+      // Draw horizontal line
+      g.drawLine(xstart, ypos, xend, ypos);
+
+      String nodeLabel = "";
+      if (showDistances && node.dist > 0)
+      {
+        nodeLabel = new Format("%-.2f").form(node.dist);
+      }
+      if (showBootstrap)
+      {
+        if (showDistances)
+        {
+          nodeLabel = nodeLabel + " : ";
+        }
+        nodeLabel = nodeLabel + String.valueOf(node.getBootstrap());
+      }
+      if (!nodeLabel.equals(""))
+      {
+        g.drawString(nodeLabel, xstart+2, ypos - 2);
+      }
+
+      String name = (markPlaceholders && node.isPlaceholder()) ?
+          (PLACEHOLDER + node.getName()) : node.getName();
+      FontMetrics fm = g.getFontMetrics(font);
+      int charWidth = fm.stringWidth(name) + 3;
+      int charHeight = fm.getHeight();
+
+      Rectangle rect = new Rectangle(xend + 10, ypos - charHeight,
+                                     charWidth, charHeight);
+
+      nameHash.put( (SequenceI) node.element(), rect);
+
+      // Colour selected leaves differently
+      SequenceGroup selected = av.getSelectionGroup();
+      if (selected != null &&
+          selected.getSequences(false).contains( (SequenceI) node.element()))
+      {
+        g.setColor(Color.gray);
+
+        g.fillRect(xend + 10, ypos - charHeight + 3, charWidth, charHeight);
+        g.setColor(Color.white);
+      }
+      g.drawString(name, xend + 10, ypos);
+      g.setColor(Color.black);
+    }
+    else
+    {
+      drawNode(g, (SequenceNode) node.left(), chunk, scale, width, offx, offy);
+      drawNode(g, (SequenceNode) node.right(), chunk, scale, width, offx, offy);
+
+      float height = node.height;
+      float dist = node.dist;
+
+      int xstart = (int) ( (height - dist) * scale) + offx;
+      int xend = (int) (height * scale) + offx;
+      int ypos = (int) (node.ycount * chunk) + offy;
+
+      g.setColor( ( (SequenceNode) node).color.darker());
+
+      // Draw horizontal line
+      g.drawLine(xstart, ypos, xend, ypos);
+      g.fillRect(xend - 2, ypos - 2, 4, 4);
+
+      int ystart = (int) ( ( (SequenceNode) node.left()).ycount * chunk) + offy;
+      int yend = (int) ( ( (SequenceNode) node.right()).ycount * chunk) + offy;
+
+      Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
+      nodeHash.put(node, pos);
+
+      g.drawLine( (int) (height * scale) + offx, ystart,
+                 (int) (height * scale) + offx, yend);
+
+      if (showDistances && node.dist > 0)
+      {
+        g.drawString(new Format("%-.2f").form(node.dist), xstart+2, ypos - 2);
+      }
+
+    }
+  }
+
+  public Object findElement(int x, int y)
+  {
+    Enumeration keys = nameHash.keys();
+
+    while (keys.hasMoreElements())
+    {
+      Object ob = keys.nextElement();
+      Rectangle rect = (Rectangle) nameHash.get(ob);
+
+      if (x >= rect.x && x <= (rect.x + rect.width) &&
+          y >= rect.y && y <= (rect.y + rect.height))
+      {
+        return ob;
+      }
+    }
+    keys = nodeHash.keys();
+
+    while (keys.hasMoreElements())
+    {
+      Object ob = keys.nextElement();
+      Rectangle rect = (Rectangle) nodeHash.get(ob);
+
+      if (x >= rect.x && x <= (rect.x + rect.width) &&
+          y >= rect.y && y <= (rect.y + rect.height))
+      {
+        return ob;
+      }
+    }
+    return null;
+
+  }
+
+  public void pickNodes(Rectangle pickBox)
+  {
+    int width = getSize().width;
+    int height = getSize().height;
+
+    SequenceNode top = tree.getTopNode();
+
+    float wscale = (float) (width * .8 - offx * 2) / tree.getMaxHeight()
+        ;
+    if (top.count == 0)
+    {
+      top.count = ( (SequenceNode) top.left()).count +
+          ( (SequenceNode) top.right()).count;
+    }
+    float chunk = (float) (height - offy) / top.count;
+
+    pickNode(pickBox, top, chunk, wscale, width, offx, offy);
+  }
+
+  public void pickNode(Rectangle pickBox, SequenceNode node, float chunk,
+                       float scale, int width, int offx, int offy)
+  {
+    if (node == null)
+    {
+      return;
+    }
+
+    if (node.left() == null && node.right() == null)
+    {
+      float height = node.height;
+      //float dist = node.dist;
+
+      //int xstart = (int) ( (height - dist) * scale) + offx;
+      int xend = (int) (height * scale) + offx;
+
+      int ypos = (int) (node.ycount * chunk) + offy;
+
+      if (pickBox.contains(new Point(xend, ypos)))
+      {
+        if (node.element() instanceof SequenceI)
+        {
+          SequenceI seq = (SequenceI) node.element();
+          SequenceGroup sg = av.getSelectionGroup();
+          if (sg != null)
+          {
+            sg.addOrRemove(seq, true);
+          }
+        }
+      }
+    }
+    else
+    {
+      pickNode(pickBox, (SequenceNode) node.left(), chunk, scale, width, offx,
+               offy);
+      pickNode(pickBox, (SequenceNode) node.right(), chunk, scale, width, offx,
+               offy);
+    }
+  }
+
+  public void setColor(SequenceNode node, Color c)
+  {
+    if (node == null)
+    {
+      return;
+    }
+
+    if (node.left() == null && node.right() == null)
+    {
+      node.color = c;
+
+      if (node.element() instanceof SequenceI)
+      {
+        ( (SequenceI) node.element()).setColor(c);
+      }
+    }
+    else
+    {
+      node.color = c;
+      setColor( (SequenceNode) node.left(), c);
+      setColor( (SequenceNode) node.right(), c);
+    }
+  }
+
+  public void paint(Graphics g)
+  {
+
+    if(tree==null)
+      return;
+
+    g.setFont(font);
+
+
+    FontMetrics fm = g.getFontMetrics(font);
+
+    if (nameHash.size() == 0)
+    {
+      repaint();
+    }
+
+    if (fitToWindow ||
+        (!fitToWindow &&
+         scrollPane.getSize().height > fm.getHeight() * nameHash.size() + offy))
+    {
+      draw(g, scrollPane.getSize().width, scrollPane.getSize().height);
+    }
+    else
+    {
+      setSize(new Dimension(scrollPane.getSize().width,
+                            fm.getHeight() * nameHash.size()));
+      draw(g, scrollPane.getSize().width, fm.getHeight() * nameHash.size());
+    }
+
+    scrollPane.validate();
+  }
+
+
+  public void draw(Graphics g, int width, int height)
+  {
+    offy = font.getSize()+10;
+
+    g.setColor(Color.white);
+    g.fillRect(0, 0, width, height);
+
+    labelLength = g.getFontMetrics(font).stringWidth(longestName) + 20; //20 allows for scrollbar
+
+    float wscale = (float) (width - labelLength - offx * 2) / tree.getMaxHeight();
+
+    SequenceNode top = tree.getTopNode();
+
+    if (top.count == 0)
+    {
+      top.count = ( (SequenceNode) top.left()).count +
+          ( (SequenceNode) top.right()).count;
+    }
+    float chunk = (float) (height - offy) / top.count;
+
+    drawNode(g, tree.getTopNode(), chunk, wscale, width, offx, offy);
+
+    if (threshold != 0)
+    {
+      if (av.getCurrentTree() == tree)
+      {
+        g.setColor(Color.red);
+      }
+      else
+      {
+        g.setColor(Color.gray);
+      }
+
+      int x = (int) (threshold *
+                     (float) (getSize().width - labelLength - 2 * offx) + offx);
+
+      g.drawLine(x, 0, x, getSize().height);
+    }
+
+  }
+
+  public void mouseReleased(MouseEvent e)
+  {}
+
+  public void mouseEntered(MouseEvent e)
+  {}
+
+  public void mouseExited(MouseEvent e)
+  {}
+
+  public void mouseClicked(MouseEvent e)
+  {
+  }
+
+  public void mousePressed(MouseEvent e)
+  {
+    av.setCurrentTree(tree);
+
+    int x = e.getX();
+    int y = e.getY();
+
+    Object ob = findElement(x, y);
+
+    if (ob instanceof SequenceI)
+    {
+      TreeSelectionChanged( (Sequence) ob);
+      repaint();
+      return;
+
+    }
+    else if (ob instanceof SequenceNode)
+    {
+      SequenceNode tmpnode = (SequenceNode) ob;
+      tree.swapNodes(tmpnode);
+      tree.reCount(tree.getTopNode());
+      tree.findHeight(tree.getTopNode());
+    }
+    else
+    {
+      // Find threshold
+
+      if (tree.getMaxHeight() != 0)
+      {
+        threshold = (float) (x - offx) /
+            (float) (getSize().width - labelLength - 2 * offx);
+
+        tree.getGroups().removeAllElements();
+        tree.groupNodes(tree.getTopNode(), threshold);
+        setColor(tree.getTopNode(), Color.black);
+
+        av.setSelectionGroup(null);
+        av.alignment.deleteAllGroups();
+
+        for (int i = 0; i < tree.getGroups().size(); i++)
+        {
+
+          Color col = new Color( (int) (Math.random() * 255),
+                                (int) (Math.random() * 255),
+                                (int) (Math.random() * 255));
+          setColor( (SequenceNode) tree.getGroups().elementAt(i), col.brighter());
+
+          Vector l = tree.findLeaves( (SequenceNode) tree.getGroups().elementAt(
+              i), new Vector());
+
+          Vector sequences = new Vector();
+          for (int j = 0; j < l.size(); j++)
+          {
+            SequenceI s1 = (SequenceI) ( (SequenceNode) l.elementAt(j)).element();
+            if(!sequences.contains(s1))
+              sequences.addElement(s1);
+          }
+
+          ColourSchemeI cs = null;
+
+          if (av.getGlobalColourScheme() != null)
+          {
+            if (av.getGlobalColourScheme() instanceof UserColourScheme)
+            {
+              cs = new UserColourScheme(
+                  ( (UserColourScheme) av.getGlobalColourScheme()).getColours());
+
+            }
+            else
+              cs = ColourSchemeProperty.getColour(sequences,
+                                                  av.alignment.getWidth(),
+                                                  ColourSchemeProperty.getColourName(
+                                                      av.getGlobalColourScheme()));
+
+              cs.setThreshold(av.getGlobalColourScheme().getThreshold(),
+                                                   av.getIgnoreGapsConsensus());
+          }
+
+          SequenceGroup sg = new SequenceGroup(sequences, "TreeGroup",
+                                               cs, true, true,
+                                               false, 0, av.alignment.getWidth()-1);
+
+
+          if (  av.getGlobalColourScheme()!=null
+             && av.getGlobalColourScheme().conservationApplied())
+            {
+            Conservation c = new Conservation("Group",
+                                              ResidueProperties.propHash, 3,
+                                              sg.getSequences(false),
+                                              sg.getStartRes(),
+                                              sg.getEndRes());
+
+            c.calculate();
+            c.verdict(false, av.ConsPercGaps);
+            cs.setConservation(c);
+
+            sg.cs = cs;
+
+          }
+
+          av.alignment.addGroup(sg);
+
+        }
+      }
+    }
+
+    PaintRefresher.Refresh(this, av.alignment);
+    repaint();
+
+  }
+
+  public void setShowDistances(boolean state)
+  {
+    this.showDistances = state;
+    repaint();
+  }
+
+  public void setShowBootstrap(boolean state)
+  {
+    this.showBootstrap = state;
+    repaint();
+  }
+
+  public void setMarkPlaceholders(boolean state)
+  {
+    this.markPlaceholders = state;
+    repaint();
+  }
+
+}
index 61b0546..1f31ce3 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.event.*;\r
-import java.awt.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-import jalview.io.*;\r
-\r
-public class TreePanel extends Frame implements ActionListener, ItemListener\r
-{\r
-  SequenceI[] seq;\r
-  String type;\r
-  String pwtype;\r
-  int start;\r
-  int end;\r
-  TreeCanvas treeCanvas;\r
-  NJTree tree;\r
-\r
-  public NJTree getTree()\r
-  {\r
-    return tree;\r
-  }\r
-\r
-  /**\r
-   * Creates a new TreePanel object.\r
-   *\r
-   * @param av DOCUMENT ME!\r
-   * @param seqVector DOCUMENT ME!\r
-   * @param type DOCUMENT ME!\r
-   * @param pwtype DOCUMENT ME!\r
-   * @param s DOCUMENT ME!\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public TreePanel(AlignViewport av, Vector seqVector, String type,\r
-                   String pwtype, int s, int e)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-      this.setMenuBar(jMenuBar1);\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    initTreePanel(av, seqVector, type, pwtype, s, e, null);\r
-  }\r
-\r
-  /**\r
-   * Creates a new TreePanel object.\r
-   *\r
-   * @param av DOCUMENT ME!\r
-   * @param seqVector DOCUMENT ME!\r
-   * @param newtree DOCUMENT ME!\r
-   * @param type DOCUMENT ME!\r
-   * @param pwtype DOCUMENT ME!\r
-   */\r
-  public TreePanel(AlignViewport av, Vector seqVector, NewickFile newtree,\r
-                   String type, String pwtype)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-      this.setMenuBar(jMenuBar1);\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    initTreePanel(av, seqVector, type, pwtype, 0, seqVector.size(), newtree);\r
-  }\r
-\r
-\r
-  void initTreePanel(AlignViewport av, Vector seqVector, String type,\r
-                     String pwtype, int s, int e, NewickFile newTree)\r
-  {\r
-\r
-    this.type = type;\r
-    this.pwtype = pwtype;\r
-\r
-    start = s;\r
-    end = e;\r
-\r
-    seq = new Sequence[seqVector.size()];\r
-    for(int i=0; i<seqVector.size(); i++)\r
-      seq[i] = (SequenceI)seqVector.elementAt(i);\r
-\r
-\r
-    treeCanvas = new TreeCanvas(av, scrollPane);\r
-    scrollPane.add(treeCanvas);\r
-\r
-\r
-    TreeLoader tl = new TreeLoader(newTree);\r
-    tl.start();\r
-\r
-  }\r
-\r
-  class TreeLoader extends Thread\r
-  {\r
-    NewickFile newtree;\r
-\r
-    public TreeLoader(NewickFile newtree)\r
-    {\r
-      this.newtree = newtree;\r
-    }\r
-\r
-    public void run()\r
-    {\r
-      if(newtree!=null)\r
-        tree = new NJTree(seq, newtree);\r
-      else\r
-        tree = new NJTree(seq, type, pwtype, start, end);\r
-\r
-      tree.reCount(tree.getTopNode());\r
-      tree.findHeight(tree.getTopNode());\r
-      treeCanvas.setTree(tree);\r
-      if(newtree!=null)\r
-      {\r
-        distanceMenu.setState(newtree.HasDistances());\r
-        bootstrapMenu.setState(newtree.HasBootstrap());\r
-        treeCanvas.setShowBootstrap(newtree.HasBootstrap());\r
-        treeCanvas.setShowDistances(newtree.HasDistances());\r
-      }\r
-\r
-\r
-      treeCanvas.repaint();\r
-\r
-    }\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==newickOutput)\r
-      newickOutput_actionPerformed();\r
-    else if(evt.getSource()==fontSize)\r
-      fontSize_actionPerformed();\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if(evt.getSource()==fitToWindow)\r
-      treeCanvas.fitToWindow = fitToWindow.getState();\r
-\r
-    else if(evt.getSource()==distanceMenu)\r
-      treeCanvas.setShowDistances(distanceMenu.getState());\r
-\r
-    else if(evt.getSource()==bootstrapMenu)\r
-      treeCanvas.setShowBootstrap(bootstrapMenu.getState());\r
-\r
-    else if(evt.getSource()==placeholdersMenu)\r
-      treeCanvas.setMarkPlaceholders(placeholdersMenu.getState());\r
-\r
-    treeCanvas.repaint();\r
-  }\r
-\r
-\r
-  public void newickOutput_actionPerformed()\r
-  {\r
-    jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
-    String output = fout.print(false, true);\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);\r
-    cap.setText(output);\r
-    java.awt.Frame frame = new java.awt.Frame();\r
-    frame.add(cap);\r
-    jalview.bin.JalviewLite.addFrame(frame, type + " " + pwtype, 500, 100);\r
-  }\r
-\r
-  public java.awt.Font getTreeFont()\r
-  {\r
-    return treeCanvas.font;\r
-  }\r
-\r
-  public void setTreeFont(java.awt.Font font)\r
-  {\r
-    treeCanvas.font = font;\r
-    treeCanvas.repaint();\r
-  }\r
-\r
-  protected void fontSize_actionPerformed()\r
-  {\r
-     if( treeCanvas==null )\r
-        return;\r
-\r
-    new FontChooser(this);\r
-  }\r
-\r
-\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  protected ScrollPane scrollPane = new ScrollPane();\r
-  MenuBar jMenuBar1 = new MenuBar();\r
-  Menu jMenu2 = new Menu();\r
-  protected MenuItem fontSize = new MenuItem();\r
-  protected CheckboxMenuItem bootstrapMenu = new CheckboxMenuItem();\r
-  protected CheckboxMenuItem distanceMenu = new CheckboxMenuItem();\r
-  protected CheckboxMenuItem placeholdersMenu = new CheckboxMenuItem();\r
-  protected CheckboxMenuItem fitToWindow = new CheckboxMenuItem();\r
-  Menu fileMenu = new Menu();\r
-  MenuItem newickOutput = new MenuItem();\r
-\r
-  private void jbInit() throws Exception {\r
-      setLayout(borderLayout1);\r
-      this.setBackground(Color.white);\r
-      this.setFont(new java.awt.Font("Verdana", 0, 12));\r
-      jMenu2.setLabel("View");\r
-      fontSize.setLabel("Font...");\r
-      fontSize.addActionListener(this);\r
-      bootstrapMenu.setLabel("Show Bootstrap Values");\r
-      bootstrapMenu.addItemListener(this);\r
-      distanceMenu.setLabel("Show Distances");\r
-      distanceMenu.addItemListener(this);\r
-      placeholdersMenu.setLabel("Mark Unassociated Leaves");\r
-      placeholdersMenu.addItemListener(this);\r
-      fitToWindow.setState(true);\r
-      fitToWindow.setLabel("Fit To Window");\r
-      fitToWindow.addItemListener(this);\r
-      fileMenu.setLabel("File");\r
-      newickOutput.setLabel("Newick Format");\r
-      newickOutput.addActionListener(this);\r
-\r
-    add(scrollPane, BorderLayout.CENTER);\r
-      jMenuBar1.add(fileMenu);\r
-      jMenuBar1.add(jMenu2);\r
-      jMenu2.add(fitToWindow);\r
-      jMenu2.add(fontSize);\r
-      jMenu2.add(distanceMenu);\r
-      jMenu2.add(bootstrapMenu);\r
-      jMenu2.add(placeholdersMenu);\r
-    fileMenu.add(newickOutput);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.event.*;
+import java.awt.*;
+
+import jalview.analysis.*;
+import jalview.datamodel.*;
+import jalview.io.*;
+
+public class TreePanel extends Frame implements ActionListener, ItemListener
+{
+  SequenceI[] seq;
+  String type;
+  String pwtype;
+  int start;
+  int end;
+  TreeCanvas treeCanvas;
+  NJTree tree;
+  AlignViewport av;
+
+  public NJTree getTree()
+  {
+    return tree;
+  }
+
+  /**
+   * Creates a new TreePanel object.
+   *
+   * @param av DOCUMENT ME!
+   * @param seqVector DOCUMENT ME!
+   * @param type DOCUMENT ME!
+   * @param pwtype DOCUMENT ME!
+   * @param s DOCUMENT ME!
+   * @param e DOCUMENT ME!
+   */
+  public TreePanel(AlignViewport av, String type, String pwtype)
+  {
+    try
+    {
+      jbInit();
+      this.setMenuBar(jMenuBar1);
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    initTreePanel(av, type, pwtype, null);
+  }
+
+  /**
+   * Creates a new TreePanel object.
+   *
+   * @param av DOCUMENT ME!
+   * @param seqVector DOCUMENT ME!
+   * @param newtree DOCUMENT ME!
+   * @param type DOCUMENT ME!
+   * @param pwtype DOCUMENT ME!
+   */
+  public TreePanel(AlignViewport av,
+                   String type,
+                   String pwtype,
+                   NewickFile newtree)
+  {
+    try
+    {
+      jbInit();
+      this.setMenuBar(jMenuBar1);
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    initTreePanel(av, type, pwtype, newtree);
+  }
+
+
+  void initTreePanel(AlignViewport av,
+                     String type,
+                     String pwtype,
+                     NewickFile newTree)
+  {
+
+    this.av = av;
+    this.type = type;
+    this.pwtype = pwtype;
+
+    treeCanvas = new TreeCanvas(av, scrollPane);
+    scrollPane.add(treeCanvas);
+
+
+    TreeLoader tl = new TreeLoader(newTree);
+    tl.start();
+
+  }
+
+  void showOriginalData()
+  {
+    // decide if av alignment is sufficiently different to original data to warrant a new window to be created
+    // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)
+    // or create a selection box around columns in alignment view
+    // test Alignment(SeqCigar[])
+    if(tree.seqData!=null)
+    {
+      Object[] alAndColsel = tree.seqData.getAlignmentAndColumnSelection(av.
+          getGapCharacter());
+
+      if (alAndColsel != null && alAndColsel[0] != null)
+      {
+        Alignment al = new Alignment( (SequenceI[]) alAndColsel[0]);
+        AlignFrame af = new AlignFrame(al,
+                                       av.applet,
+                                       "Original Data for Tree",
+                                       false);
+
+        af.viewport.setHiddenColumns( (ColumnSelection) alAndColsel[1]);
+      }
+    }
+    else
+      System.out.println("Original Tree Data not available");
+  }
+
+  class TreeLoader extends Thread
+  {
+    NewickFile newtree;
+    jalview.datamodel.AlignmentView odata=null;
+
+    public TreeLoader(NewickFile newtree)
+    {
+      this.newtree = newtree;
+    }
+
+    public void run()
+    {
+      if(newtree!=null)
+      {
+        if (odata == null)
+          tree = new NJTree(av.alignment.getSequencesArray(),
+                            newtree);
+        else
+          tree = new NJTree(av.alignment.getSequencesArray(), odata, newtree);
+
+        }
+        else
+        {
+          int start, end;
+          SequenceI [] seqs;
+          AlignmentView seqStrings = av.getAlignmentView(av.getSelectionGroup()!=null);
+          if(av.getSelectionGroup()==null)
+          {
+            start = 0;
+            end = av.alignment.getWidth();
+            seqs = av.alignment.getSequencesArray();
+          }
+          else
+          {
+            start = av.getSelectionGroup().getStartRes();
+            end = av.getSelectionGroup().getEndRes()+1;
+            seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+          }
+
+          tree = new NJTree(seqs, seqStrings, type, pwtype, start, end);
+        }
+
+      tree.reCount(tree.getTopNode());
+      tree.findHeight(tree.getTopNode());
+      treeCanvas.setTree(tree);
+      if(newtree!=null)
+      {
+        distanceMenu.setState(newtree.HasDistances());
+        bootstrapMenu.setState(newtree.HasBootstrap());
+        treeCanvas.setShowBootstrap(newtree.HasBootstrap());
+        treeCanvas.setShowDistances(newtree.HasDistances());
+      }
+
+
+      treeCanvas.repaint();
+
+      av.setCurrentTree(tree);
+
+    }
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==newickOutput)
+      newickOutput_actionPerformed();
+    else if(evt.getSource()==fontSize)
+      fontSize_actionPerformed();
+    else if(evt.getSource()==inputData)
+      showOriginalData();
+  }
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if(evt.getSource()==fitToWindow)
+      treeCanvas.fitToWindow = fitToWindow.getState();
+
+    else if(evt.getSource()==distanceMenu)
+      treeCanvas.setShowDistances(distanceMenu.getState());
+
+    else if(evt.getSource()==bootstrapMenu)
+      treeCanvas.setShowBootstrap(bootstrapMenu.getState());
+
+    else if(evt.getSource()==placeholdersMenu)
+      treeCanvas.setMarkPlaceholders(placeholdersMenu.getState());
+
+    treeCanvas.repaint();
+  }
+
+
+  public void newickOutput_actionPerformed()
+  {
+    jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());
+    String output = fout.print(false, true);
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);
+    cap.setText(output);
+    java.awt.Frame frame = new java.awt.Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame, type + " " + pwtype, 500, 100);
+  }
+
+  public java.awt.Font getTreeFont()
+  {
+    return treeCanvas.font;
+  }
+
+  public void setTreeFont(java.awt.Font font)
+  {
+    treeCanvas.font = font;
+    treeCanvas.repaint();
+  }
+
+  protected void fontSize_actionPerformed()
+  {
+     if( treeCanvas==null )
+        return;
+
+    new FontChooser(this);
+  }
+
+
+
+
+  BorderLayout borderLayout1 = new BorderLayout();
+  protected ScrollPane scrollPane = new ScrollPane();
+  MenuBar jMenuBar1 = new MenuBar();
+  Menu jMenu2 = new Menu();
+  protected MenuItem fontSize = new MenuItem();
+  protected CheckboxMenuItem bootstrapMenu = new CheckboxMenuItem();
+  protected CheckboxMenuItem distanceMenu = new CheckboxMenuItem();
+  protected CheckboxMenuItem placeholdersMenu = new CheckboxMenuItem();
+  protected CheckboxMenuItem fitToWindow = new CheckboxMenuItem();
+  Menu fileMenu = new Menu();
+  MenuItem newickOutput = new MenuItem();
+  MenuItem inputData = new MenuItem();
+
+  private void jbInit() throws Exception {
+      setLayout(borderLayout1);
+      this.setBackground(Color.white);
+      this.setFont(new java.awt.Font("Verdana", 0, 12));
+      jMenu2.setLabel("View");
+      fontSize.setLabel("Font...");
+      fontSize.addActionListener(this);
+      bootstrapMenu.setLabel("Show Bootstrap Values");
+      bootstrapMenu.addItemListener(this);
+      distanceMenu.setLabel("Show Distances");
+      distanceMenu.addItemListener(this);
+      placeholdersMenu.setLabel("Mark Unassociated Leaves");
+      placeholdersMenu.addItemListener(this);
+      fitToWindow.setState(true);
+      fitToWindow.setLabel("Fit To Window");
+      fitToWindow.addItemListener(this);
+      fileMenu.setLabel("File");
+      newickOutput.setLabel("Newick Format");
+      newickOutput.addActionListener(this);
+    inputData.setLabel("Input Data...");
+
+    add(scrollPane, BorderLayout.CENTER);
+      jMenuBar1.add(fileMenu);
+      jMenuBar1.add(jMenu2);
+      jMenu2.add(fitToWindow);
+      jMenu2.add(fontSize);
+      jMenu2.add(distanceMenu);
+      jMenu2.add(bootstrapMenu);
+      jMenu2.add(placeholdersMenu);
+    fileMenu.add(newickOutput);
+    fileMenu.add(inputData);
+    inputData.addActionListener(this);
+  }
+
+}
index eb454d7..3a3c7b9 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.schemes.*;\r
-\r
-public class UserDefinedColours\r
-    extends Panel implements ActionListener, AdjustmentListener\r
-{\r
-\r
-  AlignmentPanel ap;\r
-  SequenceGroup seqGroup;\r
-  Button selectedButton;\r
-  Vector oldColours = new Vector();\r
-  ColourSchemeI oldColourScheme;\r
-  Frame frame;\r
-  MCview.AppletPDBCanvas pdbcanvas;\r
-\r
-  Component caller;\r
-  String originalLabel;\r
-  Color originalColour;\r
-\r
-  int R = 0, G = 0, B = 0;\r
-\r
-  public ColourSchemeI loadDefaultColours()\r
-  {\r
-    // NOT IMPLEMENTED YET IN APPLET VERSION\r
-    return null;\r
-  }\r
-\r
-  public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)\r
-  {\r
-    this.ap = ap;\r
-    seqGroup = sg;\r
-\r
-    if (seqGroup != null)\r
-    {\r
-      oldColourScheme = seqGroup.cs;\r
-    }\r
-    else\r
-    {\r
-      oldColourScheme = ap.av.getGlobalColourScheme();\r
-    }\r
-\r
-    init();\r
-  }\r
-\r
-  public UserDefinedColours(MCview.AppletPDBCanvas pdb)\r
-  {\r
-    this.pdbcanvas = pdb;\r
-    init();\r
-  }\r
-\r
-  public UserDefinedColours(Component caller,\r
-                            String label,\r
-                            Color colour)\r
-  {\r
-    this.caller = caller;\r
-    originalColour = colour;\r
-    originalLabel = label;\r
-    init();\r
-    remove(buttonPanel);\r
-\r
-    setTargetColour(colour);\r
-\r
-    okcancelPanel.setBounds(new Rectangle(0, 113, 400, 35));\r
-    frame.setTitle("User Defined Colours - "+label);\r
-    frame.setSize(420, 200);\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==okButton)\r
-     okButton_actionPerformed();\r
-   else if(evt.getSource()==applyButton)\r
-      applyButton_actionPerformed();\r
-   else if(evt.getSource()==cancelButton)\r
-     cancelButton_actionPerformed();\r
-   else if(evt.getSource()==rText)\r
-     rText_actionPerformed();\r
-   else if (evt.getSource() == gText)\r
-     gText_actionPerformed();\r
-   else if (evt.getSource() == bText)\r
-     bText_actionPerformed();\r
-}\r
-\r
-  public void adjustmentValueChanged(AdjustmentEvent evt)\r
-  {\r
-    if(evt.getSource()==rScroller)\r
-    rScroller_adjustmentValueChanged();\r
-  else if(evt.getSource()==gScroller)\r
-    gScroller_adjustmentValueChanged();\r
-  else if(evt.getSource()==bScroller)\r
-    bScroller_adjustmentValueChanged();\r
-}\r
-\r
-  void init()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-    frame = new Frame();\r
-    frame.add(this);\r
-    jalview.bin.JalviewLite.addFrame(frame, "User defined colours", 420, 345);\r
-\r
-    if (seqGroup != null)\r
-    {\r
-      frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");\r
-    }\r
-\r
-    for (int i = 0; i < 20; i++)\r
-    {\r
-      makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +\r
-                 "", ResidueProperties.aa[i]);\r
-    }\r
-\r
-    makeButton("B", "B");\r
-    makeButton("Z", "Z");\r
-    makeButton("X", "X");\r
-    makeButton("Gap", "'.','-',' '");\r
-\r
-    validate();\r
-  }\r
-  protected void rText_actionPerformed()\r
-  {\r
-    try\r
-    {\r
-      int i = Integer.parseInt(rText.getText());\r
-      rScroller.setValue(i);\r
-      rScroller_adjustmentValueChanged();\r
-    }\r
-    catch (NumberFormatException ex)\r
-    {}\r
-  }\r
-\r
-  protected void gText_actionPerformed()\r
-  {\r
-    try\r
-    {\r
-      int i = Integer.parseInt(gText.getText());\r
-      gScroller.setValue(i);\r
-      gScroller_adjustmentValueChanged();\r
-    }\r
-    catch (NumberFormatException ex)\r
-    {}\r
-\r
-  }\r
-\r
-  protected void bText_actionPerformed()\r
-  {\r
-    try\r
-    {\r
-      int i = Integer.parseInt(bText.getText());\r
-      bScroller.setValue(i);\r
-      bScroller_adjustmentValueChanged();\r
-    }\r
-    catch (NumberFormatException ex)\r
-    {}\r
-\r
-  }\r
-\r
-  protected void rScroller_adjustmentValueChanged()\r
-  {\r
-    R = rScroller.getValue();\r
-    rText.setText(R + "");\r
-    colourChanged();\r
-  }\r
-\r
-  protected void gScroller_adjustmentValueChanged()\r
-  {\r
-    G = gScroller.getValue();\r
-    gText.setText(G + "");\r
-    colourChanged();\r
-  }\r
-\r
-  protected void bScroller_adjustmentValueChanged()\r
-  {\r
-    B = bScroller.getValue();\r
-    bText.setText(B + "");\r
-    colourChanged();\r
-  }\r
-\r
-  public void colourChanged()\r
-  {\r
-    Color col = new Color(R, G, B);\r
-    target.setBackground(col);\r
-    target.repaint();\r
-\r
-    if (selectedButton != null)\r
-    {\r
-      selectedButton.setBackground(col);\r
-      selectedButton.repaint();\r
-    }\r
-  }\r
-\r
-  void setTargetColour(Color col)\r
-  {\r
-    R = col.getRed();\r
-    G = col.getGreen();\r
-    B = col.getBlue();\r
-    rScroller.setValue(R);\r
-    gScroller.setValue(G);\r
-    bScroller.setValue(B);\r
-    rText.setText(R + "");\r
-    gText.setText(G + "");\r
-    bText.setText(B + "");\r
-    colourChanged();\r
-  }\r
-\r
-  public void colourButtonPressed(MouseEvent e)\r
-  {\r
-    selectedButton = (Button) e.getSource();\r
-    setTargetColour(selectedButton.getBackground());\r
-  }\r
-\r
-  void makeButton(String label, String aa)\r
-  {\r
-    final Button button = new Button();\r
-    Color col = Color.white;\r
-\r
-    try\r
-    {\r
-      col = oldColourScheme.findColour(aa, -1);\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-\r
-    button.setBackground(col);\r
-    oldColours.addElement(col);\r
-    button.setLabel(label);\r
-    button.setForeground(col.darker().darker().darker());\r
-    button.setFont(new java.awt.Font("Verdana", 1, 10));\r
-    button.addMouseListener(new java.awt.event.MouseAdapter()\r
-    {\r
-      public void mousePressed(MouseEvent e)\r
-      {\r
-        colourButtonPressed(e);\r
-      }\r
-    });\r
-\r
-    buttonPanel.add(button, null);\r
-  }\r
-\r
-  protected void okButton_actionPerformed()\r
-  {\r
-    applyButton_actionPerformed();\r
-    frame.setVisible(false);\r
-  }\r
-\r
-  protected void applyButton_actionPerformed()\r
-  {\r
-    if (caller != null)\r
-    {\r
-      if(caller instanceof FeatureSettings)\r
-        ((FeatureSettings)caller).setUserColour\r
-            (originalLabel, new Color(R,G,B));\r
-      else if(caller instanceof AnnotationColourChooser)\r
-      {\r
-        if (originalLabel.equals("Min Colour"))\r
-          ( (AnnotationColourChooser) caller).minColour_actionPerformed\r
-              (new Color(R, G, B));\r
-        else\r
-          ( (AnnotationColourChooser) caller).maxColour_actionPerformed\r
-              (new Color(R, G, B));\r
-      }\r
-      return;\r
-    }\r
-\r
-\r
-    Color[] newColours = new Color[24];\r
-    for (int i = 0; i < 24; i++)\r
-    {\r
-      Button button = (Button) buttonPanel.getComponent(i);\r
-      newColours[i] = button.getBackground();\r
-    }\r
-\r
-    UserColourScheme ucs = new UserColourScheme(newColours);\r
-    if(ap!=null)\r
-      ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
-\r
-    if(ap!=null)\r
-    {\r
-      if (seqGroup != null)\r
-      {\r
-        seqGroup.cs = ucs;\r
-      }\r
-      else\r
-      {\r
-        ap.av.setGlobalColourScheme(ucs);\r
-      }\r
-      ap.seqPanel.seqCanvas.img = null;\r
-      ap.repaint();\r
-    }\r
-    else if(pdbcanvas!=null)\r
-    {\r
-      pdbcanvas.pdb.setColours(ucs);\r
-      pdbcanvas.updateSeqColours();\r
-    }\r
-  }\r
-\r
-\r
-  protected void cancelButton_actionPerformed()\r
-  {\r
-    if (caller != null)\r
-    {\r
-      if(caller instanceof FeatureSettings)\r
-        ((FeatureSettings)caller).setUserColour\r
-            (originalLabel, originalColour);\r
-      else if (caller instanceof AnnotationColourChooser)\r
-      {\r
-        if (originalLabel.equals("Min Colour"))\r
-          ( (AnnotationColourChooser) caller).minColour_actionPerformed\r
-              (originalColour);\r
-        else\r
-          ( (AnnotationColourChooser) caller).maxColour_actionPerformed\r
-              (originalColour);\r
-      }\r
-      frame.setVisible(false);\r
-      return;\r
-    }\r
-\r
-    Color[] newColours = new Color[24];\r
-    for (int i = 0; i < 24; i++)\r
-    {\r
-      newColours[i] = (Color) oldColours.elementAt(i);\r
-      buttonPanel.getComponent(i).setBackground(newColours[i]);\r
-    }\r
-\r
-    UserColourScheme ucs = new UserColourScheme(newColours);\r
-\r
-   if(ap!=null)\r
-    {\r
-      if (seqGroup != null)\r
-      {\r
-        seqGroup.cs = ucs;\r
-      }\r
-      else\r
-      {\r
-        ap.av.setGlobalColourScheme(ucs);\r
-      }\r
-      ap.repaint();\r
-    }\r
-    else if(pdbcanvas!=null)\r
-    {\r
-      pdbcanvas.pdb.setColours(ucs);\r
-    }\r
-\r
-    frame.setVisible(false);\r
-  }\r
-\r
-\r
-  protected Panel buttonPanel = new Panel();\r
-  protected GridLayout gridLayout = new GridLayout();\r
-  Panel okcancelPanel = new Panel();\r
-  protected Button okButton = new Button();\r
-  protected Button applyButton = new Button();\r
-  protected Button cancelButton = new Button();\r
-  protected Scrollbar rScroller = new Scrollbar();\r
-  Label label1 = new Label();\r
-  protected TextField rText = new TextField();\r
-  Label label4 = new Label();\r
-  protected Scrollbar gScroller = new Scrollbar();\r
-  protected TextField gText = new TextField();\r
-  Label label5 = new Label();\r
-  protected Scrollbar bScroller = new Scrollbar();\r
-  protected TextField bText = new TextField();\r
-  protected Panel target = new Panel();\r
-\r
-  private void jbInit() throws Exception {\r
-      this.setLayout(null);\r
-      buttonPanel.setLayout(gridLayout);\r
-      gridLayout.setColumns(6);\r
-      gridLayout.setRows(4);\r
-      okButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      okButton.setLabel("OK");\r
-      okButton.addActionListener(this);\r
-      applyButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      applyButton.setLabel("Apply");\r
-      applyButton.addActionListener(this);\r
-      cancelButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-      cancelButton.setLabel("Cancel");\r
-      cancelButton.addActionListener(this);\r
-      this.setBackground(new Color(212, 208, 223));\r
-      okcancelPanel.setBounds(new Rectangle(0, 265, 400, 35));\r
-      buttonPanel.setBounds(new Rectangle(0, 123, 400, 142));\r
-      rScroller.setMaximum(256);\r
-      rScroller.setMinimum(0);\r
-      rScroller.setOrientation(0);\r
-      rScroller.setUnitIncrement(1);\r
-  rScroller.setVisibleAmount(1);\r
-  rScroller.setBounds(new Rectangle(36, 27, 119, 19));\r
-  rScroller.addAdjustmentListener(this);\r
-  label1.setAlignment(Label.RIGHT);\r
-  label1.setText("R");\r
-  label1.setBounds(new Rectangle(19, 30, 16, 15));\r
-  rText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));\r
-  rText.setText("0        ");\r
-  rText.setBounds(new Rectangle(156, 27, 53, 19));\r
-  rText.addActionListener(this);\r
-  label4.setAlignment(Label.RIGHT);\r
-  label4.setText("G");\r
-  label4.setBounds(new Rectangle(15, 56, 20, 15));\r
-  gScroller.setMaximum(256);\r
-      gScroller.setMinimum(0);\r
-      gScroller.setOrientation(0);\r
-      gScroller.setUnitIncrement(1);\r
-  gScroller.setVisibleAmount(1);\r
-  gScroller.setBounds(new Rectangle(35, 52, 120, 20));\r
-  gScroller.addAdjustmentListener(this);\r
-  gText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));\r
-  gText.setText("0        ");\r
-  gText.setBounds(new Rectangle(156, 52, 53, 20));\r
-  gText.addActionListener(this);\r
-  label5.setAlignment(Label.RIGHT);\r
-  label5.setText("B");\r
-  label5.setBounds(new Rectangle(14, 82, 20, 15));\r
-  bScroller.setMaximum(256);\r
-      bScroller.setMinimum(0);\r
-      bScroller.setOrientation(0);\r
-      bScroller.setUnitIncrement(1);\r
-  bScroller.setVisibleAmount(1);\r
-  bScroller.setBounds(new Rectangle(35, 78, 120, 20));\r
-  bScroller.addAdjustmentListener(this);\r
-  bText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));\r
-  bText.setText("0        ");\r
-  bText.setBounds(new Rectangle(157, 78, 52, 20));\r
-  bText.addActionListener(this);\r
-  target.setBackground(Color.black);\r
-      target.setBounds(new Rectangle(229, 26, 134, 79));\r
-      this.add(okcancelPanel, null);\r
-      okcancelPanel.add(okButton, null);\r
-      okcancelPanel.add(applyButton, null);\r
-      okcancelPanel.add(cancelButton, null);\r
-      this.add(buttonPanel, null);\r
-  this.add(target, null);\r
-  this.add(gScroller);\r
-  this.add(rScroller);\r
-  this.add(bScroller);\r
-  this.add(label5);\r
-  this.add(label4);\r
-  this.add(label1);\r
-  this.add(gText);\r
-  this.add(rText);\r
-  this.add(bText);\r
-}\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+public class UserDefinedColours
+    extends Panel implements ActionListener, AdjustmentListener
+{
+
+  AlignmentPanel ap;
+  SequenceGroup seqGroup;
+  Button selectedButton;
+  Vector oldColours = new Vector();
+  ColourSchemeI oldColourScheme;
+  Frame frame;
+  MCview.AppletPDBCanvas pdbcanvas;
+
+  Component caller;
+  String originalLabel;
+  Color originalColour;
+
+  int R = 0, G = 0, B = 0;
+
+  public ColourSchemeI loadDefaultColours()
+  {
+    // NOT IMPLEMENTED YET IN APPLET VERSION
+    return null;
+  }
+
+  public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
+  {
+    this.ap = ap;
+    seqGroup = sg;
+
+    if (seqGroup != null)
+    {
+      oldColourScheme = seqGroup.cs;
+    }
+    else
+    {
+      oldColourScheme = ap.av.getGlobalColourScheme();
+    }
+
+    init();
+  }
+
+  public UserDefinedColours(MCview.AppletPDBCanvas pdb)
+  {
+    this.pdbcanvas = pdb;
+    init();
+  }
+
+  public UserDefinedColours(Component caller,
+                            String label,
+                            Color colour)
+  {
+    this.caller = caller;
+    originalColour = colour;
+    originalLabel = label;
+    init();
+    remove(buttonPanel);
+
+    setTargetColour(colour);
+
+    okcancelPanel.setBounds(new Rectangle(0, 113, 400, 35));
+    frame.setTitle("User Defined Colours - "+label);
+    frame.setSize(420, 200);
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if(evt.getSource()==okButton)
+     okButton_actionPerformed();
+   else if(evt.getSource()==applyButton)
+      applyButton_actionPerformed();
+   else if(evt.getSource()==cancelButton)
+     cancelButton_actionPerformed();
+   else if(evt.getSource()==rText)
+     rText_actionPerformed();
+   else if (evt.getSource() == gText)
+     gText_actionPerformed();
+   else if (evt.getSource() == bText)
+     bText_actionPerformed();
+}
+
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+    if(evt.getSource()==rScroller)
+    rScroller_adjustmentValueChanged();
+  else if(evt.getSource()==gScroller)
+    gScroller_adjustmentValueChanged();
+  else if(evt.getSource()==bScroller)
+    bScroller_adjustmentValueChanged();
+}
+
+  void init()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    frame = new Frame();
+    frame.add(this);
+    jalview.bin.JalviewLite.addFrame(frame, "User defined colours", 420, 345);
+
+    if (seqGroup != null)
+    {
+      frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
+    }
+
+    for (int i = 0; i < 20; i++)
+    {
+      makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +
+                 "", ResidueProperties.aa[i]);
+    }
+
+    makeButton("B", "B");
+    makeButton("Z", "Z");
+    makeButton("X", "X");
+    makeButton("Gap", "'.','-',' '");
+
+    validate();
+  }
+  protected void rText_actionPerformed()
+  {
+    try
+    {
+      int i = Integer.parseInt(rText.getText());
+      rScroller.setValue(i);
+      rScroller_adjustmentValueChanged();
+    }
+    catch (NumberFormatException ex)
+    {}
+  }
+
+  protected void gText_actionPerformed()
+  {
+    try
+    {
+      int i = Integer.parseInt(gText.getText());
+      gScroller.setValue(i);
+      gScroller_adjustmentValueChanged();
+    }
+    catch (NumberFormatException ex)
+    {}
+
+  }
+
+  protected void bText_actionPerformed()
+  {
+    try
+    {
+      int i = Integer.parseInt(bText.getText());
+      bScroller.setValue(i);
+      bScroller_adjustmentValueChanged();
+    }
+    catch (NumberFormatException ex)
+    {}
+
+  }
+
+  protected void rScroller_adjustmentValueChanged()
+  {
+    R = rScroller.getValue();
+    rText.setText(R + "");
+    colourChanged();
+  }
+
+  protected void gScroller_adjustmentValueChanged()
+  {
+    G = gScroller.getValue();
+    gText.setText(G + "");
+    colourChanged();
+  }
+
+  protected void bScroller_adjustmentValueChanged()
+  {
+    B = bScroller.getValue();
+    bText.setText(B + "");
+    colourChanged();
+  }
+
+  public void colourChanged()
+  {
+    Color col = new Color(R, G, B);
+    target.setBackground(col);
+    target.repaint();
+
+    if (selectedButton != null)
+    {
+      selectedButton.setBackground(col);
+      selectedButton.repaint();
+    }
+  }
+
+  void setTargetColour(Color col)
+  {
+    R = col.getRed();
+    G = col.getGreen();
+    B = col.getBlue();
+    rScroller.setValue(R);
+    gScroller.setValue(G);
+    bScroller.setValue(B);
+    rText.setText(R + "");
+    gText.setText(G + "");
+    bText.setText(B + "");
+    colourChanged();
+  }
+
+  public void colourButtonPressed(MouseEvent e)
+  {
+    selectedButton = (Button) e.getSource();
+    setTargetColour(selectedButton.getBackground());
+  }
+
+  void makeButton(String label, String aa)
+  {
+    final Button button = new Button();
+    Color col = Color.white;
+
+    try
+    {
+      col = oldColourScheme.findColour(aa, -1);
+    }
+    catch (Exception ex)
+    {}
+
+    button.setBackground(col);
+    oldColours.addElement(col);
+    button.setLabel(label);
+    button.setForeground(col.darker().darker().darker());
+    button.setFont(new java.awt.Font("Verdana", 1, 10));
+    button.addMouseListener(new java.awt.event.MouseAdapter()
+    {
+      public void mousePressed(MouseEvent e)
+      {
+        colourButtonPressed(e);
+      }
+    });
+
+    buttonPanel.add(button, null);
+  }
+
+  protected void okButton_actionPerformed()
+  {
+    applyButton_actionPerformed();
+    frame.setVisible(false);
+  }
+
+  protected void applyButton_actionPerformed()
+  {
+    if (caller != null)
+    {
+      if(caller instanceof FeatureSettings)
+        ((FeatureSettings)caller).setUserColour
+            (originalLabel, new Color(R,G,B));
+      else if(caller instanceof AnnotationColourChooser)
+      {
+        if (originalLabel.equals("Min Colour"))
+          ( (AnnotationColourChooser) caller).minColour_actionPerformed
+              (new Color(R, G, B));
+        else
+          ( (AnnotationColourChooser) caller).maxColour_actionPerformed
+              (new Color(R, G, B));
+      }
+      return;
+    }
+
+
+    Color[] newColours = new Color[24];
+    for (int i = 0; i < 24; i++)
+    {
+      Button button = (Button) buttonPanel.getComponent(i);
+      newColours[i] = button.getBackground();
+    }
+
+    UserColourScheme ucs = new UserColourScheme(newColours);
+    if(ap!=null)
+      ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
+
+    if(ap!=null)
+    {
+      if (seqGroup != null)
+      {
+        seqGroup.cs = ucs;
+      }
+      else
+      {
+        ap.av.setGlobalColourScheme(ucs);
+      }
+      ap.seqPanel.seqCanvas.img = null;
+      ap.repaint();
+    }
+    else if(pdbcanvas!=null)
+    {
+      pdbcanvas.pdb.setColours(ucs);
+      pdbcanvas.updateSeqColours();
+    }
+  }
+
+
+  protected void cancelButton_actionPerformed()
+  {
+    if (caller != null)
+    {
+      if(caller instanceof FeatureSettings)
+        ((FeatureSettings)caller).setUserColour
+            (originalLabel, originalColour);
+      else if (caller instanceof AnnotationColourChooser)
+      {
+        if (originalLabel.equals("Min Colour"))
+          ( (AnnotationColourChooser) caller).minColour_actionPerformed
+              (originalColour);
+        else
+          ( (AnnotationColourChooser) caller).maxColour_actionPerformed
+              (originalColour);
+      }
+      frame.setVisible(false);
+      return;
+    }
+
+    Color[] newColours = new Color[24];
+    for (int i = 0; i < 24; i++)
+    {
+      newColours[i] = (Color) oldColours.elementAt(i);
+      buttonPanel.getComponent(i).setBackground(newColours[i]);
+    }
+
+    UserColourScheme ucs = new UserColourScheme(newColours);
+
+   if(ap!=null)
+    {
+      if (seqGroup != null)
+      {
+        seqGroup.cs = ucs;
+      }
+      else
+      {
+        ap.av.setGlobalColourScheme(ucs);
+      }
+      ap.repaint();
+    }
+    else if(pdbcanvas!=null)
+    {
+      pdbcanvas.pdb.setColours(ucs);
+    }
+
+    frame.setVisible(false);
+  }
+
+
+  protected Panel buttonPanel = new Panel();
+  protected GridLayout gridLayout = new GridLayout();
+  Panel okcancelPanel = new Panel();
+  protected Button okButton = new Button();
+  protected Button applyButton = new Button();
+  protected Button cancelButton = new Button();
+  protected Scrollbar rScroller = new Scrollbar();
+  Label label1 = new Label();
+  protected TextField rText = new TextField();
+  Label label4 = new Label();
+  protected Scrollbar gScroller = new Scrollbar();
+  protected TextField gText = new TextField();
+  Label label5 = new Label();
+  protected Scrollbar bScroller = new Scrollbar();
+  protected TextField bText = new TextField();
+  protected Panel target = new Panel();
+
+  private void jbInit() throws Exception {
+      this.setLayout(null);
+      buttonPanel.setLayout(gridLayout);
+      gridLayout.setColumns(6);
+      gridLayout.setRows(4);
+      okButton.setFont(new java.awt.Font("Verdana", 0, 11));
+      okButton.setLabel("OK");
+      okButton.addActionListener(this);
+      applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
+      applyButton.setLabel("Apply");
+      applyButton.addActionListener(this);
+      cancelButton.setFont(new java.awt.Font("Verdana", 0, 11));
+      cancelButton.setLabel("Cancel");
+      cancelButton.addActionListener(this);
+      this.setBackground(new Color(212, 208, 223));
+      okcancelPanel.setBounds(new Rectangle(0, 265, 400, 35));
+      buttonPanel.setBounds(new Rectangle(0, 123, 400, 142));
+      rScroller.setMaximum(256);
+      rScroller.setMinimum(0);
+      rScroller.setOrientation(0);
+      rScroller.setUnitIncrement(1);
+  rScroller.setVisibleAmount(1);
+  rScroller.setBounds(new Rectangle(36, 27, 119, 19));
+  rScroller.addAdjustmentListener(this);
+  label1.setAlignment(Label.RIGHT);
+  label1.setText("R");
+  label1.setBounds(new Rectangle(19, 30, 16, 15));
+  rText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));
+  rText.setText("0        ");
+  rText.setBounds(new Rectangle(156, 27, 53, 19));
+  rText.addActionListener(this);
+  label4.setAlignment(Label.RIGHT);
+  label4.setText("G");
+  label4.setBounds(new Rectangle(15, 56, 20, 15));
+  gScroller.setMaximum(256);
+      gScroller.setMinimum(0);
+      gScroller.setOrientation(0);
+      gScroller.setUnitIncrement(1);
+  gScroller.setVisibleAmount(1);
+  gScroller.setBounds(new Rectangle(35, 52, 120, 20));
+  gScroller.addAdjustmentListener(this);
+  gText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));
+  gText.setText("0        ");
+  gText.setBounds(new Rectangle(156, 52, 53, 20));
+  gText.addActionListener(this);
+  label5.setAlignment(Label.RIGHT);
+  label5.setText("B");
+  label5.setBounds(new Rectangle(14, 82, 20, 15));
+  bScroller.setMaximum(256);
+      bScroller.setMinimum(0);
+      bScroller.setOrientation(0);
+      bScroller.setUnitIncrement(1);
+  bScroller.setVisibleAmount(1);
+  bScroller.setBounds(new Rectangle(35, 78, 120, 20));
+  bScroller.addAdjustmentListener(this);
+  bText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));
+  bText.setText("0        ");
+  bText.setBounds(new Rectangle(157, 78, 52, 20));
+  bText.addActionListener(this);
+  target.setBackground(Color.black);
+      target.setBounds(new Rectangle(229, 26, 134, 79));
+      this.add(okcancelPanel, null);
+      okcancelPanel.add(okButton, null);
+      okcancelPanel.add(applyButton, null);
+      okcancelPanel.add(cancelButton, null);
+      this.add(buttonPanel, null);
+  this.add(target, null);
+  this.add(gScroller);
+  this.add(rScroller);
+  this.add(bScroller);
+  this.add(label5);
+  this.add(label4);
+  this.add(label1);
+  this.add(gText);
+  this.add(rText);
+  this.add(bText);
+}
+
+}
index 9702a92..a43714f 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.bin;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.apache.log4j.SimpleLayout;\r
-import org.apache.log4j.Level;\r
-import org.apache.log4j.ConsoleAppender;\r
-\r
-\r
-/**\r
- * Stores and retrieves Jalview Application Properties\r
- * <br><br>Current properties include:\r
- * <br>logs.Axis.Level - one of the stringified Levels for log4j controlling the logging level for axis (used for web services)\r
- * <br>logs.Castor.Level - one of the stringified Levels for log4j controlling the logging level for castor (used for serialization)\r
- * <br>logs.Jalview.Level - Cache.log stringified level.\r
- * <br>DISCOVERY_START - Boolean - controls if discovery services are queried on startup\r
- * <br>DISCOVERY_URLS - comma separated list of Discovery Service endpoints.\r
- * <br>SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_Y=285,SCREEN_X=371,SHOW_FULLSCREEN\r
- * FONT_NAME,FONT_SIZE,FONT_STYLE,GAP_SYMBOL,LAST_DIRECTORY,USER_DEFINED_COLOUR\r
- * SHOW_FULL_ID,SHOW_IDENTITY,SHOW_QUALITY,SHOW_ANNOTATIONS,SHOW_CONSERVATION,\r
- * DEFAULT_COLOUR,DEFAULT_FILE_FORMAT,STARTUP_FILE,SHOW_STARTUP_FILE\r
-\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Cache\r
-{\r
-  /**\r
-   * Initialises the Apache Axis logger\r
-   */\r
-  public static Logger log;\r
-\r
-    /** Jalview Properties */\r
-    public static Properties applicationProperties = new Properties();\r
-\r
-    /** Default file is  ~/.jalview_properties */\r
-    static String propertiesFile;\r
-\r
-    public static void initLogger()\r
-    {\r
-      try\r
-      {\r
-        Logger laxis = Logger.getLogger("org.apache.axis");\r
-        Logger lcastor = Logger.getLogger("org.exolab.castor");\r
-        jalview.bin.Cache.log = Logger.getLogger("jalview.bin.Jalview");\r
-\r
-        laxis.setLevel(Level.toLevel(Cache.getDefault("logs.Axis.Level",\r
-            Level.INFO.toString())));\r
-        lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",\r
-            Level.INFO.toString())));\r
-        jalview.bin.Cache.log.setLevel(Level.toLevel(Cache.getDefault(\r
-            "logs.Jalview.level",\r
-            Level.INFO.toString())));\r
-        ConsoleAppender ap = new ConsoleAppender(new SimpleLayout(),\r
-                                                 "System.err");\r
-        ap.setName("JalviewLogger");\r
-\r
-        laxis.addAppender(ap);\r
-        lcastor.addAppender(ap);\r
-        jalview.bin.Cache.log.addAppender(ap);\r
-        // Tell the user that debug is enabled\r
-        jalview.bin.Cache.log.debug("Jalview Debugging Output Follows.");\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-      System.err.println("Problems initializing the log4j system\n");\r
-      }\r
-    }\r
-\r
-\r
-    /** Called when Jalview is started */\r
-    public static void loadProperties(String propsFile)\r
-    {\r
-        propertiesFile = propsFile;\r
-        if (propsFile == null)\r
-        {\r
-          propertiesFile = System.getProperty("user.home") + "/.jalview_properties";\r
-        }\r
-\r
-        try\r
-        {\r
-            FileInputStream fis = new FileInputStream(propertiesFile);\r
-            applicationProperties.load(fis);\r
-            applicationProperties.remove("LATEST_VERSION");\r
-            applicationProperties.remove("VERSION");\r
-            fis.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          System.out.println("Error reading properties file: "+ex);\r
-        }\r
-\r
-      if(getDefault("USE_PROXY", false))\r
-      {\r
-          System.out.println("Using proxyServer: "+getDefault("PROXY_SERVER", null)+\r
-                           " proxyPort: "+getDefault("PROXY_PORT", null));\r
-          System.setProperty("http.proxyHost", getDefault("PROXY_SERVER", null));\r
-          System.setProperty("http.proxyPort", getDefault("PROXY_PORT", null));\r
-      }\r
-\r
-        // FIND THE VERSION NUMBER AND BUILD DATE FROM jalview.jar\r
-        // MUST FOLLOW READING OF LOCAL PROPERTIES FILE AS THE\r
-        // VERSION MAY HAVE CHANGED SINCE LAST USING JALVIEW\r
-         try\r
-         {\r
-             String buildDetails = "jar:"\r
-                 .concat(\r
-                 Cache.class.getProtectionDomain().getCodeSource().getLocation().toString()\r
-                 .concat("!/.build_properties")\r
-                 );\r
-\r
-             java.net.URL localJarFileURL = new java.net.URL(buildDetails);\r
-\r
-            InputStream in = localJarFileURL.openStream();\r
-            applicationProperties.load(in);\r
-            in.close();\r
-         }\r
-         catch (Exception ex)\r
-         {\r
-           System.out.println("Error reading build details: "+ex);\r
-           applicationProperties.remove("VERSION");\r
-        }\r
-\r
-        String jnlpVersion = System.getProperty("jalview.version");\r
-        String codeVersion = getProperty("VERSION");\r
-\r
-\r
-        if(codeVersion==null)\r
-        {\r
-          // THIS SHOULD ONLY BE THE CASE WHEN TESTING!!\r
-          codeVersion = "Test";\r
-          jnlpVersion = "Test";\r
-        }\r
-\r
-\r
-        System.out.println("Jalview Version: "+codeVersion);\r
-\r
-\r
-        // jnlpVersion will be null if we're using InstallAnywhere\r
-        // Dont do this check if running in headless mode\r
-        if(jnlpVersion==null && (\r
-                System.getProperty("java.awt.headless")==null\r
-             || System.getProperty("java.awt.headless").equals("false")))\r
-        {\r
-\r
-          class VersionChecker\r
-              extends Thread\r
-          {\r
-            public void run()\r
-            {\r
-              String jnlpVersion = null;\r
-              try\r
-              {\r
-                java.net.URL url = new java.net.URL(\r
-                    "http://www.jalview.org/webstart/jalview.jnlp");\r
-                BufferedReader in = new BufferedReader(new InputStreamReader(url.\r
-                    openStream()));\r
-                String line = null;\r
-                while ( (line = in.readLine()) != null)\r
-                {\r
-                  if (line.indexOf("jalview.version") == -1)\r
-                    continue;\r
-\r
-                  line = line.substring(line.indexOf("value=") + 7);\r
-                  line = line.substring(0, line.lastIndexOf("\""));\r
-                  jnlpVersion = line;\r
-                  break;\r
-                }\r
-              }\r
-              catch (Exception ex)\r
-              {\r
-                System.out.println(ex);\r
-                jnlpVersion = getProperty("VERSION");\r
-              }\r
-\r
-              setProperty("LATEST_VERSION", jnlpVersion);\r
-            }\r
-          }\r
-\r
-          VersionChecker vc = new VersionChecker();\r
-          vc.start();\r
-        }\r
-        else\r
-        {\r
-          if(jnlpVersion!=null)\r
-            setProperty("LATEST_VERSION", jnlpVersion);\r
-          else\r
-          applicationProperties.remove("LATEST_VERSION");\r
-        }\r
-\r
-        setProperty("VERSION", codeVersion);\r
-\r
-        //LOAD USERDEFINED COLOURS\r
-        jalview.gui.UserDefinedColours.initUserColourSchemes( getProperty("USER_DEFINED_COLOURS"));\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * Gets Jalview application property of given key. Returns null\r
-     * if key not found\r
-     *\r
-     * @param key Name of property\r
-     *\r
-     * @return Property value\r
-     */\r
-    public static String getProperty(String key)\r
-    {\r
-        return applicationProperties.getProperty(key);\r
-    }\r
-\r
-\r
-    /** These methods are used when checking if the saved preference\r
-     * is different to the default setting\r
-     */\r
-\r
-    public static boolean getDefault(String property, boolean def)\r
-    {\r
-      String string = getProperty(property);\r
-      if (string != null)\r
-      {\r
-        def = Boolean.valueOf(string).booleanValue();\r
-      }\r
-\r
-      return def;\r
-    }\r
-\r
-    /** These methods are used when checking if the saved preference\r
-    * is different to the default setting\r
-    */\r
-    public static String getDefault(String property, String def)\r
-    {\r
-      String string = getProperty(property);\r
-      if (string != null)\r
-      {\r
-        return string;\r
-      }\r
-\r
-      return def;\r
-    }\r
-\r
-\r
-    /**\r
-     * Stores property in the file "HOME_DIR/.jalview_properties"\r
-     *\r
-     * @param key Name of object\r
-     * @param obj String value of property\r
-     *\r
-     * @return String value of property\r
-     */\r
-    public static String setProperty(String key, String obj)\r
-    {\r
-        try\r
-        {\r
-            FileOutputStream out = new FileOutputStream(propertiesFile);\r
-            applicationProperties.setProperty(key, obj);\r
-            applicationProperties.store(out, "---JalviewX Properties File---");\r
-            out.close();\r
-        }\r
-        catch (Exception ex)\r
-        {   System.out.println("Error setting property: "+key+" "+obj+"\n"+ex);   }\r
-        return obj;\r
-    }\r
-\r
-    public static void saveProperties()\r
-    {\r
-        try\r
-        {\r
-            FileOutputStream out = new FileOutputStream(propertiesFile);\r
-            applicationProperties.store(out, "---JalviewX Properties File---");\r
-            out.close();\r
-        }\r
-        catch (Exception ex)\r
-        {  System.out.println("Error saving properties: "+ex);  }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.bin;
+
+import java.io.*;
+
+import java.util.*;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.SimpleLayout;
+import org.apache.log4j.Level;
+import org.apache.log4j.ConsoleAppender;
+
+
+/**
+ * Stores and retrieves Jalview Application Properties
+ * <br><br>Current properties include:
+ * <br>logs.Axis.Level - one of the stringified Levels for log4j controlling the logging level for axis (used for web services)
+ * <br>logs.Castor.Level - one of the stringified Levels for log4j controlling the logging level for castor (used for serialization)
+ * <br>logs.Jalview.Level - Cache.log stringified level.
+ * <br>DISCOVERY_START - Boolean - controls if discovery services are queried on startup
+ * <br>DISCOVERY_URLS - comma separated list of Discovery Service endpoints.
+ * <br>SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_Y=285,SCREEN_X=371,SHOW_FULLSCREEN
+ * FONT_NAME,FONT_SIZE,FONT_STYLE,GAP_SYMBOL,LAST_DIRECTORY,USER_DEFINED_COLOUR
+ * SHOW_FULL_ID,SHOW_IDENTITY,SHOW_QUALITY,SHOW_ANNOTATIONS,SHOW_CONSERVATION,
+ * DEFAULT_COLOUR,DEFAULT_FILE_FORMAT,STARTUP_FILE,SHOW_STARTUP_FILE
+
+ * @author $author$
+ * @version $Revision$
+ */
+public class Cache
+{
+  /**
+   * Initialises the Apache Axis logger
+   */
+  public static Logger log;
+
+    /** Jalview Properties */
+    public static Properties applicationProperties = new Properties();
+
+    /** Default file is  ~/.jalview_properties */
+    static String propertiesFile;
+
+    public static void initLogger()
+    {
+      try
+      {
+        Logger laxis = Logger.getLogger("org.apache.axis");
+        Logger lcastor = Logger.getLogger("org.exolab.castor");
+        jalview.bin.Cache.log = Logger.getLogger("jalview.bin.Jalview");
+
+        laxis.setLevel(Level.toLevel(Cache.getDefault("logs.Axis.Level",
+            Level.INFO.toString())));
+        lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
+            Level.INFO.toString())));
+        jalview.bin.Cache.log.setLevel(Level.toLevel(Cache.getDefault(
+            "logs.Jalview.level",
+            Level.INFO.toString())));
+        ConsoleAppender ap = new ConsoleAppender(new SimpleLayout(),
+                                                 "System.err");
+        ap.setName("JalviewLogger");
+
+        laxis.addAppender(ap);
+        lcastor.addAppender(ap);
+        jalview.bin.Cache.log.addAppender(ap);
+        // Tell the user that debug is enabled
+        jalview.bin.Cache.log.debug("Jalview Debugging Output Follows.");
+      }
+      catch (Exception ex)
+      {
+      System.err.println("Problems initializing the log4j system\n");
+      }
+    }
+
+
+    /** Called when Jalview is started */
+    public static void loadProperties(String propsFile)
+    {
+        propertiesFile = propsFile;
+        if (propsFile == null)
+        {
+          propertiesFile = System.getProperty("user.home") + "/.jalview_properties";
+        }
+
+        try
+        {
+            FileInputStream fis = new FileInputStream(propertiesFile);
+            applicationProperties.load(fis);
+            applicationProperties.remove("LATEST_VERSION");
+            applicationProperties.remove("VERSION");
+            fis.close();
+        }
+        catch (Exception ex)
+        {
+          System.out.println("Error reading properties file: "+ex);
+        }
+
+      if(getDefault("USE_PROXY", false))
+      {
+          System.out.println("Using proxyServer: "+getDefault("PROXY_SERVER", null)+
+                           " proxyPort: "+getDefault("PROXY_PORT", null));
+          System.setProperty("http.proxyHost", getDefault("PROXY_SERVER", null));
+          System.setProperty("http.proxyPort", getDefault("PROXY_PORT", null));
+      }
+
+        // FIND THE VERSION NUMBER AND BUILD DATE FROM jalview.jar
+        // MUST FOLLOW READING OF LOCAL PROPERTIES FILE AS THE
+        // VERSION MAY HAVE CHANGED SINCE LAST USING JALVIEW
+         try
+         {
+             String buildDetails = "jar:"
+                 .concat(
+                 Cache.class.getProtectionDomain().getCodeSource().getLocation().toString()
+                 .concat("!/.build_properties")
+                 );
+
+             java.net.URL localJarFileURL = new java.net.URL(buildDetails);
+
+            InputStream in = localJarFileURL.openStream();
+            applicationProperties.load(in);
+            in.close();
+         }
+         catch (Exception ex)
+         {
+           System.out.println("Error reading build details: "+ex);
+           applicationProperties.remove("VERSION");
+        }
+
+        String jnlpVersion = System.getProperty("jalview.version");
+        String codeVersion = getProperty("VERSION");
+
+
+        if(codeVersion==null)
+        {
+          // THIS SHOULD ONLY BE THE CASE WHEN TESTING!!
+          codeVersion = "Test";
+          jnlpVersion = "Test";
+        }
+
+
+        System.out.println("Jalview Version: "+codeVersion);
+
+
+        // jnlpVersion will be null if we're using InstallAnywhere
+        // Dont do this check if running in headless mode
+        if(jnlpVersion==null && (
+                System.getProperty("java.awt.headless")==null
+             || System.getProperty("java.awt.headless").equals("false")))
+        {
+
+          class VersionChecker
+              extends Thread
+          {
+            public void run()
+            {
+              String jnlpVersion = null;
+              try
+              {
+                java.net.URL url = new java.net.URL(
+                    "http://www.jalview.org/webstart/jalview.jnlp");
+                BufferedReader in = new BufferedReader(new InputStreamReader(url.
+                    openStream()));
+                String line = null;
+                while ( (line = in.readLine()) != null)
+                {
+                  if (line.indexOf("jalview.version") == -1)
+                    continue;
+
+                  line = line.substring(line.indexOf("value=") + 7);
+                  line = line.substring(0, line.lastIndexOf("\""));
+                  jnlpVersion = line;
+                  break;
+                }
+              }
+              catch (Exception ex)
+              {
+                System.out.println(ex);
+                jnlpVersion = getProperty("VERSION");
+              }
+
+              setProperty("LATEST_VERSION", jnlpVersion);
+            }
+          }
+
+          VersionChecker vc = new VersionChecker();
+          vc.start();
+        }
+        else
+        {
+          if(jnlpVersion!=null)
+            setProperty("LATEST_VERSION", jnlpVersion);
+          else
+          applicationProperties.remove("LATEST_VERSION");
+        }
+
+        setProperty("VERSION", codeVersion);
+
+        //LOAD USERDEFINED COLOURS
+        jalview.gui.UserDefinedColours.initUserColourSchemes( getProperty("USER_DEFINED_COLOURS"));
+        jalview.io.PIRFile.useModellerOutput = Cache.getDefault("PIR_MODELLER", false);
+    }
+
+
+
+    /**
+     * Gets Jalview application property of given key. Returns null
+     * if key not found
+     *
+     * @param key Name of property
+     *
+     * @return Property value
+     */
+    public static String getProperty(String key)
+    {
+        return applicationProperties.getProperty(key);
+    }
+
+
+    /** These methods are used when checking if the saved preference
+     * is different to the default setting
+     */
+
+    public static boolean getDefault(String property, boolean def)
+    {
+      String string = getProperty(property);
+      if (string != null)
+      {
+        def = Boolean.valueOf(string).booleanValue();
+      }
+
+      return def;
+    }
+
+    /** These methods are used when checking if the saved preference
+    * is different to the default setting
+    */
+    public static String getDefault(String property, String def)
+    {
+      String string = getProperty(property);
+      if (string != null)
+      {
+        return string;
+      }
+
+      return def;
+    }
+
+
+    /**
+     * Stores property in the file "HOME_DIR/.jalview_properties"
+     *
+     * @param key Name of object
+     * @param obj String value of property
+     *
+     * @return String value of property
+     */
+    public static String setProperty(String key, String obj)
+    {
+        try
+        {
+            FileOutputStream out = new FileOutputStream(propertiesFile);
+            applicationProperties.setProperty(key, obj);
+            applicationProperties.store(out, "---JalviewX Properties File---");
+            out.close();
+        }
+        catch (Exception ex)
+        {   System.out.println("Error setting property: "+key+" "+obj+"\n"+ex);   }
+        return obj;
+    }
+
+    public static void saveProperties()
+    {
+        try
+        {
+            FileOutputStream out = new FileOutputStream(propertiesFile);
+            applicationProperties.store(out, "---JalviewX Properties File---");
+            out.close();
+        }
+        catch (Exception ex)
+        {  System.out.println("Error saving properties: "+ex);  }
+    }
+}
index a734054..a31a971 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.bin;\r
-\r
-import jalview.gui.*;\r
-\r
-import javax.swing.*;\r
-\r
-import java.util.Vector;\r
-\r
-\r
-/**\r
- * Main class for Jalview Application\r
- * <br>\r
- * <br>start with java -Djava.ext.dirs=$PATH_TO_LIB$ jalview.bin.Jalview\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Jalview\r
-{\r
-\r
-    /**\r
-     * main class for Jalview application\r
-     *\r
-     * @param args open <em>filename</em>\r
-     */\r
-    public static void main(String[] args)\r
-    {\r
-      System.out.println("Java version: "+System.getProperty("java.version"));\r
-      System.out.println(System.getProperty("os.arch")+" "\r
-                         +System.getProperty("os.name")+" "\r
-                         +System.getProperty("os.version"));\r
-\r
-\r
-      ArgsParser aparser = new ArgsParser(args);\r
-      boolean headless = false;\r
-\r
-      if( aparser.contains("help") || aparser.contains("h") )\r
-      {\r
-        System.out.println("Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"\r
-                           +"-nodisplay\tRun Jalview without User Interface.\n"\r
-                           +"-props FILE\tUse the given Jalview properties file instead of users default.\n"\r
-                           +"-groups FILE\tUse the given file to mark groups on the alignment."\r
-                           +"\nThe first lines of the groups file lists the GroupName and GroupColours"\r
-                           +" to be used in the alignment. Use the GROUPNAME label for each of your sequences. "\r
-                           +"\nGROUPNAME<tab>GROUPCOLOUR\n"\r
-                           +"TEXT<tab>SEQUENCE_ID<tab>SEQUENCE_INDEX<tab>START_RESIDUE<tab>END_RESIDUE<tab>GROUPNAME\n"\r
-                           +"SequenceID is used in preference to SequenceIndex if both are provided.\n"\r
-                           +"Enter ID_NOT_SPECIFIED for SEQUENCE_ID or -1 for SEQUENCE_INDEX if unknown.\n"\r
-                           +"COLOUR can be hexadecimal RGB or 'red', 'blue' etc.\n\n"\r
-                           +"-fasta FILE\tCreate alignment file FILE in Fasta format.\n"\r
-                           +"-clustal FILE\tCreate alignment file FILE in Clustal format.\n"\r
-                           +"-pfam FILE\tCreate alignment file FILE in PFAM format.\n"\r
-                           +"-msf FILE\tCreate alignment file FILE in MSF format.\n"\r
-                           +"-pileup FILE\tCreate alignment file FILE in Pileup format\n"\r
-                           +"-pir FILE\tCreate alignment file FILE in PIR format.\n"\r
-                           +"-blc FILE\tCreate alignment file FILE in BLC format.\n"\r
-                           +"-jalview FILE\tCreate alignment file FILE in Jalview format.\n"\r
-                           +"-png FILE\tCreate PNG image FILE from alignment.\n"\r
-                           +"-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"\r
-                           +"-eps FILE\tCreate EPS file FILE from alignment.");\r
-        System.exit(0);\r
-          }\r
-\r
-          Cache.loadProperties(aparser.getValue("props")); // must do this before anything else!\r
-\r
-          if (aparser.contains("nodisplay"))\r
-          {\r
-            System.setProperty("java.awt.headless", "true");\r
-          }\r
-          if (System.getProperty("java.awt.headless") != null\r
-              && System.getProperty("java.awt.headless").equals("true"))\r
-          {\r
-            headless = true;\r
-          }\r
-\r
-          try\r
-          {\r
-            Cache.initLogger();\r
-          }\r
-          catch (java.lang.NoClassDefFoundError error)\r
-          {\r
-            error.printStackTrace();\r
-            System.out.println(\r
-                "\nEssential logging libraries not found."\r
-                +"\nUse: java -Djava.ext.dirs=$PATH_TO_LIB$ jalview.bin.Jalview");\r
-            System.exit(0);\r
-          }\r
-\r
-        Desktop desktop = null;\r
-        if( !headless )\r
-        {\r
-          try\r
-          {\r
-            UIManager.setLookAndFeel(\r
-                   UIManager.getSystemLookAndFeelClassName()\r
-            //        UIManager.getCrossPlatformLookAndFeelClassName()\r
-//"com.sun.java.swing.plaf.gtk.GTKLookAndFeel"\r
-//"javax.swing.plaf.metal.MetalLookAndFeel"\r
-//"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"\r
-//"com.sun.java.swing.plaf.motif.MotifLookAndFeel"\r
-\r
-                );\r
-          }\r
-          catch (Exception ex)\r
-          {\r
-          }\r
-\r
-          desktop = new Desktop();\r
-          desktop.setVisible(true);\r
-          desktop.discoverer.start();\r
-        }\r
-\r
-\r
-         String file = null, protocol = null, format = null, groups=null;\r
-         jalview.io.FileLoader fileLoader = new jalview.io.FileLoader();\r
-\r
-          file = aparser.getValue("open");\r
-\r
-          if (file == null && desktop==null)\r
-          {\r
-            System.out.println("No files to open!");\r
-            System.exit(1);\r
-          }\r
-\r
-          if(file!=null)\r
-          {\r
-\r
-            if (!file.startsWith("http://"))\r
-            {\r
-              if (! (new java.io.File(file)).exists())\r
-              {\r
-                System.out.println("Can't find " + file);\r
-                if(headless)\r
-                  System.exit(1);\r
-              }\r
-            }\r
-\r
-            protocol = "File";\r
-\r
-            if (file.indexOf("http:") > -1)\r
-            {\r
-              protocol = "URL";\r
-            }\r
-\r
-            if (file.endsWith(".jar"))\r
-              format = "Jalview";\r
-            else\r
-              format = new jalview.io.IdentifyFile().Identify(file, protocol);\r
-\r
-            System.out.println("Opening: " + format + " file " + file);\r
-\r
-            AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);\r
-\r
-            groups = aparser.getValue("groups");\r
-            if (groups != null)\r
-            {\r
-              af.parseGroupsFile(groups);\r
-            }\r
-\r
-            String imageName = "unnamed.png";\r
-            while (aparser.getSize() > 1)\r
-            {\r
-              format = aparser.nextValue();\r
-              file = aparser.nextValue();\r
-\r
-              if (format.equalsIgnoreCase("png"))\r
-              {\r
-                af.createPNG(new java.io.File(file));\r
-                imageName = (new java.io.File(file)).getName();\r
-                System.out.println("Creating PNG image: " + file);\r
-                continue;\r
-              }\r
-              else if (format.equalsIgnoreCase("imgMap"))\r
-              {\r
-                af.createImageMap(new java.io.File(file), imageName);\r
-                System.out.println("Creating image map: " + file);\r
-                continue;\r
-              }\r
-              else if (format.equalsIgnoreCase("eps"))\r
-              {\r
-                System.out.println("Creating EPS file: " + file);\r
-                af.createEPS(new java.io.File(file));\r
-                continue;\r
-              }\r
-\r
-              if (af.saveAlignment(file, format))\r
-                System.out.println("Written alignment in " + format +\r
-                                   " format to " + file);\r
-              else\r
-                System.out.println("Error writing file " + file + " in " + format +\r
-                                   " format!!");\r
-\r
-            }\r
-\r
-            while (aparser.getSize() > 0)\r
-            {\r
-              System.out.println("Unknown arg: " + aparser.nextValue());\r
-            }\r
-          }\r
-\r
-        // We'll only open the default file if the desktop is visible.\r
-        //////////////////////\r
-          if (\r
-              !headless &&\r
-              jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))\r
-          {\r
-\r
-            file = jalview.bin.Cache.getDefault("STARTUP_FILE",\r
-                                                "http://www.jalview.org/examples/exampleFile.jar");\r
-            protocol = "File";\r
-\r
-            if (file.indexOf("http:") > -1)\r
-            {\r
-              protocol = "URL";\r
-            }\r
-\r
-            if (file.endsWith(".jar"))\r
-            {\r
-              Jalview2XML.LoadJalviewAlign(file);\r
-            }\r
-            else\r
-            {\r
-              format = new jalview.io.IdentifyFile().Identify(file, protocol);\r
-              desktop.LoadFile(file, protocol, format);\r
-            }\r
-          }\r
-    }\r
-}\r
-\r
- class ArgsParser\r
- {\r
-   Vector vargs = null;\r
-   public ArgsParser(String [] args)\r
-   {\r
-     vargs = new Vector();\r
-     for (int i = 0; i < args.length; i++)\r
-     {\r
-       String arg = args[i].trim();\r
-       if (arg.charAt(0) == '-')\r
-         arg = arg.substring(1);\r
-       vargs.addElement(arg);\r
-     }\r
-   }\r
-\r
-   public String getValue(String arg)\r
-   {\r
-     int index = vargs.indexOf(arg);\r
-     String ret = null;\r
-     if (index != -1)\r
-     {\r
-       ret = vargs.elementAt(index + 1).toString();\r
-       vargs.removeElementAt(index);\r
-       vargs.removeElementAt(index);\r
-     }\r
-     return ret;\r
-   }\r
-\r
-   public boolean contains(String arg)\r
-   {\r
-     if(vargs.contains(arg))\r
-     {\r
-       vargs.removeElement(arg);\r
-       return true;\r
-     }\r
-     else\r
-       return false;\r
-   }\r
-\r
-   public String nextValue()\r
-   {\r
-     return  vargs.remove(0).toString();\r
-   }\r
-\r
-   public int getSize()\r
-   {\r
-     return vargs.size();\r
-   }\r
-\r
- }\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.bin;
+
+import jalview.gui.*;
+
+import javax.swing.*;
+
+import java.util.Vector;
+
+
+/**
+ * Main class for Jalview Application
+ * <br>
+ * <br>start with java -Djava.ext.dirs=$PATH_TO_LIB$ jalview.bin.Jalview
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Jalview
+{
+
+    /**
+     * main class for Jalview application
+     *
+     * @param args open <em>filename</em>
+     */
+    public static void main(String[] args)
+    {
+      System.out.println("Java version: "+System.getProperty("java.version"));
+      System.out.println(System.getProperty("os.arch")+" "
+                         +System.getProperty("os.name")+" "
+                         +System.getProperty("os.version"));
+
+
+      ArgsParser aparser = new ArgsParser(args);
+      boolean headless = false;
+
+      if( aparser.contains("help") || aparser.contains("h") )
+      {
+        System.out.println("Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
+                           +"-nodisplay\tRun Jalview without User Interface.\n"
+                           +"-props FILE\tUse the given Jalview properties file instead of users default.\n"
+                           +"-annotations FILE\tAdd precalculated annotations to the alignment.\n"
+                           +"-features FILE\tUse the given file to mark features on the alignment.\n"
+                           +"-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
+                           +"-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
+                           +"-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
+                           +"-msf FILE\tCreate alignment file FILE in MSF format.\n"
+                           +"-pileup FILE\tCreate alignment file FILE in Pileup format\n"
+                           +"-pir FILE\tCreate alignment file FILE in PIR format.\n"
+                           +"-blc FILE\tCreate alignment file FILE in BLC format.\n"
+                           +"-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
+                           +"-png FILE\tCreate PNG image FILE from alignment.\n"
+                           +"-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
+                           +"-eps FILE\tCreate EPS file FILE from alignment."
+            +"\n\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
+        System.exit(0);
+          }
+
+          Cache.loadProperties(aparser.getValue("props")); // must do this before anything else!
+
+          if (aparser.contains("nodisplay"))
+          {
+            System.setProperty("java.awt.headless", "true");
+          }
+          if (System.getProperty("java.awt.headless") != null
+              && System.getProperty("java.awt.headless").equals("true"))
+          {
+            headless = true;
+          }
+
+          try
+          {
+            Cache.initLogger();
+          }
+          catch (java.lang.NoClassDefFoundError error)
+          {
+            error.printStackTrace();
+            System.out.println(
+                "\nEssential logging libraries not found."
+                +"\nUse: java -Djava.ext.dirs=$PATH_TO_LIB$ jalview.bin.Jalview");
+            System.exit(0);
+          }
+
+        Desktop desktop = null;
+        if( !headless )
+        {
+          try
+          {
+            UIManager.setLookAndFeel(
+                UIManager.getSystemLookAndFeelClassName()
+                //        UIManager.getCrossPlatformLookAndFeelClassName()
+//"com.sun.java.swing.plaf.gtk.GTKLookAndFeel"
+//"javax.swing.plaf.metal.MetalLookAndFeel"
+//"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"
+//"com.sun.java.swing.plaf.motif.MotifLookAndFeel"
+
+                );
+          }
+          catch (Exception ex)
+          {
+          }
+
+          desktop = new Desktop();
+          desktop.setVisible(true);
+          desktop.discoverer.start();
+        }
+
+
+         String file = null, protocol = null, format = null, data=null;
+         jalview.io.FileLoader fileLoader = new jalview.io.FileLoader();
+
+          file = aparser.getValue("open");
+
+          if (file == null && desktop==null)
+          {
+            System.out.println("No files to open!");
+            System.exit(1);
+          }
+
+          if(file!=null)
+          {
+
+            if (!file.startsWith("http://"))
+            {
+              if (! (new java.io.File(file)).exists())
+              {
+                System.out.println("Can't find " + file);
+                if(headless)
+                  System.exit(1);
+              }
+            }
+
+            protocol = "File";
+
+            if (file.indexOf("http:") > -1 || file.indexOf("file:") >-1)
+            {
+              protocol = "URL";
+            }
+
+            if (file.endsWith(".jar"))
+              format = "Jalview";
+            else
+              format = new jalview.io.IdentifyFile().Identify(file, protocol);
+
+            System.out.println("Opening: " + format + " file " + file);
+
+            AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
+
+            data = aparser.getValue("colour");
+            if(data!=null)
+            {
+              data.replaceAll("%20", " ");
+
+              jalview.schemes.ColourSchemeI cs =
+                  jalview.schemes.ColourSchemeProperty.getColour(af.getViewport().
+                  getAlignment(), data);
+
+              if(cs == null)
+              {
+                jalview.schemes.UserColourScheme ucs
+                    = new jalview.schemes.UserColourScheme("white");
+                ucs.parseAppletParameter(data);
+                cs = ucs;
+              }
+
+              System.out.println("colour is " + data);
+              af.changeColour( cs );
+            }
+
+
+            // Must maintain ability to use the groups flag
+            data = aparser.getValue("groups");
+            if (data != null)
+            {
+              af.parseFeaturesFile(data, protocol);
+              System.out.println("Added "+data);
+            }
+            data = aparser.getValue("features");
+            if (data != null)
+            {
+              af.parseFeaturesFile(data, protocol);
+              System.out.println("Added "+data);
+            }
+
+            data = aparser.getValue("annotations");
+            if (data != null)
+            {
+              af.loadJalviewDataFile(data);
+              System.out.println("Added "+data);
+            }
+
+
+            String imageName = "unnamed.png";
+            while (aparser.getSize() > 1)
+            {
+              format = aparser.nextValue();
+              file = aparser.nextValue();
+
+              if (format.equalsIgnoreCase("png"))
+              {
+                af.createPNG(new java.io.File(file));
+                imageName = (new java.io.File(file)).getName();
+                System.out.println("Creating PNG image: " + file);
+                continue;
+              }
+              else if (format.equalsIgnoreCase("imgMap"))
+              {
+                af.createImageMap(new java.io.File(file), imageName);
+                System.out.println("Creating image map: " + file);
+                continue;
+              }
+              else if (format.equalsIgnoreCase("eps"))
+              {
+                System.out.println("Creating EPS file: " + file);
+                af.createEPS(new java.io.File(file));
+                continue;
+              }
+
+              if (af.saveAlignment(file, format))
+                System.out.println("Written alignment in " + format +
+                                   " format to " + file);
+              else
+                System.out.println("Error writing file " + file + " in " + format +
+                                   " format!!");
+
+            }
+
+            while (aparser.getSize() > 0)
+            {
+              System.out.println("Unknown arg: " + aparser.nextValue());
+            }
+          }
+
+        // We'll only open the default file if the desktop is visible.
+        // And the user
+        //////////////////////
+          if (
+              !headless
+          && file==null
+          && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true)
+                    )
+          {
+
+            file = jalview.bin.Cache.getDefault("STARTUP_FILE",
+                                                "http://www.jalview.org/examples/exampleFile.jar");
+
+            protocol = "File";
+
+            if (file.indexOf("http:") > -1)
+            {
+              protocol = "URL";
+            }
+
+            if (file.endsWith(".jar"))
+            {
+              new Jalview2XML().LoadJalviewAlign(file);
+            }
+            else
+            {
+              format = new jalview.io.IdentifyFile().Identify(file, protocol);
+              new jalview.io.FileLoader().LoadFile(file, protocol, format);
+            }
+          }
+    }
+}
+
+ class ArgsParser
+ {
+   Vector vargs = null;
+   public ArgsParser(String [] args)
+   {
+     vargs = new Vector();
+     for (int i = 0; i < args.length; i++)
+     {
+       String arg = args[i].trim();
+       if (arg.charAt(0) == '-')
+         arg = arg.substring(1);
+       vargs.addElement(arg);
+     }
+   }
+
+   public String getValue(String arg)
+   {
+     int index = vargs.indexOf(arg);
+     String ret = null;
+     if (index != -1)
+     {
+       ret = vargs.elementAt(index + 1).toString();
+       vargs.removeElementAt(index);
+       vargs.removeElementAt(index);
+     }
+     return ret;
+   }
+
+   public boolean contains(String arg)
+   {
+     if(vargs.contains(arg))
+     {
+       vargs.removeElement(arg);
+       return true;
+     }
+     else
+       return false;
+   }
+
+   public String nextValue()
+   {
+     return  vargs.remove(0).toString();
+   }
+
+   public int getSize()
+   {
+     return vargs.size();
+   }
+
+ }
index 199a843..9730eb2 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.bin;\r
-\r
-import jalview.appletgui.AlignFrame;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.io.*;\r
-\r
-import java.applet.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import jalview.appletgui.TreePanel;\r
-\r
-\r
-/**\r
- * Jalview Applet. Runs in Java 1.18 runtime\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class JalviewLite extends Applet\r
-{\r
-    static int lastFrameX = 200;\r
-    static int lastFrameY = 200;\r
-    boolean fileFound = true;\r
-    String file = "No file";\r
-    Button launcher = new Button("Start Jalview");\r
-\r
-    //The currentAlignFrame is static, it will change\r
-    //if and when the user selects a new window\r
-    static AlignFrame currentAlignFrame;\r
-\r
-    //This is the first frame to be displayed, and does not change\r
-    AlignFrame initialAlignFrame;\r
-\r
-    boolean embedded = false;\r
-\r
-\r
-    /**\r
-     * init method for Jalview Applet\r
-     */\r
-    public void init()\r
-    {\r
-        int r = 255;\r
-        int g = 255;\r
-        int b = 255;\r
-        String param = getParameter("RGB");\r
-\r
-        if (param != null)\r
-        {\r
-            try\r
-            {\r
-                r = Integer.parseInt(param.substring(0, 2), 16);\r
-                g = Integer.parseInt(param.substring(2, 4), 16);\r
-                b = Integer.parseInt(param.substring(4, 6), 16);\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                r = 255;\r
-                g = 255;\r
-                b = 255;\r
-            }\r
-        }\r
-\r
-        param = getParameter("label");\r
-        if(param != null)\r
-          launcher.setLabel(param);\r
-\r
-        this.setBackground(new Color(r, g, b));\r
-\r
-        file = getParameter("file");\r
-\r
-        final JalviewLite applet = this;\r
-        if(getParameter("embedded")!=null\r
-           && getParameter("embedded").equalsIgnoreCase("true"))\r
-        {\r
-          embedded = true;\r
-          LoadingThread loader = new LoadingThread(file, applet);\r
-          loader.start();\r
-        }\r
-        else if (file != null)\r
-        {\r
-            add(launcher);\r
-\r
-            launcher.addActionListener(new java.awt.event.ActionListener()\r
-                {\r
-                    public void actionPerformed(ActionEvent e)\r
-                    {\r
-                        LoadingThread loader = new LoadingThread(file,\r
-                            applet);\r
-                        loader.start();\r
-                      }\r
-                });\r
-        }\r
-        else\r
-        {\r
-            file = "NO FILE";\r
-            fileFound = false;\r
-        }\r
-    }\r
-\r
-\r
-    public static void main(String [] args)\r
-    {\r
-      if(args.length!=1)\r
-      {\r
-        System.out.println("\nUsage: java -jar jalviewApplet.jar fileName\n");\r
-        System.exit(1);\r
-      }\r
-\r
-      String format = new jalview.io.IdentifyFile().Identify(args[0],AppletFormatAdapter.FILE);\r
-\r
-      SequenceI[] sequences = null;\r
-     try{\r
-       sequences = new AppletFormatAdapter().readFile(args[0], AppletFormatAdapter.FILE, format);\r
-     }catch(java.io.IOException ex)\r
-     {\r
-       ex.printStackTrace();\r
-     }\r
-      if ( (sequences != null) && (sequences.length > 0))\r
-      {\r
-        AlignFrame af = new AlignFrame(new Alignment(sequences), null, args[0], false);\r
-        af.statusBar.setText("Successfully loaded file " + args[0]);\r
-      }\r
-    }\r
-\r
-\r
-    /**\r
-     * Initialises and displays a new java.awt.Frame\r
-     *\r
-     * @param frame java.awt.Frame to be displayed\r
-     * @param title title of new frame\r
-     * @param width width if new frame\r
-     * @param height height of new frame\r
-     */\r
-    public static void addFrame(final Frame frame, String title, int width,\r
-        int height)\r
-    {\r
-        frame.setLocation(lastFrameX, lastFrameY);\r
-        lastFrameX += 40;\r
-        lastFrameY += 40;\r
-        frame.setSize(width, height);\r
-        frame.setTitle(title);\r
-        frame.addWindowListener(new WindowAdapter()\r
-            {\r
-                public void windowClosing(WindowEvent e)\r
-                {\r
-                    if(currentAlignFrame == frame)\r
-                    {\r
-                      currentAlignFrame = null;\r
-                    }\r
-                    lastFrameX -=40;\r
-                    lastFrameY -=40;\r
-                    frame.setMenuBar(null);\r
-                    frame.dispose();\r
-                }\r
-                public void windowActivated(WindowEvent e)\r
-                {\r
-                  if(frame instanceof AlignFrame)\r
-                    currentAlignFrame = (AlignFrame)frame;\r
-                }\r
-\r
-            });\r
-        frame.setVisible(true);\r
-    }\r
-\r
-    public String getSelectedSequences()\r
-    {\r
-      StringBuffer result = new StringBuffer("");\r
-\r
-      if(initialAlignFrame.viewport.getSelectionGroup()!=null)\r
-      {\r
-        SequenceI[] seqs = initialAlignFrame.viewport.getSelectionGroup().\r
-            getSequencesInOrder(\r
-                initialAlignFrame.viewport.getAlignment());\r
-\r
-        for (int i = 0; i < seqs.length; i++)\r
-          result.append(seqs[i].getName() + "¬");\r
-      }\r
-\r
-      return result.toString();\r
-    }\r
-\r
-    public String getAlignment(String format)\r
-    {\r
-      return getAlignment(format, "true");\r
-    }\r
-\r
-    public String getAlignment(String format, String suffix)\r
-    {\r
-      try\r
-      {\r
-        boolean seqlimits = suffix.equalsIgnoreCase("true");\r
-\r
-        String reply = new AppletFormatAdapter().formatSequences(format,\r
-            currentAlignFrame.viewport.getAlignment().getSequences(), seqlimits);\r
-        return reply;\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-        return "Error retrieving alignment in " + format + " format. ";\r
-      }\r
-    }\r
-\r
-    /**\r
-     * This paints the background surrounding the "Launch Jalview button"\r
-     * <br>\r
-     * <br>If file given in parameter not found, displays error message\r
-     *\r
-     * @param g graphics context\r
-     */\r
-    public void paint(Graphics g)\r
-    {\r
-        if (!fileFound)\r
-        {\r
-            g.setColor(new Color(200, 200, 200));\r
-            g.setColor(Color.cyan);\r
-            g.fillRect(0, 0, getSize().width, getSize().height);\r
-            g.setColor(Color.red);\r
-            g.drawString("Jalview can't open file", 5, 15);\r
-            g.drawString("\"" + file + "\"", 5, 30);\r
-        }\r
-        else if(embedded)\r
-        {\r
-          g.setColor(Color.black);\r
-          g.setFont(new Font("Arial", Font.BOLD, 24));\r
-          g.drawString("Jalview Applet", 50, this.size().height/2 -30);\r
-          g.drawString("Loading Data...", 50, this.size().height/2);\r
-        }\r
-\r
-\r
-    }\r
-\r
-    class LoadingThread extends Thread\r
-    {\r
-        String file;\r
-        String protocol;\r
-        String format;\r
-        JalviewLite applet;\r
-\r
-        public LoadingThread(String _file,\r
-                             JalviewLite _applet)\r
-        {\r
-            file = _file;\r
-            if(inArchive(file))\r
-              protocol = AppletFormatAdapter.CLASSLOADER;\r
-            else\r
-            {\r
-              file = addProtocol(file);\r
-              protocol = AppletFormatAdapter.URL;\r
-            }\r
-            format = new jalview.io.IdentifyFile().Identify(file, protocol);\r
-            applet = _applet;\r
-        }\r
-\r
-        public void run()\r
-        {\r
-            SequenceI[] sequences = null;\r
-            try{\r
-              sequences = new AppletFormatAdapter().readFile(file, protocol,\r
-                  format);\r
-            }catch(java.io.IOException ex)\r
-            {\r
-              ex.printStackTrace();\r
-            }\r
-            if ((sequences != null) && (sequences.length > 0))\r
-            {\r
-              currentAlignFrame = new AlignFrame(new Alignment(sequences),\r
-                                                 applet,\r
-                                                 file,\r
-                                                 embedded);\r
-\r
-              initialAlignFrame = currentAlignFrame;\r
-\r
-              currentAlignFrame.statusBar.setText("Successfully loaded file " + file);\r
-\r
-\r
-                String treeFile = applet.getParameter("treeFile");\r
-                if (treeFile != null)\r
-                {\r
-                  try\r
-                  {\r
-                    if(inArchive(treeFile))\r
-                      protocol = AppletFormatAdapter.CLASSLOADER;\r
-                    else\r
-                    {\r
-                      protocol = AppletFormatAdapter.URL;\r
-                      treeFile = addProtocol(treeFile);\r
-                    }\r
-\r
-                    jalview.io.NewickFile fin = new jalview.io.NewickFile(treeFile, protocol);\r
-\r
-                    fin.parse();\r
-\r
-                    if (fin.getTree() != null)\r
-                    {\r
-                      currentAlignFrame.loadTree(fin, treeFile);\r
-                    }\r
-                  }\r
-                  catch (Exception ex)\r
-                  {\r
-                    ex.printStackTrace();\r
-                  }\r
-              }\r
-\r
-              String param = getParameter("features");\r
-              if (param != null)\r
-              {\r
-                if( !inArchive(param) )\r
-                  param = addProtocol( param );\r
-\r
-                currentAlignFrame.parseFeaturesFile(param);\r
-              }\r
-\r
-             param = getParameter("annotations");\r
-             if (param != null)\r
-             {\r
-               if( !inArchive(param) )\r
-                  param = addProtocol( param );\r
-\r
-               new AnnotationReader().readAnnotationFile(\r
-                   currentAlignFrame.viewport.getAlignment(),\r
-                   param);\r
-\r
-               currentAlignFrame.alignPanel.fontChanged();\r
-             }\r
-\r
-\r
-                String pdbfile = applet.getParameter("PDBFILE");\r
-                if(pdbfile!=null)\r
-                {\r
-                  if( inArchive(pdbfile) )\r
-                    protocol = AppletFormatAdapter.CLASSLOADER;\r
-                  else\r
-                  {\r
-                    protocol = AppletFormatAdapter.URL;\r
-                    pdbfile = addProtocol(pdbfile);\r
-                  }\r
-\r
-                  String sequence = applet.getParameter("PDBSEQ");\r
-\r
-                  if(sequence!=null)\r
-                  {\r
-                    new MCview.AppletPDBViewer(pdbfile, protocol,\r
-                                               (Sequence)currentAlignFrame.getAlignViewport().getAlignment().findName(sequence),\r
-                                               currentAlignFrame.getSeqcanvas());\r
-                  }\r
-\r
-                }\r
-            }\r
-            else\r
-            {\r
-                fileFound = false;\r
-                remove(launcher);\r
-                repaint();\r
-            }\r
-        }\r
-\r
-        /**\r
-         * Discovers whether the given file is in the Applet Archive\r
-         * @param file String\r
-         * @return boolean\r
-         */\r
-        boolean inArchive(String file)\r
-        {\r
-          //This might throw a security exception in certain browsers\r
-          //Netscape Communicator for instance.\r
-          try{\r
-            return (getClass().getResourceAsStream("/" + file) != null);\r
-          }catch(Exception ex)\r
-          {\r
-            System.out.println("Exception checking resources: "+file+" "+ex);\r
-            return false;\r
-          }\r
-        }\r
-\r
-        String addProtocol(String file)\r
-        {\r
-          if (file.indexOf("://") == -1)\r
-             file = getCodeBase() + file;\r
-\r
-          return file;\r
-        }\r
-\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.bin;
+
+import jalview.appletgui.AlignFrame;
+
+import jalview.datamodel.*;
+
+import jalview.io.*;
+
+import java.applet.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+
+/**
+ * Jalview Applet. Runs in Java 1.18 runtime
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class JalviewLite extends Applet
+{
+    static int lastFrameX = 200;
+    static int lastFrameY = 200;
+    boolean fileFound = true;
+    String file = "No file";
+    Button launcher = new Button("Start Jalview");
+
+    //The currentAlignFrame is static, it will change
+    //if and when the user selects a new window
+    static AlignFrame currentAlignFrame;
+
+    //This is the first frame to be displayed, and does not change
+    AlignFrame initialAlignFrame;
+
+    boolean embedded = false;
+
+
+    /**
+     * init method for Jalview Applet
+     */
+    public void init()
+    {
+        int r = 255;
+        int g = 255;
+        int b = 255;
+        String param = getParameter("RGB");
+
+        if (param != null)
+        {
+            try
+            {
+                r = Integer.parseInt(param.substring(0, 2), 16);
+                g = Integer.parseInt(param.substring(2, 4), 16);
+                b = Integer.parseInt(param.substring(4, 6), 16);
+            }
+            catch (Exception ex)
+            {
+                r = 255;
+                g = 255;
+                b = 255;
+            }
+        }
+
+        param = getParameter("label");
+        if(param != null)
+          launcher.setLabel(param);
+
+        this.setBackground(new Color(r, g, b));
+
+        file = getParameter("file");
+
+        if(file==null)
+        {
+          //Maybe the sequences are added as parameters
+          StringBuffer data = new StringBuffer("PASTE");
+          int i=1;
+          while( (file=getParameter("sequence"+i))!=null)
+          {
+            data.append(file.toString()+"\n");
+            i++;
+          }
+          if(data.length()>5)
+            file = data.toString();
+        }
+
+        final JalviewLite applet = this;
+        if(getParameter("embedded")!=null
+           && getParameter("embedded").equalsIgnoreCase("true"))
+        {
+          embedded = true;
+          LoadingThread loader = new LoadingThread(file, applet);
+          loader.start();
+        }
+        else if (file != null)
+        {
+            add(launcher);
+
+            launcher.addActionListener(new java.awt.event.ActionListener()
+                {
+                    public void actionPerformed(ActionEvent e)
+                    {
+                        LoadingThread loader = new LoadingThread(file,
+                            applet);
+                        loader.start();
+                      }
+                });
+        }
+        else
+        {
+            file = "NO FILE";
+            fileFound = false;
+        }
+    }
+
+
+    public static void main(String [] args)
+    {
+      if(args.length!=1)
+      {
+        System.out.println("\nUsage: java -jar jalviewApplet.jar fileName\n");
+        System.exit(1);
+      }
+
+      String format = new jalview.io.IdentifyFile().Identify(args[0],AppletFormatAdapter.FILE);
+
+      SequenceI[] sequences = null;
+     try{
+       sequences = new AppletFormatAdapter().readFile(args[0], AppletFormatAdapter.FILE, format);
+     }catch(java.io.IOException ex)
+     {
+       ex.printStackTrace();
+     }
+      if ( (sequences != null) && (sequences.length > 0))
+      {
+        AlignFrame af = new AlignFrame(new Alignment(sequences), null, args[0], false);
+        af.statusBar.setText("Successfully loaded file " + args[0]);
+      }
+    }
+
+
+    /**
+     * Initialises and displays a new java.awt.Frame
+     *
+     * @param frame java.awt.Frame to be displayed
+     * @param title title of new frame
+     * @param width width if new frame
+     * @param height height of new frame
+     */
+    public static void addFrame(final Frame frame, String title, int width,
+        int height)
+    {
+        frame.setLocation(lastFrameX, lastFrameY);
+        lastFrameX += 40;
+        lastFrameY += 40;
+        frame.setSize(width, height);
+        frame.setTitle(title);
+        frame.addWindowListener(new WindowAdapter()
+            {
+                public void windowClosing(WindowEvent e)
+                {
+                    if(currentAlignFrame == frame)
+                    {
+                      currentAlignFrame = null;
+                    }
+                    lastFrameX -=40;
+                    lastFrameY -=40;
+                    frame.setMenuBar(null);
+                    frame.dispose();
+                }
+                public void windowActivated(WindowEvent e)
+                {
+                  if(frame instanceof AlignFrame)
+                    currentAlignFrame = (AlignFrame)frame;
+                }
+
+            });
+        frame.setVisible(true);
+    }
+
+    public String getSelectedSequences()
+    {
+      StringBuffer result = new StringBuffer("");
+
+      if(initialAlignFrame.viewport.getSelectionGroup()!=null)
+      {
+        SequenceI[] seqs = initialAlignFrame.viewport.getSelectionGroup().
+            getSequencesInOrder(
+                initialAlignFrame.viewport.getAlignment());
+
+        for (int i = 0; i < seqs.length; i++)
+          result.append(seqs[i].getName() + "¬");
+      }
+
+      return result.toString();
+    }
+
+    public String getAlignment(String format)
+    {
+      return getAlignment(format, "true");
+    }
+
+    public String getAlignment(String format, String suffix)
+    {
+      try
+      {
+        boolean seqlimits = suffix.equalsIgnoreCase("true");
+
+        String reply = new AppletFormatAdapter().formatSequences(format,
+            currentAlignFrame.viewport.getAlignment().getSequences(), seqlimits);
+        return reply;
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+        return "Error retrieving alignment in " + format + " format. ";
+      }
+    }
+
+    /**
+     * This paints the background surrounding the "Launch Jalview button"
+     * <br>
+     * <br>If file given in parameter not found, displays error message
+     *
+     * @param g graphics context
+     */
+    public void paint(Graphics g)
+    {
+        if (!fileFound)
+        {
+            g.setColor(new Color(200, 200, 200));
+            g.setColor(Color.cyan);
+            g.fillRect(0, 0, getSize().width, getSize().height);
+            g.setColor(Color.red);
+            g.drawString("Jalview can't open file", 5, 15);
+            g.drawString("\"" + file + "\"", 5, 30);
+        }
+        else if(embedded)
+        {
+          g.setColor(Color.black);
+          g.setFont(new Font("Arial", Font.BOLD, 24));
+          g.drawString("Jalview Applet", 50, this.size().height/2 -30);
+          g.drawString("Loading Data...", 50, this.size().height/2);
+        }
+
+
+    }
+
+    class LoadingThread extends Thread
+    {
+        String file;
+        String protocol;
+        String format;
+        JalviewLite applet;
+
+        public LoadingThread(String _file,
+                             JalviewLite _applet)
+        {
+            file = _file;
+            if(file.startsWith("PASTE"))
+            {
+              file = file.substring(5);
+              protocol = AppletFormatAdapter.PASTE;
+            }
+            else if(inArchive(file))
+              protocol = AppletFormatAdapter.CLASSLOADER;
+            else
+            {
+              file = addProtocol(file);
+              protocol = AppletFormatAdapter.URL;
+            }
+            format = new jalview.io.IdentifyFile().Identify(file, protocol);
+            applet = _applet;
+        }
+
+        public void run()
+        {
+            SequenceI[] sequences = null;
+            try{
+              sequences = new AppletFormatAdapter().readFile(file, protocol,
+                  format);
+            }catch(java.io.IOException ex)
+            {
+              ex.printStackTrace();
+            }
+            if ((sequences != null) && (sequences.length > 0))
+            {
+              currentAlignFrame = new AlignFrame(new Alignment(sequences),
+                                                 applet,
+                                                 file,
+                                                 embedded);
+
+              if(protocol==jalview.io.AppletFormatAdapter.PASTE)
+                currentAlignFrame.setTitle("Sequences from "+getDocumentBase());
+
+              initialAlignFrame = currentAlignFrame;
+
+              currentAlignFrame.statusBar.setText("Successfully loaded file " + file);
+
+
+                String treeFile = applet.getParameter("tree");
+                if(treeFile==null)
+                  treeFile = applet.getParameter("treeFile");
+
+                if (treeFile != null)
+                {
+                  try
+                  {
+                    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)
+                    {
+                      currentAlignFrame.loadTree(fin, treeFile);
+                    }
+                  }
+                  catch (Exception ex)
+                  {
+                    ex.printStackTrace();
+                  }
+              }
+
+              String param = getParameter("features");
+              if (param != null)
+              {
+                if( !inArchive(param) )
+                  param = addProtocol( param );
+
+                currentAlignFrame.parseFeaturesFile(param, protocol);
+              }
+
+              param = getParameter("showFeatureSettings");
+              if(param !=null && param.equalsIgnoreCase("true"))
+              {
+                currentAlignFrame.viewport.showSequenceFeatures(true);
+                currentAlignFrame.featureSettings_actionPerformed();
+              }
+
+             param = getParameter("annotations");
+             if (param != null)
+             {
+               if( !inArchive(param) )
+                  param = addProtocol( param );
+
+               new AnnotationFile().readAnnotationFile(
+                   currentAlignFrame.viewport.getAlignment(),
+                   param);
+
+               currentAlignFrame.alignPanel.fontChanged();
+               currentAlignFrame.alignPanel.setScrollValues(0,0);
+
+             }
+
+             param = getParameter("jnetfile");
+             if (param != null)
+             {
+               try
+               {
+                 if (inArchive(param))
+                   protocol = AppletFormatAdapter.CLASSLOADER;
+                 else
+                 {
+                   protocol = AppletFormatAdapter.URL;
+                   param = addProtocol(param);
+                 }
+
+                 jalview.io.JPredFile predictions = new jalview.io.JPredFile(
+                     param, protocol);
+                 new JnetAnnotationMaker().add_annotation(predictions,
+                     currentAlignFrame.viewport.getAlignment(),
+                     0,false); // do not add sequence profile from concise output
+                 currentAlignFrame.alignPanel.fontChanged();
+                 currentAlignFrame.alignPanel.setScrollValues(0, 0);
+               } catch (Exception ex) {
+                 ex.printStackTrace();
+               }
+             }
+
+
+                String pdbfile = applet.getParameter("PDBFILE");
+                if(pdbfile!=null)
+                {
+                  if( inArchive(pdbfile) )
+                    protocol = AppletFormatAdapter.CLASSLOADER;
+                  else
+                  {
+                    protocol = AppletFormatAdapter.URL;
+                    pdbfile = addProtocol(pdbfile);
+                  }
+
+                  String sequence = applet.getParameter("PDBSEQ");
+
+                  if(sequence!=null)
+                  {
+                    new MCview.AppletPDBViewer(pdbfile, protocol,
+                                               (Sequence)currentAlignFrame.getAlignViewport().getAlignment().findName(sequence),
+                                               currentAlignFrame.getSeqcanvas());
+                  }
+
+                }
+            }
+            else
+            {
+                fileFound = false;
+                remove(launcher);
+                repaint();
+            }
+        }
+
+        /**
+         * Discovers whether the given file is in the Applet Archive
+         * @param file String
+         * @return boolean
+         */
+        boolean inArchive(String file)
+        {
+          //This might throw a security exception in certain browsers
+          //Netscape Communicator for instance.
+          try{
+            return (getClass().getResourceAsStream("/" + file) != null);
+          }catch(Exception ex)
+          {
+            System.out.println("Exception checking resources: "+file+" "+ex);
+            return false;
+          }
+        }
+
+        String addProtocol(String file)
+        {
+          if (file.indexOf("://") == -1)
+             file = getCodeBase() + file;
+
+          return file;
+        }
+
+    }
+}
index 00d1be8..90a8b31 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.util.*;\r
-\r
-import java.util.*;\r
-\r
-/** Data structure to hold and manipulate a multiple sequence alignment\r
- */\r
-public class Alignment implements AlignmentI\r
-{\r
-    protected Alignment dataset;\r
-    protected Vector sequences;\r
-    protected Vector groups = new Vector();\r
-    protected Vector superGroup = new Vector();\r
-    protected char gapCharacter = '-';\r
-    protected int type = NUCLEOTIDE;\r
-    public static final int PROTEIN = 0;\r
-    public static final int NUCLEOTIDE = 1;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public AlignmentAnnotation[] annotations;\r
-\r
-    HiddenSequences hiddenSequences = new HiddenSequences(this);\r
-\r
-\r
-    /** Make an alignment from an array of Sequences.\r
-     *\r
-     * @param sequences\r
-     */\r
-    public Alignment(SequenceI[] seqs)\r
-    {\r
-        int i=0;\r
-\r
-        if( jalview.util.Comparison.isNucleotide(seqs))\r
-          type = NUCLEOTIDE;\r
-        else\r
-          type = PROTEIN;\r
-\r
-        sequences = new Vector();\r
-\r
-        for (i = 0; i < seqs.length; i++)\r
-        {\r
-            sequences.addElement(seqs[i]);\r
-\r
-            if(seqs[i].getDatasetSequence()!=null\r
-            && seqs[i].getDatasetSequence().getAnnotation()!=null)\r
-            {\r
-\r
-              for(int a=0; a<seqs[i].getDatasetSequence().getAnnotation().length; a++)\r
-              {\r
-                       this.addAnnotation(seqs[i].getDatasetSequence().getAnnotation()[a], seqs[i]);\r
-              }\r
-            }\r
-        }\r
-\r
-        getWidth();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getSequences()\r
-    {\r
-        return sequences;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceI getSequenceAt(int i)\r
-    {\r
-        if (i < sequences.size())\r
-        {\r
-            return (SequenceI) sequences.elementAt(i);\r
-        }\r
-\r
-        return null;\r
-    }\r
-\r
-    /** Adds a sequence to the alignment.  Recalculates maxLength and size.\r
-     *\r
-     * @param snew\r
-     */\r
-    public void addSequence(SequenceI snew)\r
-    {\r
-        sequences.addElement(snew);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    public void addSequence(SequenceI[] seq)\r
-    {\r
-        for (int i = 0; i < seq.length; i++)\r
-        {\r
-            addSequence(seq[i]);\r
-        }\r
-    }\r
-\r
-    /** Adds a sequence to the alignment.  Recalculates maxLength and size.\r
-     *\r
-     * @param snew\r
-     */\r
-    public void setSequenceAt(int i, SequenceI snew)\r
-    {\r
-        SequenceI oldseq = getSequenceAt(i);\r
-        deleteSequence(oldseq);\r
-\r
-        sequences.setElementAt(snew, i);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getGroups()\r
-    {\r
-        return groups;\r
-    }\r
-\r
-    /** Takes out columns consisting entirely of gaps (-,.," ")\r
-     */\r
-    public void removeGaps()\r
-    {\r
-        SequenceI current;\r
-        int iSize = getWidth();\r
-\r
-        for (int i = 0; i < iSize; i++)\r
-        {\r
-            boolean delete = true;\r
-\r
-            for (int j = 0; j < getHeight(); j++)\r
-            {\r
-                current = getSequenceAt(j);\r
-\r
-                if (current.getLength() > i)\r
-                {\r
-                    /* MC Should move this to a method somewhere */\r
-                    if (!jalview.util.Comparison.isGap(current.getCharAt(i)))\r
-                    {\r
-                        delete = false;\r
-                    }\r
-                }\r
-            }\r
-\r
-            if (delete)\r
-            {\r
-                deleteColumns(i, i);\r
-                iSize--;\r
-                i--;\r
-            }\r
-        }\r
-    }\r
-\r
-    /** Removes a range of columns (start to end inclusive).\r
-     *\r
-     * @param start Start column in the alignment\r
-     * @param end End column in the alignment\r
-     */\r
-    public void deleteColumns(int start, int end)\r
-    {\r
-        deleteColumns(0, getHeight() - 1, start, end);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq1 DOCUMENT ME!\r
-     * @param seq2 DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public void deleteColumns(int seq1, int seq2, int start, int end)\r
-    {\r
-        for (int i = 0; i <= (end - start); i++)\r
-        {\r
-            for (int j = seq1; j <= seq2; j++)\r
-            {\r
-                getSequenceAt(j).deleteCharAt(start);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void trimLeft(int i)\r
-    {\r
-        int j, jSize = getHeight();\r
-        for (j = 0; j < jSize; j++)\r
-        {\r
-            SequenceI s = getSequenceAt(j);\r
-            int newstart = s.findPosition(i);\r
-\r
-            if(i>s.getLength())\r
-            {\r
-              sequences.removeElement(s);\r
-              j--;\r
-              jSize--;\r
-            }\r
-            else\r
-            {\r
-              s.setStart(newstart);\r
-              s.setSequence(s.getSequence().substring(i));\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void trimRight(int i)\r
-    {\r
-        for (int j = 0; j < getHeight(); j++)\r
-        {\r
-            SequenceI s = getSequenceAt(j);\r
-            int newend = s.findPosition(i);\r
-\r
-            s.setEnd(newend);\r
-            if(s.getLength()>i)\r
-              s.setSequence(s.getSequence().substring(0, i + 1));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     */\r
-    public void deleteSequence(SequenceI s)\r
-    {\r
-        for (int i = 0; i < getHeight(); i++)\r
-        {\r
-            if (getSequenceAt(i) == s)\r
-            {\r
-                deleteSequence(i);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void deleteSequence(int i)\r
-    {\r
-        sequences.removeElementAt(i);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param threshold DOCUMENT ME!\r
-     * @param sel DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector removeRedundancy(float threshold, Vector sel)\r
-    {\r
-        Vector del = new Vector();\r
-\r
-        for (int i = 1; i < sel.size(); i++)\r
-        {\r
-            for (int j = 0; j < i; j++)\r
-            {\r
-                // Only do the comparison if either have not been deleted\r
-                if (!del.contains((SequenceI) sel.elementAt(i)) ||\r
-                        !del.contains((SequenceI) sel.elementAt(j)))\r
-                {\r
-                    // use PID instead of Comparison (which is really not pleasant)\r
-                    float pid = Comparison.PID((SequenceI) sel.elementAt(j),\r
-                            (SequenceI) sel.elementAt(i));\r
-\r
-                    if (pid >= threshold)\r
-                    {\r
-                        // Delete the shortest one\r
-                        if (((SequenceI) sel.elementAt(j)).getSequence().length() > ((SequenceI) sel\r
-                                                                                         .elementAt(\r
-                                    i)).getSequence().length())\r
-                        {\r
-                            del.addElement(sel.elementAt(i));\r
-                        }\r
-                        else\r
-                        {\r
-                            del.addElement(sel.elementAt(i));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        // Now delete the sequences\r
-        for (int i = 0; i < del.size(); i++)\r
-        {\r
-            deleteSequence((SequenceI) del.elementAt(i));\r
-        }\r
-\r
-        return del;\r
-    }\r
-\r
-    /**    */\r
-    public SequenceGroup findGroup(int i)\r
-    {\r
-        return findGroup(getSequenceAt(i));\r
-    }\r
-\r
-    /**    */\r
-    public SequenceGroup findGroup(SequenceI s)\r
-    {\r
-        for (int i = 0; i < this.groups.size(); i++)\r
-        {\r
-            SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-\r
-            if (sg.sequences.contains(s))\r
-            {\r
-                return sg;\r
-            }\r
-        }\r
-\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceGroup[] findAllGroups(SequenceI s)\r
-    {\r
-        Vector temp = new Vector();\r
-\r
-        int gSize = groups.size();\r
-        for (int i = 0; i < gSize; i++)\r
-        {\r
-            SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-            if(sg==null || sg.sequences==null)\r
-            {\r
-              this.deleteGroup(sg);\r
-              gSize--;\r
-              continue;\r
-            }\r
-\r
-            if (sg.sequences.contains(s))\r
-            {\r
-                temp.addElement(sg);\r
-            }\r
-        }\r
-\r
-        SequenceGroup[] ret = new SequenceGroup[temp.size()];\r
-\r
-        for (int i = 0; i < temp.size(); i++)\r
-        {\r
-            ret[i] = (SequenceGroup) temp.elementAt(i);\r
-        }\r
-\r
-        return ret;\r
-    }\r
-\r
-\r
-\r
-    /**    */\r
-    public void addGroup(SequenceGroup sg)\r
-    {\r
-        if (!groups.contains(sg))\r
-        {\r
-            groups.addElement(sg);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void deleteAllGroups()\r
-    {\r
-        groups.removeAllElements();\r
-        superGroup.removeAllElements();\r
-\r
-        int i = 0;\r
-\r
-        while (i < sequences.size())\r
-        {\r
-            SequenceI s = getSequenceAt(i);\r
-            s.setColor(java.awt.Color.white);\r
-            i++;\r
-        }\r
-    }\r
-\r
-    /**    */\r
-    public void deleteGroup(SequenceGroup g)\r
-    {\r
-        if (groups.contains(g))\r
-        {\r
-            groups.removeElement(g);\r
-        }\r
-    }\r
-\r
-    /**    */\r
-    public SequenceI findName(String name)\r
-    {\r
-        int i = 0;\r
-\r
-        while (i < sequences.size())\r
-        {\r
-            if (getSequenceAt(i).getName().equals(name))\r
-            {\r
-                return getSequenceAt(i);\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        return null;\r
-    }\r
-\r
-\r
-    /**    */\r
-    public int findIndex(SequenceI s)\r
-    {\r
-        int i = 0;\r
-\r
-        while (i < sequences.size())\r
-        {\r
-            if (s == getSequenceAt(i))\r
-            {\r
-                return i;\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        return -1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getHeight()\r
-    {\r
-        return sequences.size();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getWidth()\r
-    {\r
-        int maxLength = -1;\r
-\r
-        for (int i = 0; i < sequences.size(); i++)\r
-        {\r
-            if (getSequenceAt(i).getLength() > maxLength)\r
-            {\r
-                maxLength = getSequenceAt(i).getLength();\r
-            }\r
-        }\r
-\r
-        return maxLength;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getMaxIdLength()\r
-    {\r
-        int max = 0;\r
-        int i = 0;\r
-\r
-        while (i < sequences.size())\r
-        {\r
-            SequenceI seq = getSequenceAt(i);\r
-            String tmp = seq.getName() + "/" + seq.getStart() + "-" +\r
-                seq.getEnd();\r
-\r
-            if (tmp.length() > max)\r
-            {\r
-                max = tmp.length();\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        return max;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param gc DOCUMENT ME!\r
-     */\r
-    public void setGapCharacter(char gc)\r
-    {\r
-        gapCharacter = gc;\r
-\r
-        for (int i = 0; i < sequences.size(); i++)\r
-        {\r
-            Sequence seq = (Sequence) sequences.elementAt(i);\r
-            seq.sequence = seq.sequence.replace('.', gc);\r
-            seq.sequence = seq.sequence.replace('-', gc);\r
-            seq.sequence = seq.sequence.replace(' ', gc);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public char getGapCharacter()\r
-    {\r
-        return gapCharacter;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getAAFrequency()\r
-    {\r
-        return AAFrequency.calculate(sequences, 0, getWidth());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean isAligned()\r
-    {\r
-        int width = getWidth();\r
-\r
-        for (int i = 0; i < sequences.size(); i++)\r
-        {\r
-            if (getSequenceAt(i).getLength() != width)\r
-            {\r
-                return false;\r
-            }\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param aa DOCUMENT ME!\r
-     */\r
-    public void deleteAnnotation(AlignmentAnnotation aa)\r
-    {\r
-        int aSize = 1;\r
-\r
-        if (annotations != null)\r
-        {\r
-            aSize = annotations.length;\r
-        }\r
-\r
-        AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize - 1];\r
-\r
-        int tIndex = 0;\r
-\r
-        for (int i = 0; i < aSize; i++)\r
-        {\r
-            if (annotations[i] == aa)\r
-            {\r
-                continue;\r
-            }\r
-\r
-            temp[tIndex] = annotations[i];\r
-            tIndex++;\r
-        }\r
-\r
-        annotations = temp;\r
-    }\r
-\r
-    /**\r
-     *\r
-     * @param aa AlignmentAnnotation\r
-     * @param seqRef The sequence to associate this annotation with\r
-     * @return The adjusted AlignmentAnnotation, with dataset sequence and annotation added\r
-     */\r
-    public AlignmentAnnotation addAnnotation(AlignmentAnnotation aa, SequenceI seqRef)\r
-    {\r
-      if(seqRef!=null)\r
-      {\r
-          //We can only add Annotations to the dataset sequences\r
-           if(seqRef.getDatasetSequence()==null)\r
-           {\r
-                  setDataset(null);\r
-            }\r
-\r
-        AlignmentAnnotation []  old = seqRef.getDatasetSequence().getAnnotation();\r
-\r
-        //First check if this is a new annotation or not. If it is new,\r
-        //we must add the annotation to the dataset\r
-        boolean newAnnotation = true;\r
-        if(seqRef.getDatasetSequence().getAnnotation()!=null)\r
-        {\r
-          for(int a=0; a<old.length; a++)\r
-          {\r
-            if(old[a] == aa)\r
-            {\r
-\r
-              newAnnotation = false;\r
-              break;\r
-            }\r
-          }\r
-        }\r
-\r
-        if(newAnnotation)\r
-         {\r
-           seqRef.getDatasetSequence().addAlignmentAnnotation(aa);\r
-         }\r
-\r
-          AlignmentAnnotation copy = null;\r
-          if (aa.graph > 0)\r
-            copy = new AlignmentAnnotation(\r
-                aa.label, aa.description, aa.annotations, aa.graphMin,\r
-                aa.graphMax, aa.graph\r
-                );\r
-          else\r
-            copy = new AlignmentAnnotation(\r
-                aa.label, aa.description, aa.annotations\r
-                );\r
-\r
-         copy.datasetAnnotation = aa;\r
-\r
-         addAnnotation(copy);\r
-\r
-         copy.sequenceRef = seqRef;\r
-\r
-         return copy;\r
-      }\r
-      else\r
-      {\r
-        addAnnotation(aa);\r
-        return aa;\r
-      }\r
-    }\r
-\r
-    public void adjustSequenceAnnotations()\r
-    {\r
-      if(annotations!=null)\r
-      {\r
-        for (int a = 0; a < annotations.length; a++)\r
-        {\r
-          if (annotations[a].sequenceRef != null)\r
-          {\r
-            annotations[a].adjustForAlignment();\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param aa DOCUMENT ME!\r
-     */\r
-    public void addAnnotation(AlignmentAnnotation aa)\r
-    {\r
-        int aSize = 1;\r
-        if (annotations != null)\r
-        {\r
-            aSize = annotations.length + 1;\r
-        }\r
-\r
-        AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];\r
-\r
-        temp[aSize-1] = aa;\r
-\r
-        int i = 0;\r
-\r
-        if (aSize > 1)\r
-        {\r
-            for (i = 0; i < (aSize-1); i++)\r
-            {\r
-                temp[i] = annotations[i];\r
-            }\r
-        }\r
-\r
-        annotations = temp;\r
-    }\r
-\r
-    public void setAnnotationIndex(AlignmentAnnotation aa, int index)\r
-    {\r
-      if(aa==null || annotations==null || annotations.length-1<index)\r
-        return;\r
-\r
-      int aSize = annotations.length;\r
-      AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];\r
-\r
-      temp[index] = aa;\r
-\r
-      for (int i = 0; i < aSize; i++)\r
-      {\r
-        if(i==index)\r
-          continue;\r
-\r
-        if(i<index)\r
-          temp[i] = annotations[i];\r
-        else\r
-          temp[i] = annotations[i-1];\r
-      }\r
-\r
-        annotations = temp;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public AlignmentAnnotation[] getAlignmentAnnotation()\r
-    {\r
-        return annotations;\r
-    }\r
-\r
-    public void setNucleotide(boolean b)\r
-    {\r
-      if(b)\r
-        type = NUCLEOTIDE;\r
-      else\r
-        type = PROTEIN;\r
-    }\r
-\r
-    public boolean isNucleotide()\r
-    {\r
-      if(type==NUCLEOTIDE)\r
-        return true;\r
-      else\r
-        return false;\r
-    }\r
-\r
-    public void setDataset(Alignment data)\r
-    {\r
-      if(dataset==null && data==null)\r
-      {\r
-        // Create a new dataset for this alignment.\r
-        // Can only be done once, if dataset is not null\r
-        // This will not be performed\r
-        Sequence[] seqs = new Sequence[getHeight()];\r
-        for (int i = 0; i < getHeight(); i++)\r
-        {\r
-\r
-          seqs[i] = new Sequence(getSequenceAt(i).getName(),\r
-                                 AlignSeq.extractGaps(\r
-                                     jalview.util.Comparison.GapChars,\r
-                                     getSequenceAt(i).getSequence()\r
-                                 ),\r
-                                 getSequenceAt(i).getStart(),\r
-                                 getSequenceAt(i).getEnd());\r
-\r
-          getSequenceAt(i).setDatasetSequence(seqs[i]);\r
-        }\r
-\r
-        dataset = new Alignment(seqs);\r
-      }\r
-      else if(dataset==null && data!=null)\r
-      {\r
-        dataset = data;\r
-      }\r
-    }\r
-\r
-    public Alignment getDataset()\r
-    {\r
-      return dataset;\r
-    }\r
-\r
-    public boolean padGaps() {\r
-      boolean modified=false;\r
-      int Width = getWidth();\r
-      SequenceI current;\r
-      for (int i = 0; i < sequences.size();\r
-           i++)\r
-      {\r
-        current = getSequenceAt(i);\r
-\r
-        if (current.getLength() < Width)\r
-        {\r
-          current.insertCharAt(Width - 1, gapCharacter);\r
-          modified=true;\r
-        }\r
-      }\r
-      return modified;\r
-    }\r
-\r
-    public HiddenSequences getHiddenSequences()\r
-    {\r
-      return hiddenSequences;\r
-    }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import jalview.analysis.*;
+
+import jalview.util.*;
+
+import java.util.*;
+
+/** Data structure to hold and manipulate a multiple sequence alignment
+ */
+public class Alignment implements AlignmentI
+{
+    protected Alignment dataset;
+    protected Vector sequences;
+    protected Vector groups = new Vector();
+    protected char gapCharacter = '-';
+    protected int type = NUCLEOTIDE;
+    public static final int PROTEIN = 0;
+    public static final int NUCLEOTIDE = 1;
+
+    /** DOCUMENT ME!! */
+    public AlignmentAnnotation[] annotations;
+
+    HiddenSequences hiddenSequences = new HiddenSequences(this);
+
+    private void initAlignment(SequenceI[] seqs) {
+      int i=0;
+
+      if( jalview.util.Comparison.isNucleotide(seqs))
+        type = NUCLEOTIDE;
+      else
+        type = PROTEIN;
+
+      sequences = new Vector();
+
+      for (i = 0; i < seqs.length; i++)
+      {
+        sequences.addElement(seqs[i]);
+      }
+
+    }
+    /** Make an alignment from an array of Sequences.
+     *
+     * @param sequences
+     */
+    public Alignment(SequenceI[] seqs)
+    {
+      initAlignment(seqs);
+    }
+    /**
+     * Make a new alignment from an array of SeqCigars
+     * @param seqs SeqCigar[]
+     */
+    public Alignment(SeqCigar[] alseqs) {
+      SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs, gapCharacter, new ColumnSelection(), null);
+      initAlignment(seqs);
+    }
+    /**
+     * Make a new alignment from an CigarArray
+     * JBPNote - can only do this when compactAlignment does not contain hidden regions.
+     * JBPNote - must also check that compactAlignment resolves to a set of SeqCigars - or construct them appropriately.
+     * @param compactAlignment CigarArray
+     */
+    public static AlignmentI createAlignment(CigarArray compactAlignment) {
+      throw new Error("Alignment(CigarArray) not yet implemented");
+      // this(compactAlignment.refCigars);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getSequences()
+    {
+        return sequences;
+    }
+
+    public SequenceI [] getSequencesArray()
+    {
+      SequenceI [] reply = new SequenceI[sequences.size()];
+      for(int i=0; i<sequences.size(); i++)
+      {
+        reply[i] = (SequenceI)sequences.elementAt(i);
+      }
+      return reply;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceI getSequenceAt(int i)
+    {
+        if (i < sequences.size())
+        {
+            return (SequenceI) sequences.elementAt(i);
+        }
+
+        return null;
+    }
+
+    /** Adds a sequence to the alignment.  Recalculates maxLength and size.
+     *
+     * @param snew
+     */
+    public void addSequence(SequenceI snew)
+    {
+      if(dataset!=null)
+      {
+        if(snew.getDatasetSequence()!=null)
+        {
+          System.out.println(snew.getName());
+          getDataset().addSequence(snew.getDatasetSequence());
+        }
+        else
+        {
+          Sequence ds = new Sequence(snew.getName(),
+                                     AlignSeq.extractGaps("-. ",
+              snew.getSequence()),
+                                     snew.getStart(),
+                                     snew.getEnd());
+
+          snew.setDatasetSequence(ds);
+          getDataset().addSequence(ds);
+        }
+      }
+
+      sequences.addElement(snew);
+    }
+
+
+    /** Adds a sequence to the alignment.  Recalculates maxLength and size.
+     *
+     * @param snew
+     */
+    public void setSequenceAt(int i, SequenceI snew)
+    {
+        SequenceI oldseq = getSequenceAt(i);
+        deleteSequence(oldseq);
+
+        sequences.setElementAt(snew, i);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getGroups()
+    {
+        return groups;
+    }
+    /** Takes out columns consisting entirely of gaps (-,.," ")
+     */
+    public void removeGaps() {
+      removeGaps((ShiftList)null);
+    }
+    /**
+     * remove gaps in alignment - recording any frame shifts in shiftrecord
+     * intended to be passed to ColumnSelection.compensateForEdits(shiftrecord)
+     * @param shiftrecord
+     */
+    public void removeGaps(ShiftList shiftrecord) {
+        SequenceI[] seqs = getVisibleAndRepresentedSeqs();
+        int j, jSize = seqs.length;
+
+        int width = 0;
+        for (int i = 0; i < jSize; i++)
+        {
+          if (seqs[i].getLength() > width)
+          {
+            width = seqs[i].getLength();
+          }
+        }
+
+        int startCol = -1, endCol = -1;
+        boolean delete = true;
+        for (int i = 0; i < width; i++)
+        {
+            delete = true;
+
+            for (j = 0; j < jSize; j++)
+            {
+                if (seqs[j].getLength() > i)
+                {
+                    if (!jalview.util.Comparison.isGap(seqs[j].getCharAt(i)))
+                    {
+                        if(delete)
+                          endCol = i;
+
+                        delete = false;
+                        break;
+                    }
+                }
+            }
+
+            if(delete && startCol==-1)
+            {
+              startCol = i;
+            }
+
+
+            if (!delete && startCol > -1)
+            {
+              deleteColumns(seqs, startCol, endCol);
+              if (shiftrecord!=null) {
+                shiftrecord.addShift(startCol, 1+endCol-startCol);
+              }
+              width -= (endCol - startCol);
+              i -= (endCol - startCol);
+              startCol = -1;
+              endCol = -1;
+            }
+        }
+
+        if (delete && startCol > -1)
+        {
+          deleteColumns(seqs, startCol, endCol);
+          if (shiftrecord!=null) {
+            shiftrecord.addShift(startCol, 1+endCol-startCol);
+          }
+        }
+    }
+
+    /** Removes a range of columns (start to end inclusive).
+     *
+     * @param seqs Sequences to remove columns from
+     * @param start Start column in the alignment
+     * @param end End column in the alignment
+     */
+    public void deleteColumns(SequenceI [] seqs, int start, int end)
+    {
+      for(int i=0; i<seqs.length; i++)
+        seqs[i].deleteChars(start, end);
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void trimLeft(int i)
+    {
+        SequenceI[] seqs = getVisibleAndRepresentedSeqs();
+        int j, jSize = seqs.length;
+        for (j = 0; j < jSize; j++)
+        {
+            int newstart = seqs[j].findPosition(i);
+
+            if(i>seqs[j].getLength())
+            {
+              sequences.removeElement(seqs[j]);
+              j--;
+              jSize--;
+            }
+            else
+            {
+              seqs[j].setStart(newstart);
+              seqs[j].setSequence(seqs[j].getSequence().substring(i));
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void trimRight(int i)
+    {
+        SequenceI[] seqs = getVisibleAndRepresentedSeqs();
+        int j, jSize = seqs.length;
+        for (j = 0; j < jSize; j++)
+        {
+            int newend = seqs[j].findPosition(i);
+
+            seqs[j].setEnd(newend);
+            if(seqs[j].getLength()>i)
+              seqs[j].setSequence(seqs[j].getSequence().substring(0, i + 1));
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     */
+    public void deleteSequence(SequenceI s)
+    {
+        for (int i = 0; i < getHeight(); i++)
+        {
+            if (getSequenceAt(i) == s)
+            {
+                deleteSequence(i);
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void deleteSequence(int i)
+    {
+        sequences.removeElementAt(i);
+    }
+
+
+    /**    */
+    public SequenceGroup findGroup(SequenceI s)
+    {
+        for (int i = 0; i < this.groups.size(); i++)
+        {
+            SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+
+            if (sg.getSequences(false).contains(s))
+            {
+                return sg;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceGroup[] findAllGroups(SequenceI s)
+    {
+        Vector temp = new Vector();
+
+        int gSize = groups.size();
+        for (int i = 0; i < gSize; i++)
+        {
+            SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+            if(sg==null || sg.getSequences(false)==null)
+            {
+              this.deleteGroup(sg);
+              gSize--;
+              continue;
+            }
+
+            if (sg.getSequences(false).contains(s))
+            {
+                temp.addElement(sg);
+            }
+        }
+
+        SequenceGroup[] ret = new SequenceGroup[temp.size()];
+
+        for (int i = 0; i < temp.size(); i++)
+        {
+            ret[i] = (SequenceGroup) temp.elementAt(i);
+        }
+
+        return ret;
+    }
+
+
+
+    /**    */
+    public void addGroup(SequenceGroup sg)
+    {
+        if (!groups.contains(sg))
+        {
+            groups.addElement(sg);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void deleteAllGroups()
+    {
+        groups.removeAllElements();
+
+        int i = 0;
+
+        while (i < sequences.size())
+        {
+            SequenceI s = getSequenceAt(i);
+            s.setColor(java.awt.Color.white);
+            i++;
+        }
+    }
+
+    /**    */
+    public void deleteGroup(SequenceGroup g)
+    {
+        if (groups.contains(g))
+        {
+            groups.removeElement(g);
+        }
+    }
+
+    /**    */
+    public SequenceI findName(String name)
+    {
+        int i = 0;
+
+        while (i < sequences.size())
+        {
+            if (getSequenceAt(i).getName().equals(name))
+            {
+                return getSequenceAt(i);
+            }
+
+            i++;
+        }
+
+        return null;
+    }
+
+    public SequenceI [] findSequenceMatch(String name)
+    {
+      Vector matches = new Vector();
+      int i = 0;
+
+      while (i < sequences.size())
+      {
+          if (getSequenceAt(i).getName().equals(name))
+          {
+              matches.addElement(getSequenceAt(i));
+          }
+          i++;
+      }
+
+      SequenceI [] result = new SequenceI[matches.size()];
+      for(i=0; i<result.length; i++)
+        result[i] = (SequenceI)matches.elementAt(i);
+
+      return result;
+
+    }
+
+
+    /**    */
+    public int findIndex(SequenceI s)
+    {
+        int i = 0;
+
+        while (i < sequences.size())
+        {
+            if (s == getSequenceAt(i))
+            {
+                return i;
+            }
+
+            i++;
+        }
+
+        return -1;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getHeight()
+    {
+        return sequences.size();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getWidth()
+    {
+        int maxLength = -1;
+
+        for (int i = 0; i < sequences.size(); i++)
+        {
+            if (getSequenceAt(i).getLength() > maxLength)
+            {
+                maxLength = getSequenceAt(i).getLength();
+            }
+        }
+
+        return maxLength;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getMaxIdLength()
+    {
+        int max = 0;
+        int i = 0;
+
+        while (i < sequences.size())
+        {
+            SequenceI seq = getSequenceAt(i);
+            String tmp = seq.getName() + "/" + seq.getStart() + "-" +
+                seq.getEnd();
+
+            if (tmp.length() > max)
+            {
+                max = tmp.length();
+            }
+
+            i++;
+        }
+
+        return max;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param gc DOCUMENT ME!
+     */
+    public void setGapCharacter(char gc)
+    {
+        gapCharacter = gc;
+
+        for (int i = 0; i < sequences.size(); i++)
+        {
+            Sequence seq = (Sequence) sequences.elementAt(i);
+            seq.setSequence( seq.getSequence().replace('.', gc) );
+            seq.setSequence( seq.getSequence().replace('-', gc) );
+            seq.setSequence( seq.getSequence().replace(' ', gc) );
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public char getGapCharacter()
+    {
+        return gapCharacter;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getAAFrequency()
+    {
+        return AAFrequency.calculate(sequences, 0, getWidth());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean isAligned()
+    {
+        int width = getWidth();
+
+        for (int i = 0; i < sequences.size(); i++)
+        {
+            if (getSequenceAt(i).getLength() != width)
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param aa DOCUMENT ME!
+     */
+    public void deleteAnnotation(AlignmentAnnotation aa)
+    {
+        int aSize = 1;
+
+        if (annotations != null)
+        {
+            aSize = annotations.length;
+        }
+
+        AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize - 1];
+
+        int tIndex = 0;
+
+        for (int i = 0; i < aSize; i++)
+        {
+            if (annotations[i] == aa)
+            {
+                continue;
+            }
+
+            temp[tIndex] = annotations[i];
+            tIndex++;
+        }
+
+        annotations = temp;
+    }
+
+
+    public void adjustSequenceAnnotations()
+    {
+      if(annotations!=null)
+      {
+        for (int a = 0; a < annotations.length; a++)
+        {
+          if (annotations[a].sequenceRef != null)
+          {
+            annotations[a].adjustForAlignment();
+          }
+        }
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param aa DOCUMENT ME!
+     */
+    public void addAnnotation(AlignmentAnnotation aa)
+    {
+        int aSize = 1;
+        if (annotations != null)
+        {
+            aSize = annotations.length + 1;
+        }
+
+        AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
+
+        temp[aSize-1] = aa;
+
+        int i = 0;
+
+        if (aSize > 1)
+        {
+            for (i = 0; i < (aSize-1); i++)
+            {
+                temp[i] = annotations[i];
+            }
+        }
+
+        annotations = temp;
+    }
+
+    public void setAnnotationIndex(AlignmentAnnotation aa, int index)
+    {
+      if(aa==null || annotations==null || annotations.length-1<index)
+        return;
+
+      int aSize = annotations.length;
+      AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
+
+      temp[index] = aa;
+
+      for (int i = 0; i < aSize; i++)
+      {
+        if(i==index)
+          continue;
+
+        if(i<index)
+          temp[i] = annotations[i];
+        else
+          temp[i] = annotations[i-1];
+      }
+
+        annotations = temp;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AlignmentAnnotation[] getAlignmentAnnotation()
+    {
+        return annotations;
+    }
+
+    public void setNucleotide(boolean b)
+    {
+      if(b)
+        type = NUCLEOTIDE;
+      else
+        type = PROTEIN;
+    }
+
+    public boolean isNucleotide()
+    {
+      if(type==NUCLEOTIDE)
+        return true;
+      else
+        return false;
+    }
+
+    public void setDataset(Alignment data)
+    {
+      if(dataset==null && data==null)
+      {
+        // Create a new dataset for this alignment.
+        // Can only be done once, if dataset is not null
+        // This will not be performed
+        Sequence[] seqs = new Sequence[getHeight()];
+        for (int i = 0; i < getHeight(); i++)
+        {
+          if(getSequenceAt(i).getDatasetSequence()!=null)
+          {
+            seqs[i] = (Sequence)getSequenceAt(i).getDatasetSequence();
+          }
+          else
+          {
+            seqs[i] = new Sequence(getSequenceAt(i).getName(),
+                                   AlignSeq.extractGaps(
+                                       jalview.util.Comparison.GapChars,
+                                       getSequenceAt(i).getSequence()
+                                   ),
+                                   getSequenceAt(i).getStart(),
+                                   getSequenceAt(i).getEnd());
+            seqs[i].sequenceFeatures = getSequenceAt(i).getSequenceFeatures();
+            getSequenceAt(i).setSequenceFeatures(null);
+            getSequenceAt(i).setDatasetSequence(seqs[i]);
+          }
+        }
+
+        dataset = new Alignment(seqs);
+      }
+      else if(dataset==null && data!=null)
+      {
+        dataset = data;
+      }
+    }
+
+    public Alignment getDataset()
+    {
+      return dataset;
+    }
+
+    public boolean padGaps() {
+      boolean modified=false;
+
+      //Remove excess gaps from the end of alignment
+      int maxLength = -1;
+
+      SequenceI current;
+      for (int i = 0; i < sequences.size(); i++)
+      {
+        current = getSequenceAt(i);
+        for (int j = current.getLength(); j > maxLength; j--)
+        {
+          if (j > maxLength && !jalview.util.Comparison.isGap(
+              current.getCharAt(j)))
+          {
+            maxLength = j;
+            break;
+          }
+        }
+      }
+
+      maxLength++;
+
+      for (int i = 0; i < sequences.size();
+           i++)
+      {
+        current = getSequenceAt(i);
+
+        if (current.getLength() < maxLength)
+        {
+          current.insertCharAt(maxLength - 1, gapCharacter);
+          modified=true;
+        }
+        else if(current.getLength() > maxLength)
+        {
+          current.deleteChars(maxLength, current.getLength());
+        }
+      }
+      return modified;
+    }
+
+    public HiddenSequences getHiddenSequences()
+    {
+      return hiddenSequences;
+    }
+    SequenceI [] getVisibleAndRepresentedSeqs()
+    {
+      if(hiddenSequences==null || hiddenSequences.getSize()<1)
+        return getSequencesArray();
+
+      Vector seqs = new Vector();
+      SequenceI seq;
+      SequenceGroup hidden;
+      for (int i = 0; i < sequences.size(); i++)
+      {
+        seq = (SequenceI) sequences.elementAt(i);
+        seqs.addElement(seq);
+        hidden = seq.getHiddenSequences();
+        if(hidden!=null)
+        {
+          for(int j=0; j<hidden.getSize(false); j++)
+          {
+            seqs.addElement(hidden.getSequenceAt(j));
+          }
+        }
+      }
+      SequenceI [] result = new SequenceI[seqs.size()];
+      for(int i=0; i<seqs.size(); i++)
+        result[i] = (SequenceI)seqs.elementAt(i);
+
+      return result;
+
+    }
+
+  public CigarArray getCompactAlignment()
+  {
+    SeqCigar alseqs[] = new SeqCigar[sequences.size()];
+    for (int i=0; i<sequences.size(); i++) {
+      alseqs[i] = new SeqCigar((SequenceI) sequences.elementAt(i));
+    }
+    return new CigarArray(alseqs);
+  }
+
+}
index c3ccb0b..470497e 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.datamodel;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AlignmentAnnotation\r
-{\r
-    public SequenceI sequenceRef;\r
-\r
-    /** This annotation is the original loaded annotation\r
-     *  without any gaps. It is necessary to adjust the annotation\r
-     *  if sequences are updated */\r
-    public AlignmentAnnotation datasetAnnotation;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public String label;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public String description;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public Annotation[] annotations;\r
-\r
-\r
-    /** DOCUMENT ME!! */\r
-    public float graphMin;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public float graphMax;\r
-\r
-    public GraphLine threshold;\r
-\r
-    // Graphical hints and tips\r
-\r
-    /** DOCUMENT ME!! */\r
-    public boolean editable = false;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public boolean hasIcons; //\r
-\r
-    /** DOCUMENT ME!! */\r
-    public boolean hasText;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public boolean visible = true;\r
-\r
-    public int graphGroup = -1;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int height = 0;\r
-\r
-    public int graph = 0;\r
-\r
-    public int graphHeight = 40;\r
-\r
-    public static final int NO_GRAPH = 0;\r
-\r
-    public static final int BAR_GRAPH = 1;\r
-\r
-    public static final int LINE_GRAPH = 2;\r
-\r
-    public static int getGraphValueFromString(String string)\r
-    {\r
-      if(string.equalsIgnoreCase("BAR_GRAPH"))\r
-        return BAR_GRAPH;\r
-      else if(string.equalsIgnoreCase("LINE_GRAPH"))\r
-        return LINE_GRAPH;\r
-      else\r
-        return NO_GRAPH;\r
-    }\r
-\r
-    /**\r
-     * Creates a new AlignmentAnnotation object.\r
-     *\r
-     * @param label DOCUMENT ME!\r
-     * @param description DOCUMENT ME!\r
-     * @param annotations DOCUMENT ME!\r
-     */\r
-    public AlignmentAnnotation(String label, String description,\r
-        Annotation[] annotations)\r
-    {\r
-        // always editable?\r
-        editable = true;\r
-        this.label = label;\r
-        this.description = description;\r
-        this.annotations = annotations;\r
-\r
-        for (int i = 0; i < annotations.length; i++)\r
-        {\r
-            if ((annotations[i] != null) &&\r
-                    ((annotations[i].secondaryStructure == 'H') ||\r
-                    (annotations[i].secondaryStructure == 'E')))\r
-            {\r
-                hasIcons = true;\r
-            }\r
-\r
-            if ((annotations[i] != null) &&\r
-                    (annotations[i].displayCharacter.length() > 0))\r
-            {\r
-                hasText = true;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Creates a new AlignmentAnnotation object.\r
-     *\r
-     * @param label DOCUMENT ME!\r
-     * @param description DOCUMENT ME!\r
-     * @param annotations DOCUMENT ME!\r
-     * @param min DOCUMENT ME!\r
-     * @param max DOCUMENT ME!\r
-     * @param winLength DOCUMENT ME!\r
-     */\r
-    public AlignmentAnnotation(String label, String description,\r
-        Annotation[] annotations, float min, float max, int graphType)\r
-    {\r
-        // graphs are not editable\r
-        this.label = label;\r
-        this.description = description;\r
-        this.annotations = annotations;\r
-        graph = graphType;\r
-\r
-        if (min == max)\r
-        {\r
-            min = 999999999;\r
-            for (int i = 0; i < annotations.length; i++)\r
-            {\r
-                if (annotations[i] == null)\r
-                {\r
-                    continue;\r
-                }\r
-\r
-                if (annotations[i].value > max)\r
-                {\r
-                    max = annotations[i].value;\r
-                }\r
-\r
-                if (annotations[i].value < min)\r
-                {\r
-                    min = annotations[i].value;\r
-                }\r
-            }\r
-        }\r
-\r
-        graphMin = min;\r
-        graphMax = max;\r
-\r
-        for (int i = 0; i < annotations.length; i++)\r
-        {\r
-            if ((annotations[i] != null) &&\r
-                    ((annotations[i].secondaryStructure == 'H') ||\r
-                    (annotations[i].secondaryStructure == 'E')))\r
-            {\r
-                hasIcons = true;\r
-            }\r
-\r
-            if ((annotations[i] != null) &&\r
-                    (annotations[i].displayCharacter.length() > 0))\r
-            {\r
-                hasText = true;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String toString()\r
-    {\r
-        StringBuffer buffer = new StringBuffer();\r
-\r
-        for (int i = 0; i < annotations.length; i++)\r
-        {\r
-            if (annotations[i] != null)\r
-            {\r
-                if (graph!=0)\r
-                {\r
-                    buffer.append(annotations[i].value);\r
-                }\r
-                else if (hasIcons)\r
-                {\r
-                    buffer.append(annotations[i].secondaryStructure);\r
-                }\r
-                else\r
-                {\r
-                    buffer.append(annotations[i].displayCharacter);\r
-                }\r
-            }\r
-\r
-            buffer.append(", ");\r
-        }\r
-\r
-        if (label.equals("Consensus"))\r
-        {\r
-            buffer.append("\n");\r
-\r
-            for (int i = 0; i < annotations.length; i++)\r
-            {\r
-                if (annotations[i] != null)\r
-                {\r
-                    buffer.append(annotations[i].description);\r
-                }\r
-\r
-                buffer.append(", ");\r
-            }\r
-        }\r
-\r
-        return buffer.toString();\r
-      }\r
-\r
-      public void setThreshold(GraphLine line)\r
-      {\r
-        threshold = line;\r
-      }\r
-\r
-      public GraphLine getThreshold()\r
-      {\r
-          return threshold;\r
-      }\r
-\r
-      public void adjustForAlignment()\r
-      {\r
-          int a=0, aSize = sequenceRef.getLength();\r
-\r
-          int index = 0;\r
-          Annotation[] temp = new Annotation[aSize];\r
-\r
-          for (a = 0; a < aSize; a++)\r
-          {\r
-            if (!jalview.util.Comparison.isGap(sequenceRef.getCharAt(a)))\r
-            {\r
-              index = sequenceRef.findPosition(a);\r
-              if(datasetAnnotation.annotations.length>index)\r
-                temp[a] = datasetAnnotation.annotations[index];\r
-            }\r
-          }\r
-\r
-          annotations = temp;\r
-      }\r
-}\r
-\r
-\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.datamodel;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AlignmentAnnotation
+{
+    public SequenceI sequenceRef;
+
+    /** DOCUMENT ME!! */
+    public String label;
+
+    /** DOCUMENT ME!! */
+    public String description;
+
+    /** DOCUMENT ME!! */
+    public Annotation[] annotations;
+
+    public java.util.Hashtable sequenceMapping;
+
+    /** DOCUMENT ME!! */
+    public float graphMin;
+
+    /** DOCUMENT ME!! */
+    public float graphMax;
+
+    public GraphLine threshold;
+
+    // Graphical hints and tips
+
+    /** DOCUMENT ME!! */
+    public boolean editable = false;
+
+    /** DOCUMENT ME!! */
+    public boolean hasIcons; //
+
+    /** DOCUMENT ME!! */
+    public boolean hasText;
+
+    /** DOCUMENT ME!! */
+    public boolean visible = true;
+
+    public int graphGroup = -1;
+
+    /** DOCUMENT ME!! */
+    public int height = 0;
+
+    public int graph = 0;
+
+    public int graphHeight = 40;
+
+    public static final int NO_GRAPH = 0;
+
+    public static final int BAR_GRAPH = 1;
+
+    public static final int LINE_GRAPH = 2;
+
+    public static int getGraphValueFromString(String string)
+    {
+      if(string.equalsIgnoreCase("BAR_GRAPH"))
+        return BAR_GRAPH;
+      else if(string.equalsIgnoreCase("LINE_GRAPH"))
+        return LINE_GRAPH;
+      else
+        return NO_GRAPH;
+    }
+
+    /**
+     * Creates a new AlignmentAnnotation object.
+     *
+     * @param label DOCUMENT ME!
+     * @param description DOCUMENT ME!
+     * @param annotations DOCUMENT ME!
+     */
+    public AlignmentAnnotation(String label, String description,
+        Annotation[] annotations)
+    {
+        // always editable?
+        editable = true;
+        this.label = label;
+        this.description = description;
+        this.annotations = annotations;
+
+        for (int i = 0; i < annotations.length; i++)
+        {
+            if ((annotations[i] != null) &&
+                    ((annotations[i].secondaryStructure == 'H') ||
+                    (annotations[i].secondaryStructure == 'E')))
+            {
+                hasIcons = true;
+            }
+
+            if ((annotations[i] != null) &&
+                    (annotations[i].displayCharacter.length() > 0))
+            {
+                hasText = true;
+            }
+        }
+    }
+
+    /**
+     * Creates a new AlignmentAnnotation object.
+     *
+     * @param label DOCUMENT ME!
+     * @param description DOCUMENT ME!
+     * @param annotations DOCUMENT ME!
+     * @param min DOCUMENT ME!
+     * @param max DOCUMENT ME!
+     * @param winLength DOCUMENT ME!
+     */
+    public AlignmentAnnotation(String label, String description,
+        Annotation[] annotations, float min, float max, int graphType)
+    {
+        // graphs are not editable
+        this.label = label;
+        this.description = description;
+        this.annotations = annotations;
+        graph = graphType;
+
+        boolean drawValues = true;
+
+        if (min == max)
+        {
+            min = 999999999;
+            for (int i = 0; i < annotations.length; i++)
+            {
+                if (annotations[i] == null)
+                {
+                    continue;
+                }
+
+                if(drawValues && annotations[i].displayCharacter.length() > 1 )
+                {
+                  drawValues = false;
+                }
+
+                if (annotations[i].value > max)
+                {
+                    max = annotations[i].value;
+                }
+
+                if (annotations[i].value < min)
+                {
+                    min = annotations[i].value;
+                }
+            }
+        }
+
+        graphMin = min;
+        graphMax = max;
+
+        for (int i = 0; i < annotations.length; i++)
+        {
+            if (!hasIcons
+                && annotations[i] != null
+                && ((annotations[i].secondaryStructure == 'H') ||
+                    (annotations[i].secondaryStructure == 'E')))
+            {
+                hasIcons = true;
+            }
+
+            if (!hasText
+                && annotations[i]!=null
+                && annotations[i].displayCharacter.length() > 0)
+            {
+                hasText = true;
+            }
+        }
+
+        if(!drawValues && graphType!=NO_GRAPH)
+        {
+          for (int i = 0; i < annotations.length; i++)
+          {
+            if (annotations[i] != null)
+              annotations[i].displayCharacter = "";
+          }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        for (int i = 0; i < annotations.length; i++)
+        {
+            if (annotations[i] != null)
+            {
+                if (graph!=0)
+                {
+                    buffer.append(annotations[i].value);
+                }
+                else if (hasIcons)
+                {
+                    buffer.append(annotations[i].secondaryStructure);
+                }
+                else
+                {
+                    buffer.append(annotations[i].displayCharacter);
+                }
+            }
+
+            buffer.append(", ");
+        }
+
+        if (label.equals("Consensus"))
+        {
+            buffer.append("\n");
+
+            for (int i = 0; i < annotations.length; i++)
+            {
+                if (annotations[i] != null)
+                {
+                    buffer.append(annotations[i].description);
+                }
+
+                buffer.append(", ");
+            }
+        }
+
+        return buffer.toString();
+      }
+
+      public void setThreshold(GraphLine line)
+      {
+        threshold = line;
+      }
+
+      public GraphLine getThreshold()
+      {
+          return threshold;
+      }
+
+      /**
+       * Attach the annotation to seqRef, starting from startRes position.
+       * @param seqRef
+       * @param startRes
+       */
+      public void createSequenceMapping(SequenceI seqRef,
+                                        int startRes,
+                                        boolean alreadyMapped)
+      {
+        if(seqRef == null)
+          return;
+
+        sequenceMapping = new java.util.Hashtable();
+
+        sequenceRef = seqRef;
+        int seqPos;
+
+        for(int i = 0; i < annotations.length; i++)
+        {
+            if (annotations[i] != null)
+            {
+              if(alreadyMapped)
+                seqPos = seqRef.findPosition(i);
+              else
+                seqPos = i+startRes;
+
+              sequenceMapping.put(new Integer(seqPos), annotations[i]);
+            }
+         }
+
+        adjustForAlignment();
+      }
+
+      public void adjustForAlignment()
+      {
+          int a=0, aSize = sequenceRef.getLength();
+
+          if(aSize == 0)
+          {
+            //Its been deleted
+            return;
+          }
+
+          int position;
+          Annotation[] temp = new Annotation[aSize];
+          Integer index;
+
+          for (a = sequenceRef.getStart(); a <= sequenceRef.getEnd(); a++)
+          {
+              index = new Integer(a);
+              if(sequenceMapping.containsKey(index))
+              {
+                position = sequenceRef.findIndex(a)-1;
+
+                temp[position] = (Annotation)sequenceMapping.get(index);
+              }
+          }
+
+          annotations = temp;
+      }
+}
+
+
index 7fe4627..bcfcc81 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.datamodel;\r
-\r
-import java.util.*;\r
-\r
-\r
-/** Data structure to hold and manipulate a multiple sequence alignment\r
- */\r
-public interface AlignmentI\r
-{\r
-    /**\r
-     *  Calculates the number of sequences in an alignment\r
-     *\r
-     * @return Number of sequences in alignment\r
-     */\r
-    public int getHeight();\r
-\r
-    /**\r
-     * Calculates the maximum width of the alignment, including gaps.\r
-     *\r
-     * @return Greatest sequence length within alignment.\r
-     */\r
-    public int getWidth();\r
-\r
-    /**\r
-     * Calculates the longest sequence Id of the alignment\r
-     *\r
-     * @return Number of characters in longest sequence Id.\r
-     */\r
-    public int getMaxIdLength();\r
-\r
-    /**\r
-     * Calculates if this set of sequences is all the same length\r
-     *\r
-     * @return true if all sequences in alignment are the same length\r
-     */\r
-    public boolean isAligned();\r
-\r
-    /**\r
-     * Gets sequences as a Vector\r
-     *\r
-     * @return All sequences in alignment.\r
-     */\r
-    public Vector getSequences();\r
-\r
-    /**\r
-     * Find a specific sequence in this alignment.\r
-     *\r
-     * @param i Index of required sequence.\r
-     *\r
-     * @return SequenceI at given index.\r
-     */\r
-    public SequenceI getSequenceAt(int i);\r
-\r
-    /**\r
-     * Add a new sequence to this alignment.\r
-     *\r
-     * @param seq New sequence will be added at end of alignment.\r
-     */\r
-    public void addSequence(SequenceI seq);\r
-\r
-    /**\r
-     * Used to set a particular index of the alignment with the given sequence.\r
-     *\r
-     * @param i Index of sequence to be updated.\r
-     * @param seq New sequence to be inserted.\r
-     */\r
-    public void setSequenceAt(int i, SequenceI seq);\r
-\r
-    /**\r
-     * Deletes a sequence from the alignment.\r
-     *\r
-     * @param s Sequence to be deleted.\r
-     */\r
-    public void deleteSequence(SequenceI s);\r
-\r
-    /**\r
-     * Deletes a sequence from the alignment.\r
-     *\r
-     * @param i Index of sequence to be deleted.\r
-     */\r
-    public void deleteSequence(int i);\r
-\r
-    /**\r
-     * Deletes all residues in every sequence of alignment within given columns.\r
-     *\r
-     * @param start Start index of columns to delete.\r
-     * @param end End index to columns to delete.\r
-     */\r
-    public void deleteColumns(int start, int end);\r
-\r
-    /**\r
-     * Deletes all residues in every sequence of alignment within given columns.\r
-     *\r
-     * @param seq1 Index of first sequence to delete columns from.\r
-     * @param seq2 Index of last sequence to delete columns from.\r
-     * @param start Start index of columns to delete.\r
-     * @param end End index of columns to delete.\r
-     */\r
-    public void deleteColumns(int seq1, int seq2, int start, int end);\r
-\r
-    /**\r
-     * Finds sequence in alignment using sequence name as query.\r
-     *\r
-     * @param name Id of sequence to search for.\r
-     *\r
-     * @return Sequence matching query, if found. If not found returns null.\r
-     */\r
-    public SequenceI findName(String name);\r
-\r
-\r
-    /**\r
-     * Finds index of a given sequence in the alignment.\r
-     *\r
-     * @param s Sequence to look for.\r
-     *\r
-     * @return Index of sequence within the alignment.\r
-     */\r
-    public int findIndex(SequenceI s);\r
-\r
-    /**\r
-    * All sequences will be cut from beginning to given index.\r
-    *\r
-    * @param i Remove all residues in sequences up to this column.\r
-     */\r
-    public void trimLeft(int i);\r
-\r
-    /**\r
-     * All sequences will be cut from given index.\r
-     *\r
-     * @param i Remove all residues in sequences beyond this column.\r
-     */\r
-    public void trimRight(int i);\r
-\r
-    /**\r
-     * Removes all columns containing entirely gap characters.\r
-     */\r
-    public void removeGaps();\r
-\r
-    /**\r
-     * Removes redundant sequences from alignment.\r
-     *\r
-     * @param threshold Remove all sequences above the given threshold.\r
-     * @param sel Set of sequences which will have redundant sequences removed from.\r
-     *\r
-     * @return All sequences below redundancy threshold.\r
-     */\r
-    public Vector removeRedundancy(float threshold, Vector sel);\r
-\r
-    /**\r
-     * Finds group that sequence at index i in alignment is part of.\r
-     *\r
-     * @param i Index in alignment.\r
-     *\r
-     * @return First group found for sequence at position i. WARNING :\r
-     * Sequences may be members of several groups. This method is incomplete.\r
-     */\r
-    public SequenceGroup findGroup(int i);\r
-\r
-    /**\r
-     * Finds group that given sequence is part of.\r
-     *\r
-     * @param s Sequence in alignment.\r
-     *\r
-     * @return First group found for sequence. WARNING :\r
-     * Sequences may be members of several groups. This method is incomplete.\r
-     */\r
-    public SequenceGroup findGroup(SequenceI s);\r
-\r
-    /**\r
-     * Finds all groups that a given sequence is part of.\r
-     *\r
-     * @param s Sequence in alignment.\r
-     *\r
-     * @return All groups containing given sequence.\r
-     */\r
-    public SequenceGroup[] findAllGroups(SequenceI s);\r
-\r
-    /**\r
-     * Adds a new SequenceGroup to this alignment.\r
-     *\r
-     * @param sg New group to be added.\r
-     */\r
-    public void addGroup(SequenceGroup sg);\r
-\r
-    /**\r
-     * Deletes a specific SequenceGroup\r
-     *\r
-     * @param g Group will be deleted from alignment.\r
-     */\r
-    public void deleteGroup(SequenceGroup g);\r
-\r
-    /**\r
-     * Get all the groups associated with this alignment.\r
-     *\r
-     * @return All groups as a Vector.\r
-     */\r
-    public Vector getGroups();\r
-\r
-    /**\r
-     * Deletes all groups from this alignment.\r
-     */\r
-    public void deleteAllGroups();\r
-\r
-\r
-    /**\r
-     * Adds a new AlignmentAnnotation to this alignment\r
-     */\r
-    public void addAnnotation(AlignmentAnnotation aa);\r
-\r
-    /**\r
-     * Adds a new AlignmentAnnotation to this alignment,\r
-     *  associated to Sequence starting at sequence index\r
-     */\r
-    public AlignmentAnnotation addAnnotation(AlignmentAnnotation aa, SequenceI seqRef);\r
-\r
-    public void setAnnotationIndex(AlignmentAnnotation aa, int index);\r
-\r
-    /**\r
-     * Deletes a specific AlignmentAnnotation from the alignment.\r
-     *\r
-     * @param aa DOCUMENT ME!\r
-     */\r
-    public void deleteAnnotation(AlignmentAnnotation aa);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public AlignmentAnnotation[] getAlignmentAnnotation();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param gc DOCUMENT ME!\r
-     */\r
-    public void setGapCharacter(char gc);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public char getGapCharacter();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getAAFrequency();\r
-\r
-    /**\r
-     * Returns true if alignment is nucleotide sequence\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean isNucleotide();\r
-\r
-    /**\r
-     * Set true if the alignment is a nucleotide sequence\r
-     *\r
-     * @return\r
-     */\r
-    public void setNucleotide(boolean b);\r
-\r
-\r
-    public Alignment getDataset();\r
-\r
-    public void setDataset(Alignment dataset);\r
-    /**\r
-     * pads sequences with gaps (to ensure the set looks like an alignment)\r
-     * @return boolean true if alignment was modified\r
-     */\r
-    public boolean padGaps();\r
-\r
-    public void adjustSequenceAnnotations();\r
-\r
-    public HiddenSequences getHiddenSequences();\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.datamodel;
+
+import jalview.util.ShiftList;
+
+import java.util.*;
+
+
+/** Data structure to hold and manipulate a multiple sequence alignment
+ */
+public interface AlignmentI
+{
+    /**
+     *  Calculates the number of sequences in an alignment
+     *
+     * @return Number of sequences in alignment
+     */
+    public int getHeight();
+
+    /**
+     * Calculates the maximum width of the alignment, including gaps.
+     *
+     * @return Greatest sequence length within alignment.
+     */
+    public int getWidth();
+
+    /**
+     * Calculates the longest sequence Id of the alignment
+     *
+     * @return Number of characters in longest sequence Id.
+     */
+    public int getMaxIdLength();
+
+    /**
+     * Calculates if this set of sequences is all the same length
+     *
+     * @return true if all sequences in alignment are the same length
+     */
+    public boolean isAligned();
+
+    /**
+     * Gets sequences as a Vector
+     *
+     * @return All sequences in alignment.
+     */
+    public Vector getSequences();
+
+    /**
+     * Gets sequences as a SequenceI[]
+     *
+     * @return All sequences in alignment.
+     */
+    public SequenceI [] getSequencesArray();
+
+    /**
+     * Find a specific sequence in this alignment.
+     *
+     * @param i Index of required sequence.
+     *
+     * @return SequenceI at given index.
+     */
+    public SequenceI getSequenceAt(int i);
+
+    /**
+     * Add a new sequence to this alignment.
+     *
+     * @param seq New sequence will be added at end of alignment.
+     */
+    public void addSequence(SequenceI seq);
+
+    /**
+     * Used to set a particular index of the alignment with the given sequence.
+     *
+     * @param i Index of sequence to be updated.
+     * @param seq New sequence to be inserted.
+     */
+    public void setSequenceAt(int i, SequenceI seq);
+
+    /**
+     * Deletes a sequence from the alignment.
+     *
+     * @param s Sequence to be deleted.
+     */
+    public void deleteSequence(SequenceI s);
+
+    /**
+     * Deletes a sequence from the alignment.
+     *
+     * @param i Index of sequence to be deleted.
+     */
+    public void deleteSequence(int i);
+
+    /**
+     * Deletes all residues in every sequence of alignment within given columns.
+     *
+     * @param start Start index of columns to delete.
+     * @param end End index to columns to delete.
+     */
+    public void deleteColumns(SequenceI seqs [], int start, int end);
+
+
+    /**
+     * Finds sequence in alignment using sequence name as query.
+     *
+     * @param name Id of sequence to search for.
+     *
+     * @return Sequence matching query, if found. If not found returns null.
+     */
+    public SequenceI findName(String name);
+
+    public SequenceI [] findSequenceMatch(String name);
+
+    /**
+     * Finds index of a given sequence in the alignment.
+     *
+     * @param s Sequence to look for.
+     *
+     * @return Index of sequence within the alignment.
+     */
+    public int findIndex(SequenceI s);
+
+    /**
+    * All sequences will be cut from beginning to given index.
+    *
+    * @param i Remove all residues in sequences up to this column.
+     */
+    public void trimLeft(int i);
+
+    /**
+     * All sequences will be cut from given index.
+     *
+     * @param i Remove all residues in sequences beyond this column.
+     */
+    public void trimRight(int i);
+
+    /**
+     * Removes all columns containing entirely gap characters.
+     */
+    public void removeGaps();
+    /**
+     * remove gaps in alignment - recording any frame shifts in shiftrecord
+     * @param shiftrecord
+     */
+    public void removeGaps(ShiftList shiftrecord);
+
+    /**
+     * Finds group that given sequence is part of.
+     *
+     * @param s Sequence in alignment.
+     *
+     * @return First group found for sequence. WARNING :
+     * Sequences may be members of several groups. This method is incomplete.
+     */
+    public SequenceGroup findGroup(SequenceI s);
+
+    /**
+     * Finds all groups that a given sequence is part of.
+     *
+     * @param s Sequence in alignment.
+     *
+     * @return All groups containing given sequence.
+     */
+    public SequenceGroup[] findAllGroups(SequenceI s);
+
+    /**
+     * Adds a new SequenceGroup to this alignment.
+     *
+     * @param sg New group to be added.
+     */
+    public void addGroup(SequenceGroup sg);
+
+    /**
+     * Deletes a specific SequenceGroup
+     *
+     * @param g Group will be deleted from alignment.
+     */
+    public void deleteGroup(SequenceGroup g);
+
+    /**
+     * Get all the groups associated with this alignment.
+     *
+     * @return All groups as a Vector.
+     */
+    public Vector getGroups();
+
+    /**
+     * Deletes all groups from this alignment.
+     */
+    public void deleteAllGroups();
+
+
+    /**
+     * Adds a new AlignmentAnnotation to this alignment
+     */
+    public void addAnnotation(AlignmentAnnotation aa);
+
+
+    public void setAnnotationIndex(AlignmentAnnotation aa, int index);
+
+    /**
+     * Deletes a specific AlignmentAnnotation from the alignment.
+     *
+     * @param aa DOCUMENT ME!
+     */
+    public void deleteAnnotation(AlignmentAnnotation aa);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AlignmentAnnotation[] getAlignmentAnnotation();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param gc DOCUMENT ME!
+     */
+    public void setGapCharacter(char gc);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public char getGapCharacter();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getAAFrequency();
+
+    /**
+     * Returns true if alignment is nucleotide sequence
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean isNucleotide();
+
+    /**
+     * Set true if the alignment is a nucleotide sequence
+     *
+     * @return
+     */
+    public void setNucleotide(boolean b);
+
+
+    public Alignment getDataset();
+
+    public 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();
+
+    public void adjustSequenceAnnotations();
+
+    public HiddenSequences getHiddenSequences();
+    /**
+     * Compact representation of alignment
+     * @return CigarArray
+     */
+    public CigarArray getCompactAlignment();
+}
index 1fa3b96..d113d92 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * <p>Title: </p>\r
- *\r
- * <p>Description: </p>\r
- *\r
- * <p>Copyright: Copyright (c) 2004</p>\r
- *\r
- * <p>Company: Dundee University</p>\r
- *\r
- * @author not attributable\r
- * @version 1.0\r
- */\r
-public class AlignmentOrder\r
-{\r
-    // JBPNote : this method would return a vector containing all sequences in seqset\r
-    // with those also contained in order at the beginning of the vector in the order\r
-    // given by order. AlignmentSorter.vectorSubsetToArray already does this, but that method\r
-    // should be here for completeness.\r
-\r
-    /*  public Vector getOrder(AlignmentI seqset)\r
-       {\r
-         Vector perm = new Vector(seqset.getHeight());\r
-         for (i=0, o = 0, n=seqset.getHeight(), p = Order.size(); i<n; i++)\r
-      perm.setElement(i,...).\r
-         return Order;\r
-       }\r
-     */\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int FILE = 0;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int MSA = 1;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int USER = 2;\r
-    private int Type = 0;\r
-    private String Name;\r
-    private Vector Order = null;\r
-\r
-    /**\r
-     * Creates a new AlignmentOrder object.\r
-     */\r
-    public AlignmentOrder()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * AlignmentOrder\r
-     *\r
-     * @param anOrder Vector\r
-     */\r
-    public AlignmentOrder(Vector anOrder)\r
-    {\r
-        Order = anOrder;\r
-    }\r
-\r
-    /**\r
-     * AlignmentOrder\r
-     *\r
-     * @param orderFrom AlignmentI\r
-     */\r
-    public AlignmentOrder(AlignmentI orderFrom)\r
-    {\r
-        Order = new Vector();\r
-\r
-        for (int i = 0, ns = orderFrom.getHeight(); i < ns; i++)\r
-        {\r
-            Order.addElement(orderFrom.getSequenceAt(i));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Creates a new AlignmentOrder object.\r
-     *\r
-     * @param orderFrom DOCUMENT ME!\r
-     */\r
-    public AlignmentOrder(SequenceI[] orderFrom)\r
-    {\r
-        Order = new Vector();\r
-\r
-        for (int i = 0, ns = orderFrom.length; i < ns; i++)\r
-        {\r
-            Order.addElement(orderFrom[i]);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param Type DOCUMENT ME!\r
-     */\r
-    public void setType(int Type)\r
-    {\r
-        this.Type = Type;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getType()\r
-    {\r
-        return Type;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param Name DOCUMENT ME!\r
-     */\r
-    public void setName(String Name)\r
-    {\r
-        this.Name = Name;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getName()\r
-    {\r
-        return Name;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param Order DOCUMENT ME!\r
-     */\r
-    public void setOrder(Vector Order)\r
-    {\r
-        this.Order = Order;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getOrder()\r
-    {\r
-        return Order;\r
-    }\r
-\r
-    /**\r
-     * AlignmentOrder\r
-     *\r
-     * @param orderThis AlignmentI\r
-     * @param byThat AlignmentI\r
-     */\r
-\r
-    /* public AlignmentOrder(AlignmentI orderThis, AlignmentI byThat)\r
-     {\r
-       // Vector is an ordering of this alignment using the order of sequence objects in byThat,\r
-       // where ids and unaligned sequences must match\r
-\r
-     } */\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import java.util.*;
+
+
+/**
+ * <p>Title: </p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2004</p>
+ *
+ * <p>Company: Dundee University</p>
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class AlignmentOrder
+{
+    // JBPNote : this method would return a vector containing all sequences in seqset
+    // with those also contained in order at the beginning of the vector in the order
+    // given by order. AlignmentSorter.vectorSubsetToArray already does this, but that method
+    // should be here for completeness.
+
+    /*  public Vector getOrder(AlignmentI seqset)
+       {
+         Vector perm = new Vector(seqset.getHeight());
+         for (i=0, o = 0, n=seqset.getHeight(), p = Order.size(); i<n; i++)
+      perm.setElement(i,...).
+         return Order;
+       }
+     */
+
+    /** DOCUMENT ME!! */
+    public static final int FILE = 0;
+
+    /** DOCUMENT ME!! */
+    public static final int MSA = 1;
+
+    /** DOCUMENT ME!! */
+    public static final int USER = 2;
+    private int Type = 0;
+    private String Name;
+    private Vector Order = null;
+
+    /**
+     * Creates a new AlignmentOrder object.
+     */
+    public AlignmentOrder()
+    {
+    }
+
+    /**
+     * AlignmentOrder
+     *
+     * @param anOrder Vector
+     */
+    public AlignmentOrder(Vector anOrder)
+    {
+        Order = anOrder;
+    }
+
+    /**
+     * AlignmentOrder
+     *
+     * @param orderFrom AlignmentI
+     */
+    public AlignmentOrder(AlignmentI orderFrom)
+    {
+        Order = new Vector();
+
+        for (int i = 0, ns = orderFrom.getHeight(); i < ns; i++)
+        {
+            Order.addElement(orderFrom.getSequenceAt(i));
+        }
+    }
+
+    /**
+     * Creates a new AlignmentOrder object.
+     *
+     * @param orderFrom DOCUMENT ME!
+     */
+    public AlignmentOrder(SequenceI[] orderFrom)
+    {
+        Order = new Vector();
+
+        for (int i = 0, ns = orderFrom.length; i < ns; i++)
+        {
+            Order.addElement(orderFrom[i]);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param Type DOCUMENT ME!
+     */
+    public void setType(int Type)
+    {
+        this.Type = Type;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getType()
+    {
+        return Type;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param Name DOCUMENT ME!
+     */
+    public void setName(String Name)
+    {
+        this.Name = Name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getName()
+    {
+        return Name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param Order DOCUMENT ME!
+     */
+    public void setOrder(Vector Order)
+    {
+        this.Order = Order;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getOrder()
+    {
+        return Order;
+    }
+    /**
+     * replaces oldref with newref in the alignment order.
+     * @param oldref
+     * @param newref
+     * @return true if oldref was contained in order and replaced with newref
+     */
+    public boolean updateSequence(SequenceI oldref, SequenceI newref) {
+      int found=Order.indexOf(oldref);
+      if (found>-1) {
+        Order.setElementAt(newref, found);
+      }
+      return found>-1;
+    }
+    /**
+     * Exact equivalence of two AlignmentOrders
+     * @param o
+     * @return true if o orders the same sequenceI objects in the same way
+     */
+    public boolean equals(AlignmentOrder o) {
+      return equals(o, true);
+    }
+    /**
+     * Exact equivalence of two AlignmentOrders
+     *  // TODO: Weak SequenceI equivalence - will throw Error at moment
+     * @param o
+     * @param identity - false - use weak equivalence (refers to same or different parts of same sequence)
+     * @return true if o orders equivalent sequenceI objects in the same way
+     */
+    public boolean equals(AlignmentOrder o, boolean identity) {
+      if (o!=this) {
+        if (o==null)
+          return false;
+        if (Order!=null && o.Order!=null && Order.size()==o.Order.size()) {
+          if (!identity) {
+            throw new Error("Weak sequenceI equivalence not yet implemented.");
+          } else {
+            for (int i=0,j=o.Order.size(); i<j; i++) {
+            if (Order.elementAt(i)!=o.Order.elementAt(i))
+              return false;
+            }
+          }
+        } else
+          return false;
+      }
+      return true;
+    }
+    /**
+     * Consistency test for alignmentOrders
+     * @param o
+     * @return true if o contains or is contained by this and the common SequenceI objects are ordered in the same way
+     */
+    public boolean isConsistent(AlignmentOrder o) {
+      return isConsistent(o, true);
+    }
+    /**
+     * Consistency test for alignmentOrders
+     * @param o
+     *  // TODO: Weak SequenceI equivalence - will throw Error at moment
+     * @param identity - false - use weak equivalence (refers to same or different parts of same sequence)
+     * @return true if o contains or is contained by this and the common SequenceI objects are ordered in the same way
+     */
+    public boolean isConsistent(AlignmentOrder o, boolean identity) {
+      if (o!=this) {
+        if (o==null)
+          return false;
+        if (Order!=null && o.Order!=null) {
+          Vector c,s;
+          if (o.Order.size()>Order.size()) {
+            c = o.Order;
+            s = Order;
+          } else {
+            c = Order;
+            s = o.Order;
+          }
+          if (!identity) {
+            throw new Error("Weak sequenceI equivalence not yet implemented.");
+          } else {
+            // test if c contains s and order in s is conserved in c
+            int last=-1;
+            for (int i=0,j=s.size(); i<j; i++) {
+              int pos=c.indexOf(s.elementAt(i)); // JBPNote - optimize by incremental position search
+              if (pos>last) {
+                last=pos;
+              } else
+                return false;
+            }
+          }
+        } else
+          return false;
+      }
+      return true;
+    }
+    /**
+     * AlignmentOrder
+     *
+     * @param orderThis AlignmentI
+     * @param byThat AlignmentI
+     */
+
+    /* public AlignmentOrder(AlignmentI orderThis, AlignmentI byThat)
+     {
+       // Vector is an ordering of this alignment using the order of sequence objects in byThat,
+       // where ids and unaligned sequences must match
+
+     } */
+}
index 2316d13..9aa8913 100755 (executable)
@@ -1,6 +1,6 @@
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package jalview.datamodel;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Annotation\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public String displayCharacter = "";\r
-\r
-    /** DOCUMENT ME!! */\r
-    public String description = ""; // currently used as mouse over\r
-\r
-    /** DOCUMENT ME!! */\r
-    public char secondaryStructure = ' '; // recognises H and E\r
-\r
-    /** DOCUMENT ME!! */\r
-    public float value;\r
-\r
-    // add visual cues here\r
-\r
-    /** DOCUMENT ME!! */\r
-    public Color colour = Color.black;\r
-\r
-    /**\r
-     * Creates a new Annotation object.\r
-     *\r
-     * @param displayChar DOCUMENT ME!\r
-     * @param desc DOCUMENT ME!\r
-     * @param ss DOCUMENT ME!\r
-     * @param val DOCUMENT ME!\r
-     */\r
-    public Annotation(String displayChar, String desc, char ss, float val)\r
-    {\r
-        displayCharacter = displayChar;\r
-        description = desc;\r
-        secondaryStructure = ss;\r
-        value = val;\r
-    }\r
-\r
-    /**\r
-     * Creates a new Annotation object.\r
-     *\r
-     * @param displayChar DOCUMENT ME!\r
-     * @param desc DOCUMENT ME!\r
-     * @param ss DOCUMENT ME!\r
-     * @param val DOCUMENT ME!\r
-     * @param colour DOCUMENT ME!\r
-     */\r
-    public Annotation(String displayChar, String desc, char ss, float val,\r
-        Color colour)\r
-    {\r
-        this(displayChar, desc, ss, val);\r
-        this.colour = colour;\r
-    }\r
-}\r
+*/
+package jalview.datamodel;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Annotation
+{
+    /** DOCUMENT ME!! */
+    public String displayCharacter = "";
+
+    /** DOCUMENT ME!! */
+    public String description = ""; // currently used as mouse over
+
+    /** DOCUMENT ME!! */
+    public char secondaryStructure = ' '; // recognises H and E
+
+    /** DOCUMENT ME!! */
+    public float value;
+
+    // add visual cues here
+
+    /** DOCUMENT ME!! */
+    public Color colour = Color.black;
+
+    /**
+     * Creates a new Annotation object.
+     *
+     * @param displayChar DOCUMENT ME!
+     * @param desc DOCUMENT ME!
+     * @param ss DOCUMENT ME!
+     * @param val DOCUMENT ME!
+     */
+    public Annotation(String displayChar, String desc, char ss, float val)
+    {
+        displayCharacter = displayChar;
+        description = desc;
+        secondaryStructure = ss;
+        value = val;
+    }
+
+    /**
+     * Creates a new Annotation object.
+     *
+     * @param displayChar DOCUMENT ME!
+     * @param desc DOCUMENT ME!
+     * @param ss DOCUMENT ME!
+     * @param val DOCUMENT ME!
+     * @param colour DOCUMENT ME!
+     */
+    public Annotation(String displayChar, String desc, char ss, float val,
+        Color colour)
+    {
+        this(displayChar, desc, ss, val);
+        this.colour = colour;
+    }
+}
index cbec833..bb9a426 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class BinaryNode\r
-{\r
-    Object element;\r
-    String name;\r
-    BinaryNode left;\r
-    BinaryNode right;\r
-    BinaryNode parent;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int bootstrap;\r
-\r
-    /**\r
-     * Creates a new BinaryNode object.\r
-     */\r
-    public BinaryNode()\r
-    {\r
-        left = right = parent = null;\r
-        bootstrap = 0;\r
-    }\r
-\r
-    /**\r
-     * Creates a new BinaryNode object.\r
-     *\r
-     * @param element DOCUMENT ME!\r
-     * @param parent DOCUMENT ME!\r
-     * @param name DOCUMENT ME!\r
-     */\r
-    public BinaryNode(Object element, BinaryNode parent, String name)\r
-    {\r
-        this.element = element;\r
-        this.parent = parent;\r
-        this.name = name;\r
-\r
-        left = right = null;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Object element()\r
-    {\r
-        return element;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param v DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Object setElement(Object v)\r
-    {\r
-        return element = v;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public BinaryNode left()\r
-    {\r
-        return left;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public BinaryNode setLeft(BinaryNode n)\r
-    {\r
-        return left = n;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public BinaryNode right()\r
-    {\r
-        return right;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public BinaryNode setRight(BinaryNode n)\r
-    {\r
-        return right = n;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public BinaryNode parent()\r
-    {\r
-        return parent;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public BinaryNode setParent(BinaryNode n)\r
-    {\r
-        return parent = n;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean isLeaf()\r
-    {\r
-        return (left == null) && (right == null);\r
-    }\r
-\r
-    /**\r
-     * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children of this node (removing any old references)\r
-     * a null parameter DOES NOT mean that the pointer to the corresponding child node is set to  NULL - you  should use\r
-     * setChild(null), or detach() for this.\r
-     *\r
-     */\r
-    public void SetChildren(BinaryNode leftchild, BinaryNode rightchild)\r
-    {\r
-        if (leftchild != null)\r
-        {\r
-            this.setLeft(leftchild);\r
-            leftchild.detach();\r
-            leftchild.setParent(this);\r
-        }\r
-\r
-        if (rightchild != null)\r
-        {\r
-            this.setRight(rightchild);\r
-            rightchild.detach();\r
-            rightchild.setParent(this);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Detaches the node from the binary tree, along with all its child nodes.\r
-     * @return BinaryNode The detached node.\r
-     */\r
-    public BinaryNode detach()\r
-    {\r
-        if (this.parent != null)\r
-        {\r
-            if (this.parent.left == this)\r
-            {\r
-                this.parent.left = null;\r
-            }\r
-            else\r
-            {\r
-                if (this.parent.right == this)\r
-                {\r
-                    this.parent.right = null;\r
-                }\r
-            }\r
-        }\r
-\r
-        this.parent = null;\r
-\r
-        return this;\r
-    }\r
-\r
-    /**\r
-     * Traverses up through the tree until a node with a free leftchild is discovered.\r
-     * @return BinaryNode\r
-     */\r
-    public BinaryNode ascendLeft()\r
-    {\r
-        BinaryNode c = this;\r
-\r
-        do\r
-        {\r
-            c = c.parent();\r
-        }\r
-        while ((c != null) && (c.left() != null) && !c.left().isLeaf());\r
-\r
-        return c;\r
-    }\r
-\r
-    /**\r
-     * Traverses up through the tree until a node with a free rightchild is discovered.\r
-     * Jalview builds trees by descent on the left, so this may be unused.\r
-     * @return BinaryNode\r
-     */\r
-    public BinaryNode ascendRight()\r
-    {\r
-        BinaryNode c = this;\r
-\r
-        do\r
-        {\r
-            c = c.parent();\r
-        }\r
-        while ((c != null) && (c.right() != null) && !c.right().isLeaf());\r
-\r
-        return c;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     */\r
-    public void setName(String name)\r
-    {\r
-        this.name = name;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getName()\r
-    {\r
-        return this.name;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param boot DOCUMENT ME!\r
-     */\r
-    public void setBootstrap(int boot)\r
-    {\r
-        this.bootstrap = boot;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getBootstrap()\r
-    {\r
-        return bootstrap;\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class BinaryNode
+{
+    Object element;
+    String name;
+    BinaryNode left;
+    BinaryNode right;
+    BinaryNode parent;
+
+    /** DOCUMENT ME!! */
+    public int bootstrap;
+
+    /**
+     * Creates a new BinaryNode object.
+     */
+    public BinaryNode()
+    {
+        left = right = parent = null;
+        bootstrap = 0;
+    }
+
+    /**
+     * Creates a new BinaryNode object.
+     *
+     * @param element DOCUMENT ME!
+     * @param parent DOCUMENT ME!
+     * @param name DOCUMENT ME!
+     */
+    public BinaryNode(Object element, BinaryNode parent, String name)
+    {
+        this.element = element;
+        this.parent = parent;
+        this.name = name;
+
+        left = right = null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Object element()
+    {
+        return element;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param v DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Object setElement(Object v)
+    {
+        return element = v;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public BinaryNode left()
+    {
+        return left;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public BinaryNode setLeft(BinaryNode n)
+    {
+        return left = n;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public BinaryNode right()
+    {
+        return right;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public BinaryNode setRight(BinaryNode n)
+    {
+        return right = n;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public BinaryNode parent()
+    {
+        return parent;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public BinaryNode setParent(BinaryNode n)
+    {
+        return parent = n;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean isLeaf()
+    {
+        return (left == null) && (right == null);
+    }
+
+    /**
+     * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children of this node (removing any old references)
+     * a null parameter DOES NOT mean that the pointer to the corresponding child node is set to  NULL - you  should use
+     * setChild(null), or detach() for this.
+     *
+     */
+    public void SetChildren(BinaryNode leftchild, BinaryNode rightchild)
+    {
+        if (leftchild != null)
+        {
+            this.setLeft(leftchild);
+            leftchild.detach();
+            leftchild.setParent(this);
+        }
+
+        if (rightchild != null)
+        {
+            this.setRight(rightchild);
+            rightchild.detach();
+            rightchild.setParent(this);
+        }
+    }
+
+    /**
+     * Detaches the node from the binary tree, along with all its child nodes.
+     * @return BinaryNode The detached node.
+     */
+    public BinaryNode detach()
+    {
+        if (this.parent != null)
+        {
+            if (this.parent.left == this)
+            {
+                this.parent.left = null;
+            }
+            else
+            {
+                if (this.parent.right == this)
+                {
+                    this.parent.right = null;
+                }
+            }
+        }
+
+        this.parent = null;
+
+        return this;
+    }
+
+    /**
+     * Traverses up through the tree until a node with a free leftchild is discovered.
+     * @return BinaryNode
+     */
+    public BinaryNode ascendLeft()
+    {
+        BinaryNode c = this;
+
+        do
+        {
+            c = c.parent();
+        }
+        while ((c != null) && (c.left() != null) && !c.left().isLeaf());
+
+        return c;
+    }
+
+    /**
+     * Traverses up through the tree until a node with a free rightchild is discovered.
+     * Jalview builds trees by descent on the left, so this may be unused.
+     * @return BinaryNode
+     */
+    public BinaryNode ascendRight()
+    {
+        BinaryNode c = this;
+
+        do
+        {
+            c = c.parent();
+        }
+        while ((c != null) && (c.right() != null) && !c.right().isLeaf());
+
+        return c;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getName()
+    {
+        return this.name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param boot DOCUMENT ME!
+     */
+    public void setBootstrap(int boot)
+    {
+        this.bootstrap = boot;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getBootstrap()
+    {
+        return bootstrap;
+    }
+}
index 89d3971..c638bb3 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.datamodel;\r
-\r
-import jalview.schemes.*;\r
-\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class BinarySequence extends Sequence\r
-{\r
-    int[] binary;\r
-    double[] dbinary;\r
-\r
-    /**\r
-     * Creates a new BinarySequence object.\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     */\r
-    public BinarySequence(SequenceI s)\r
-    {\r
-        super(s.getName(), s.getSequence(), s.getStart(), s.getEnd());\r
-    }\r
-\r
-    /**\r
-     * Creates a new BinarySequence object.\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     * @param sequence DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public BinarySequence(String name, String sequence, int start, int end)\r
-    {\r
-        super(name, sequence, start, end);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void encode()\r
-    {\r
-        // Set all matrix to 0\r
-        dbinary = new double[getSequence().length() * 21];\r
-\r
-        int nores = 21;\r
-\r
-        for (int i = 0; i < dbinary.length; i++)\r
-        {\r
-            dbinary[i] = 0.0;\r
-        }\r
-\r
-        for (int i = 0; i < getSequence().length(); i++)\r
-        {\r
-            int aanum = 20;\r
-\r
-            try\r
-            {\r
-                aanum = ((Integer) ResidueProperties.getAAHash().get(getSequence()\r
-                                                                         .substring(i,\r
-                            i + 1))).intValue();\r
-            }\r
-            catch (NullPointerException e)\r
-            {\r
-                aanum = 20;\r
-            }\r
-\r
-            if (aanum > 20)\r
-            {\r
-                aanum = 20;\r
-            }\r
-\r
-            dbinary[(i * nores) + aanum] = 1.0;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void blosumEncode()\r
-    {\r
-        // Set all matrix to 0\r
-        dbinary = new double[getSequence().length() * 21];\r
-\r
-        int nores = 21;\r
-\r
-        //for (int i = 0; i < dbinary.length; i++) {\r
-        //  dbinary[i] = 0.0;\r
-        //}\r
-        for (int i = 0; i < getSequence().length(); i++)\r
-        {\r
-            int aanum = 20;\r
-\r
-            try\r
-            {\r
-                aanum = ((Integer) ResidueProperties.getAAHash().get(getSequence()\r
-                                                                         .substring(i,\r
-                            i + 1))).intValue();\r
-            }\r
-            catch (NullPointerException e)\r
-            {\r
-                aanum = 20;\r
-            }\r
-\r
-            if (aanum > 20)\r
-            {\r
-                aanum = 20;\r
-            }\r
-\r
-            // Do the blosum thing\r
-            for (int j = 0; j < 20; j++)\r
-            {\r
-                dbinary[(i * nores) + j] = ResidueProperties.getBLOSUM62()[aanum][j];\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String toBinaryString()\r
-    {\r
-        String out = "";\r
-\r
-        for (int i = 0; i < binary.length; i++)\r
-        {\r
-            out += (new Integer(binary[i])).toString();\r
-\r
-            if (i < (binary.length - 1))\r
-            {\r
-                out += " ";\r
-            }\r
-        }\r
-\r
-        return out;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public double[] getDBinary()\r
-    {\r
-        return dbinary;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param rt DOCUMENT ME!\r
-     */\r
-    public static void printMemory(Runtime rt)\r
-    {\r
-        System.out.println("DEBUG: Free memory = " + rt.freeMemory()); // log.\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.datamodel;
+
+import jalview.schemes.*;
+
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class BinarySequence extends Sequence
+{
+    int[] binary;
+    double[] dbinary;
+
+    /**
+     * Creates a new BinarySequence object.
+     *
+     * @param s DOCUMENT ME!
+     */
+    public BinarySequence(String s)
+    {
+        super("", s, 0, s.length());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void encode()
+    {
+        // Set all matrix to 0
+        dbinary = new double[getSequence().length() * 21];
+
+        int nores = 21;
+
+        for (int i = 0; i < dbinary.length; i++)
+        {
+            dbinary[i] = 0.0;
+        }
+
+        for (int i = 0; i < getSequence().length(); i++)
+        {
+            int aanum = 20;
+
+            try
+            {
+                aanum = ((Integer) ResidueProperties.getAAHash().get(getSequence()
+                                                                         .substring(i,
+                            i + 1))).intValue();
+            }
+            catch (NullPointerException e)
+            {
+                aanum = 20;
+            }
+
+            if (aanum > 20)
+            {
+                aanum = 20;
+            }
+
+            dbinary[(i * nores) + aanum] = 1.0;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void blosumEncode()
+    {
+        // Set all matrix to 0
+        dbinary = new double[getSequence().length() * 21];
+
+        int nores = 21;
+
+        //for (int i = 0; i < dbinary.length; i++) {
+        //  dbinary[i] = 0.0;
+        //}
+        for (int i = 0; i < getSequence().length(); i++)
+        {
+            int aanum = 20;
+
+            try
+            {
+                aanum = ((Integer) ResidueProperties.getAAHash().get(getSequence()
+                                                                         .substring(i,
+                            i + 1))).intValue();
+            }
+            catch (NullPointerException e)
+            {
+                aanum = 20;
+            }
+
+            if (aanum > 20)
+            {
+                aanum = 20;
+            }
+
+            // Do the blosum thing
+            for (int j = 0; j < 20; j++)
+            {
+                dbinary[(i * nores) + j] = ResidueProperties.getBLOSUM62()[aanum][j];
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String toBinaryString()
+    {
+        String out = "";
+
+        for (int i = 0; i < binary.length; i++)
+        {
+            out += (new Integer(binary[i])).toString();
+
+            if (i < (binary.length - 1))
+            {
+                out += " ";
+            }
+        }
+
+        return out;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public double[] getDBinary()
+    {
+        return dbinary;
+    }
+
+}
index 57f6021..253136d 100755 (executable)
@@ -1,41 +1,41 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-public class DBRefEntry\r
-{\r
-  String source, version, accessionId;\r
-\r
-  public DBRefEntry(String source, String version, String accessionId)\r
-  {\r
-    this.source = source;\r
-    this.version = version;\r
-    this.accessionId = accessionId;\r
-  }\r
-\r
-  public String getSource()\r
-  {    return source; }\r
-\r
-  public String getVersion()\r
-  { return version; }\r
-\r
-  public String getAccessionId()\r
-  { return accessionId; }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+public class DBRefEntry
+{
+  String source, version, accessionId;
+
+  public DBRefEntry(String source, String version, String accessionId)
+  {
+    this.source = source;
+    this.version = version;
+    this.accessionId = accessionId;
+  }
+
+  public String getSource()
+  {    return source; }
+
+  public String getVersion()
+  { return version; }
+
+  public String getAccessionId()
+  { return accessionId; }
+
+}
index 2f484ac..1417542 100755 (executable)
@@ -1,37 +1,37 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.datamodel;\r
-\r
-public class GraphLine\r
-{\r
-    public float value;\r
-    public String label = "";\r
-    public java.awt.Color colour = java.awt.Color.black;\r
-    public boolean displayed = true;\r
-\r
-    public GraphLine(float value, String label, java.awt.Color col)\r
-    {\r
-      this.value = value;\r
-      if(label != null)\r
-        this.label = label;\r
-\r
-      if(col != null )\r
-        this.colour = col;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.datamodel;
+
+public class GraphLine
+{
+    public float value;
+    public String label = "";
+    public java.awt.Color colour = java.awt.Color.black;
+    public boolean displayed = true;
+
+    public GraphLine(float value, String label, java.awt.Color col)
+    {
+      this.value = value;
+      if(label != null)
+        this.label = label;
+
+      if(col != null )
+        this.colour = col;
+    }
+}
index 3a5946c..be7dbe2 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.datamodel;\r
-\r
-import java.util.*;\r
-\r
-public class HiddenSequences\r
-{\r
-  Hashtable hiddenSequences;\r
-  AlignmentI alignment;\r
-\r
-  public HiddenSequences(AlignmentI al)\r
-  {\r
-    alignment = al;\r
-  }\r
-\r
-  public int getSize()\r
-  {\r
-    return hiddenSequences == null ? 0 : hiddenSequences.size();\r
-  }\r
-\r
-  public void hideSequence(SequenceI sequence)\r
-  {\r
-    if(hiddenSequences==null)\r
-      hiddenSequences = new Hashtable();\r
-\r
-    int alignmentIndex = alignment.findIndex(sequence);\r
-    alignmentIndex = adjustForHiddenSeqs(alignmentIndex);\r
-\r
-    hiddenSequences.put(new Integer(alignmentIndex), sequence);\r
-\r
-    alignment.deleteSequence(sequence);\r
-  }\r
-\r
-  public void showSequence(int alignmentIndex)\r
-  {\r
-    SequenceI repSequence = alignment.getSequenceAt(alignmentIndex);\r
-    if(repSequence.getHiddenSequences()==null && alignmentIndex>0)\r
-      repSequence = alignment.getSequenceAt(alignmentIndex-1);\r
-    if(repSequence.getHiddenSequences()==null)\r
-      repSequence = null;\r
-\r
-    int start = adjustForHiddenSeqs(alignmentIndex-1);\r
-    int end = adjustForHiddenSeqs(alignmentIndex);\r
-\r
-    for(int index = end; index > start; index--)\r
-    {\r
-      SequenceI seq =  (SequenceI)hiddenSequences.remove(new Integer(\r
-          index));\r
-\r
-      if(seq!=null)\r
-      {\r
-        alignment.getSequences().insertElementAt(seq, alignmentIndex);\r
-        if(repSequence!=null)\r
-        {\r
-          repSequence.showHiddenSequence(seq);\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  public SequenceI getHiddenSequence(int alignmentIndex)\r
-  {\r
-    return (SequenceI)hiddenSequences.get(new Integer(alignmentIndex));\r
-  }\r
-\r
-  public int findIndexWithoutHiddenSeqs(int alignmentIndex)\r
-  {\r
-    int index = 0;\r
-    int hiddenSeqs = 0;\r
-    while(index <= alignmentIndex)\r
-    {\r
-     if(hiddenSequences.containsKey(new Integer(index)))\r
-     {\r
-       hiddenSeqs ++;\r
-     }\r
-      index ++;\r
-    };\r
-\r
-    return (alignmentIndex - hiddenSeqs) ;\r
-  }\r
-\r
-  public int adjustForHiddenSeqs(int alignmentIndex)\r
-  {\r
-    int index = 0;\r
-    while(index <= alignmentIndex)\r
-    {\r
-     if(hiddenSequences.containsKey(new Integer(index)))\r
-     {\r
-       alignmentIndex ++;\r
-     }\r
-      index ++;\r
-    };\r
-\r
-    return alignmentIndex ;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.datamodel;
+
+import java.util.*;
+
+public class HiddenSequences
+{
+  Hashtable hiddenSequences;
+  AlignmentI alignment;
+
+  public HiddenSequences(AlignmentI al)
+  {
+    alignment = al;
+  }
+
+  public int getSize()
+  {
+    return hiddenSequences == null ? 0 : hiddenSequences.size();
+  }
+
+  public int getWidth()
+  {
+    Enumeration en = hiddenSequences.elements();
+    int width = 0;
+    while(en.hasMoreElements())
+    {
+      SequenceI seq = (SequenceI)en.nextElement();
+      if(seq.getLength()>width)
+        width = seq.getLength();
+    }
+    return width;
+  }
+
+  public void hideSequence(SequenceI sequence)
+  {
+    if(hiddenSequences==null)
+      hiddenSequences = new Hashtable();
+
+    int alignmentIndex = alignment.findIndex(sequence);
+    alignmentIndex = adjustForHiddenSeqs(alignmentIndex);
+
+    hiddenSequences.put(new Integer(alignmentIndex), sequence);
+
+    alignment.deleteSequence(sequence);
+  }
+
+  public Vector showAll()
+  {
+   Vector revealedSeqs = new Vector();
+   for(int i=0; i<alignment.getHeight()+hiddenSequences.size(); i++)
+    {
+      Vector tmp = showSequence(i);
+      for(int t=0; t<tmp.size(); t++)
+        revealedSeqs.addElement(tmp.elementAt(t));
+    }
+    return revealedSeqs;
+  }
+
+  public Vector showSequence(int alignmentIndex)
+  {
+    Vector revealedSeqs = new Vector();
+    SequenceI repSequence = alignment.getSequenceAt(alignmentIndex);
+    if(repSequence!=null
+       && repSequence.getHiddenSequences()==null
+       && alignmentIndex>0)
+      repSequence = alignment.getSequenceAt(alignmentIndex-1);
+
+    if(repSequence!=null
+       && repSequence.getHiddenSequences()==null)
+      repSequence = null;
+
+    int start = adjustForHiddenSeqs(alignmentIndex-1);
+    int end = adjustForHiddenSeqs(alignmentIndex);
+
+    for(int index = end; index > start; index--)
+    {
+      SequenceI seq =  (SequenceI)hiddenSequences.remove(new Integer(
+          index));
+
+
+      if(seq!=null)
+      {
+        revealedSeqs.addElement(seq);
+        alignment.getSequences().insertElementAt(seq, alignmentIndex);
+        if(repSequence!=null)
+        {
+          repSequence.showHiddenSequence(seq);
+        }
+      }
+    }
+
+    return revealedSeqs;
+  }
+
+  public Hashtable getHiddenSequences()
+  {
+    return hiddenSequences;
+  }
+
+  public SequenceI getHiddenSequence(int alignmentIndex)
+  {
+    return (SequenceI)hiddenSequences.get(new Integer(alignmentIndex));
+  }
+
+  public int findIndexWithoutHiddenSeqs(int alignmentIndex)
+  {
+    int index = 0;
+    int hiddenSeqs = 0;
+    while(index <= alignmentIndex)
+    {
+     if(hiddenSequences.containsKey(new Integer(index)))
+     {
+       hiddenSeqs ++;
+     }
+      index ++;
+    };
+
+    return (alignmentIndex - hiddenSeqs) ;
+  }
+
+  public int adjustForHiddenSeqs(int alignmentIndex)
+  {
+    int index = 0;
+    while(index <= alignmentIndex)
+    {
+     if(hiddenSequences.containsKey(new Integer(index)))
+     {
+       alignmentIndex ++;
+     }
+      index ++;
+    };
+
+    return alignmentIndex ;
+  }
+
+  public AlignmentI getFullAlignment()
+  {
+    int isize = alignment.getHeight()+hiddenSequences.size();
+    SequenceI [] seq = new Sequence[isize];
+
+    Enumeration en = hiddenSequences.keys();
+    while(en.hasMoreElements())
+    {
+      Integer key = (Integer)en.nextElement();
+      seq[key.intValue()] = (SequenceI)hiddenSequences.get(key);
+    }
+
+    int index = 0;
+    for(int i=0; i<isize; i++)
+    {
+      if(seq[i]!=null)
+      {
+        continue;
+      }
+
+      seq[i] = alignment.getSequenceAt(index);
+      index++;
+    }
+
+    return new Alignment(seq);
+  }
+
+  public boolean isHidden(SequenceI seq)
+  {
+    return hiddenSequences.contains(seq);
+  }
+}
index 0520bc0..37e4ce0 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.datamodel;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class HistoryItem\r
-{\r
-  /** DOCUMENT ME!! */\r
-  public static final int EDIT = 0;\r
-\r
-  /** DOCUMENT ME!! */\r
-  public static final int SORT = 1;\r
-\r
-  /** DOCUMENT ME!! */\r
-  public static final int HIDE = 2;\r
-\r
-  /** DOCUMENT ME!! */\r
-  public static final int PASTE = 3;\r
-\r
-  final int type;\r
-\r
-  AlignmentI alignment;\r
-  String description;\r
-\r
-  Vector sequences;\r
-  Vector seqAsString;\r
-  Vector alignIndex;\r
-\r
-  Vector hiddenSeqs;\r
-  Vector hiddenSeqsAsString;\r
-\r
-\r
-  /**\r
-   * Creates a new HistoryItem object.\r
-   *\r
-   * @param description DOCUMENT ME!\r
-   * @param al DOCUMENT ME!\r
-   * @param type DOCUMENT ME!\r
-   */\r
-  public HistoryItem(String description, AlignmentI al, int type)\r
-  {\r
-    alignment = al;\r
-    this.type = type;\r
-    this.description = description;\r
-    sequences = new Vector();\r
-    alignIndex = new Vector();\r
-    seqAsString = new Vector();\r
-\r
-    for (int i = 0; i < al.getHeight(); i++)\r
-    {\r
-      SequenceI seq = al.getSequenceAt(i);\r
-      sequences.addElement(seq);\r
-      alignIndex.addElement(i + "");\r
-      seqAsString.addElement(seq.getSequence().toString());\r
-    }\r
-\r
-    if(alignment.getHiddenSequences()!=null\r
-       && alignment.getHiddenSequences().getSize()>0)\r
-    {\r
-      hiddenSeqs = new Vector();\r
-      hiddenSeqsAsString = new Vector();\r
-      Enumeration en = alignment.getHiddenSequences().hiddenSequences.elements();\r
-      while (en.hasMoreElements())\r
-      {\r
-        SequenceI key = (SequenceI) en.nextElement();\r
-        hiddenSeqs.addElement(key);\r
-        hiddenSeqsAsString.addElement(key.getSequence().toString());\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public String getDescription()\r
-  {\r
-    return description;\r
-  }\r
-\r
-\r
-  public void restore()\r
-  {\r
-    if (type == HistoryItem.SORT)\r
-    {\r
-      for (int i = 0; i < sequences.size(); i++)\r
-      {\r
-        alignment.getSequences().setElementAt(sequences.elementAt(i), i);\r
-      }\r
-    }\r
-    else\r
-    {\r
-\r
-      for (int i = 0; i < sequences.size(); i++)\r
-      {\r
-        SequenceI restore = (SequenceI) sequences.elementAt(i);\r
-\r
-        if (restore.getLength() == 0)\r
-        {\r
-          //This is for edits which remove all residues in a sequence\r
-          restore.setSequence(seqAsString.elementAt(i).toString());\r
-          alignment.getSequences().insertElementAt(restore,\r
-              Integer.parseInt(alignIndex.elementAt(i).toString()));\r
-        }\r
-        else\r
-        {\r
-          restore.setSequence(seqAsString.elementAt(i).toString());\r
-        }\r
-      }\r
-\r
-      if(hiddenSeqs!=null)\r
-      {\r
-        for(int hs=0; hs<hiddenSeqs.size(); hs++)\r
-        {\r
-          SequenceI key = (SequenceI) hiddenSeqs.elementAt(hs);\r
-          key.setSequence(hiddenSeqsAsString.elementAt(hs).toString());\r
-        }\r
-      }\r
-\r
-      if (type == HistoryItem.PASTE)\r
-      {\r
-        for (int i = alignment.getHeight() - 1;\r
-             i > (sequences.size() - 1); i--)\r
-        {\r
-          alignment.deleteSequence(i);\r
-        }\r
-      }\r
-    }\r
-\r
-  }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.datamodel;
+
+import jalview.util.ShiftList;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class HistoryItem
+{
+  /** DOCUMENT ME!! */
+  public static final int EDIT = 0;
+
+  /** DOCUMENT ME!! */
+  public static final int SORT = 1;
+
+  /** DOCUMENT ME!! */
+  public static final int HIDE = 2;
+
+  /** DOCUMENT ME!! */
+  public static final int PASTE = 3;
+
+  final int type;
+
+  AlignmentI alignment;
+  String description;
+
+  Vector sequences;
+  Vector seqAsString;
+  Vector alignIndex;
+
+  Vector hiddenSeqs;
+  Vector hiddenSeqsAsString;
+  /**
+   * public field - set directly if history involves a frame shift
+   * should contain the <em>inverse</em> frame shift operations.
+   */
+  public ShiftList alColumnChanges=null;
+
+  /**
+   * Creates a new HistoryItem object.
+   *
+   * @param description DOCUMENT ME!
+   * @param al DOCUMENT ME!
+   * @param type DOCUMENT ME!
+   */
+  public HistoryItem(String description, AlignmentI al, int type)
+  {
+    alignment = al;
+    this.type = type;
+    this.description = description;
+    sequences = new Vector();
+    alignIndex = new Vector();
+    seqAsString = new Vector();
+
+    for (int i = 0; i < al.getHeight(); i++)
+    {
+      SequenceI seq = al.getSequenceAt(i);
+      sequences.addElement(seq);
+      alignIndex.addElement(i + "");
+      seqAsString.addElement(seq.getStart()
+                             +" "+seq.getEnd()
+                             +" "+seq.getSequence().toString());
+    }
+
+    if(alignment.getHiddenSequences()!=null
+       && alignment.getHiddenSequences().getSize()>0)
+    {
+      hiddenSeqs = new Vector();
+      hiddenSeqsAsString = new Vector();
+      Enumeration en = alignment.getHiddenSequences().hiddenSequences.elements();
+      while (en.hasMoreElements())
+      {
+        SequenceI key = (SequenceI) en.nextElement();
+        hiddenSeqs.addElement(key);
+        hiddenSeqsAsString.addElement(key.getSequence().toString());
+      }
+    }
+  }
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * restore state - adjusting gui hiddenColumn view as necessary
+   * @param columnSelection
+   */
+  public void restore(ColumnSelection columnSelection)
+  {
+    if (type == HistoryItem.SORT)
+    {
+      for (int i = 0; i < sequences.size(); i++)
+      {
+        alignment.getSequences().setElementAt(sequences.elementAt(i), i);
+      }
+    }
+    else
+    {
+      StringTokenizer st;
+      for (int i = 0; i < sequences.size(); i++)
+      {
+        SequenceI restore = (SequenceI) sequences.elementAt(i);
+
+
+        if (restore.getLength() == 0)
+        {
+          //This is for edits which remove all residues in a sequence
+          alignment.getSequences().insertElementAt(restore,
+              Integer.parseInt(alignIndex.elementAt(i).toString()));
+        }
+
+        st = new StringTokenizer(seqAsString.elementAt(i).toString());
+        restore.setStart(Integer.parseInt(st.nextToken()));
+        restore.setEnd(Integer.parseInt(st.nextToken()));
+        restore.setSequence(st.nextToken());
+      }
+
+      if(hiddenSeqs!=null)
+      {
+        for(int hs=0; hs<hiddenSeqs.size(); hs++)
+        {
+          SequenceI key = (SequenceI) hiddenSeqs.elementAt(hs);
+          key.setSequence(hiddenSeqsAsString.elementAt(hs).toString());
+        }
+      }
+
+      if (type == HistoryItem.PASTE)
+      {
+        for (int i = alignment.getHeight() - 1;
+             i > (sequences.size() - 1); i--)
+        {
+          alignment.deleteSequence(i);
+        }
+      }
+      if (alColumnChanges!=null) {
+        columnSelection.compensateForEdits(alColumnChanges);
+      }
+    }
+
+  }
+  /**
+   * note a frame shift that must be compensated for
+   * @param pos start position for shift (in original reference frame)
+   * @param shift length of shift
+   */
+  public void addShift(int pos, int shift) {
+    if (alColumnChanges==null)
+      alColumnChanges = new ShiftList();
+    alColumnChanges.addShift(pos, -shift);
+  }
+}
index 356a75f..5ca3400 100755 (executable)
@@ -1,54 +1,61 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import java.util.*;\r
-public class PDBEntry\r
-{\r
-  String type;\r
-  String id;\r
-  Hashtable properties;\r
-\r
-  public PDBEntry()\r
-  {  }\r
-\r
-  public void setType(String type)\r
-  { this.type = type; }\r
-\r
-  public String getType()\r
-  { return type; }\r
-\r
-  public void setId(String id)\r
-  { this.id = id; }\r
-\r
-  public String getId()\r
-  { return id; }\r
-\r
-  public void setProperty(Hashtable property)\r
-  {\r
-    this.properties = property;\r
-  }\r
-\r
-  public Hashtable getProperty()\r
-  {\r
-    return properties;\r
-  }\r
-\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import java.util.*;
+public class PDBEntry
+{
+  String file;
+  String type;
+  String id;
+  Hashtable properties;
+
+  public PDBEntry()
+  {  }
+
+  public void setFile(String file)
+  { this.file = file; }
+
+  public String getFile()
+  {  return file; }
+
+  public void setType(String type)
+  { this.type = type; }
+
+  public String getType()
+  { return type; }
+
+  public void setId(String id)
+  { this.id = id; }
+
+  public String getId()
+  { return id; }
+
+  public void setProperty(Hashtable property)
+  {
+    this.properties = property;
+  }
+
+  public Hashtable getProperty()
+  {
+    return properties;
+  }
+
+
+}
index 52d3662..8b64998 100755 (executable)
@@ -1,44 +1,44 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-import java.util.*;\r
-\r
-public class Provenance\r
-{\r
-  Vector entries = new Vector();\r
-  public Provenance()\r
-  {\r
-\r
-  }\r
-\r
-  public ProvenanceEntry[] getEntries()\r
-  {\r
-    ProvenanceEntry [] ret = new ProvenanceEntry[entries.size()];\r
-    for(int i=0; i<entries.size(); i++)\r
-       ret[i] = (ProvenanceEntry)entries.elementAt(i);\r
-    return ret;\r
-  }\r
-\r
-  public void addEntry(String user, String action, java.util.Date date, String id)\r
-  {\r
-    entries.addElement( new ProvenanceEntry(user,action,date,id));\r
-  }\r
-\r
-}\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+import java.util.*;
+
+public class Provenance
+{
+  Vector entries = new Vector();
+  public Provenance()
+  {
+
+  }
+
+  public ProvenanceEntry[] getEntries()
+  {
+    ProvenanceEntry [] ret = new ProvenanceEntry[entries.size()];
+    for(int i=0; i<entries.size(); i++)
+       ret[i] = (ProvenanceEntry)entries.elementAt(i);
+    return ret;
+  }
+
+  public void addEntry(String user, String action, java.util.Date date, String id)
+  {
+    entries.addElement( new ProvenanceEntry(user,action,date,id));
+  }
+
+}
+
index f8c77d7..a993bc9 100755 (executable)
@@ -1,41 +1,41 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-public class ProvenanceEntry\r
-{\r
-    String user, action, id;\r
-    java.util.Date date;\r
-    public ProvenanceEntry(String u, String a, java.util.Date d, String i)\r
-    {\r
-      user = u; action = a; date = d; id = i;\r
-    }\r
-\r
-    public String getUser()\r
-    {return user;}\r
-\r
-    public String getAction()\r
-    {return action;}\r
-\r
-    public java.util.Date getDate()\r
-    {return date;}\r
-\r
-    public String getID()\r
-    {return id;}\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+public class ProvenanceEntry
+{
+    String user, action, id;
+    java.util.Date date;
+    public ProvenanceEntry(String u, String a, java.util.Date d, String i)
+    {
+      user = u; action = a; date = d; id = i;
+    }
+
+    public String getUser()
+    {return user;}
+
+    public String getAction()
+    {return action;}
+
+    public java.util.Date getDate()
+    {return date;}
+
+    public String getID()
+    {return id;}
+}
index b0535b6..7d0b532 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-public class SearchResults\r
-{\r
-\r
-  Match [] matches;\r
-\r
-    /**\r
-     * This method replaces the old search results which merely\r
-     * held an alignment index of search matches. This broke\r
-     * when sequences were moved around the alignment\r
-     * @param seq Sequence\r
-     * @param start int\r
-     * @param end int\r
-     */\r
-  public void addResult(SequenceI seq, int start, int end)\r
-  {\r
-    if(matches == null)\r
-    {\r
-      matches = new Match[]{new Match(seq, start, end)};\r
-      return;\r
-    }\r
-\r
-    int mSize = matches.length;\r
-\r
-    Match [] tmp = new Match[mSize+1];\r
-    int m;\r
-    for(m=0; m<mSize; m++)\r
-    {\r
-      tmp[m] = matches[m];\r
-    }\r
-\r
-    tmp[m] = new Match(seq, start, end);\r
-\r
-    matches = tmp;\r
-  }\r
-\r
-  /**\r
-  * This Method returns the search matches which lie between the\r
-  * start and end points of the sequence in question. It is\r
-  * optimised for returning objects for drawing on SequenceCanvas\r
-  */\r
-  public int [] getResults(SequenceI sequence, int start, int end)\r
-  {\r
-    if(matches==null)\r
-      return null;\r
-\r
-    int [] result = null;\r
-    int [] tmp = null;\r
-    int resultLength;\r
-\r
-    for(int m=0; m<matches.length; m++)\r
-    {\r
-      if( matches[m].sequence == sequence )\r
-      {\r
-        int matchStart = matches[m].sequence.findIndex( matches[m].start ) - 1;\r
-        int matchEnd = matches[m].sequence.findIndex( matches[m].end ) - 1;\r
-\r
-        if(matchStart<=end && matchEnd>=start)\r
-        {\r
-          if(matchStart<start)\r
-            matchStart = start;\r
-\r
-          if(matchEnd>end)\r
-            matchEnd = end;\r
-\r
-\r
-          if(result==null)\r
-            result = new int[]{matchStart, matchEnd};\r
-          else\r
-          {\r
-            resultLength = result.length;\r
-            tmp = new int[resultLength+2];\r
-            System.arraycopy(result,0,tmp,0,resultLength);\r
-            result = tmp;\r
-            result[resultLength] = matchStart;\r
-            result[resultLength+1] = matchEnd;\r
-          }\r
-        }\r
-      }\r
-    }\r
-    return result;\r
-  }\r
-\r
-  public int getSize()\r
-  {\r
-    return matches==null ? 0 : matches.length;\r
-  }\r
-\r
-  public SequenceI getResultSequence(int index)\r
-  {    return matches[index].sequence;  }\r
-\r
-  public int getResultStart(int index)\r
-  {    return matches[index].start;  }\r
-\r
-  public int getResultEnd(int index)\r
-  {    return matches[index].end;  }\r
-\r
-  class Match\r
-  {\r
-    SequenceI sequence;\r
-    int start;\r
-    int end;\r
-\r
-    public Match(SequenceI seq, int start, int end)\r
-    {\r
-     sequence = seq;\r
-     this.start = start;\r
-     this.end = end;\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+public class SearchResults
+{
+
+  Match [] matches;
+
+    /**
+     * This method replaces the old search results which merely
+     * held an alignment index of search matches. This broke
+     * when sequences were moved around the alignment
+     * @param seq Sequence
+     * @param start int
+     * @param end int
+     */
+  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;
+  }
+
+  /**
+  * This Method returns the search matches which lie between the
+  * start and end points of the sequence in question. It is
+  * optimised for returning objects for drawing on SequenceCanvas
+  */
+  public int [] getResults(SequenceI sequence, int start, int end)
+  {
+    if(matches==null)
+      return null;
+
+    int [] result = null;
+    int [] tmp = null;
+    int resultLength;
+
+    for(int m=0; m<matches.length; m++)
+    {
+      if( matches[m].sequence == sequence )
+      {
+        int matchStart = matches[m].sequence.findIndex( matches[m].start ) - 1;
+        int matchEnd = matches[m].sequence.findIndex( matches[m].end ) - 1;
+
+        if(matchStart<=end && matchEnd>=start)
+        {
+          if(matchStart<start)
+            matchStart = start;
+
+          if(matchEnd>end)
+            matchEnd = end;
+
+
+          if(result==null)
+            result = new int[]{matchStart, matchEnd};
+          else
+          {
+            resultLength = result.length;
+            tmp = new int[resultLength+2];
+            System.arraycopy(result,0,tmp,0,resultLength);
+            result = tmp;
+            result[resultLength] = matchStart;
+            result[resultLength+1] = matchEnd;
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+  public int getSize()
+  {
+    return matches==null ? 0 : matches.length;
+  }
+
+  public SequenceI getResultSequence(int index)
+  {    return matches[index].sequence;  }
+
+  public int getResultStart(int index)
+  {    return matches[index].start;  }
+
+  public int getResultEnd(int index)
+  {    return matches[index].end;  }
+
+  class Match
+  {
+    SequenceI sequence;
+    int start;
+    int end;
+
+    public Match(SequenceI seq, int start, int end)
+    {
+     sequence = seq;
+     this.start = start;
+     this.end = end;
+    }
+  }
+}
index f593226..635043b 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.datamodel;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Sequence implements SequenceI\r
-{\r
-    SequenceI datasetSequence;\r
-    String name;\r
-    String sequence;\r
-    String description;\r
-    int start;\r
-    int end;\r
-    Color color = Color.white;\r
-    Vector pdbIds;\r
-    String vamsasId;\r
-    Vector dbrefs;\r
-\r
-    /** This annotation is displayed below the alignment but the\r
-     * positions are tied to the residues of this sequence */\r
-    Vector annotation;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public SequenceFeature [] sequenceFeatures;\r
-\r
-    /** This array holds hidden sequences\r
-     * of which this sequence is the representitive member of a group\r
-     */\r
-    SequenceGroup hiddenSequences;\r
-\r
-    /**\r
-     * Creates a new Sequence object.\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     * @param sequence DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public Sequence(String name, String sequence, int start, int end)\r
-    {\r
-      this.name = name;\r
-      this.sequence = sequence;\r
-      this.start = start;\r
-      this.end = end;\r
-\r
-      parseId();\r
-\r
-      checkValidRange();\r
-    }\r
-\r
-    com.stevesoft.pat.Regex limitrx = new com.stevesoft.pat.Regex(\r
-                        "[/][0-9]{1,}[-][0-9]{1,}$");\r
-    com.stevesoft.pat.Regex endrx = new com.stevesoft.pat.Regex(\r
-                        "[0-9]{1,}$");\r
-\r
-    void parseId()\r
-    {\r
-        // Does sequence have the /start-end signiature?\r
-         if(limitrx.search(name))\r
-         {\r
-            name = limitrx.left();\r
-            endrx.search(limitrx.stringMatched());\r
-            setStart( Integer.parseInt( limitrx.stringMatched().substring(1,endrx.matchedFrom()-1 )));\r
-            setEnd(   Integer.parseInt( endrx.stringMatched() ));\r
-         }\r
-    }\r
-\r
-    void checkValidRange()\r
-    {\r
-      if (end < 1)\r
-      {\r
-        int endRes = 0;\r
-        char ch;\r
-        for (int j = 0; j < sequence.length(); j++)\r
-        {\r
-          ch = sequence.charAt(j);\r
-          if (!jalview.util.Comparison.isGap( (ch)))\r
-          {\r
-            endRes++;\r
-          }\r
-        }\r
-        if (endRes > 0)\r
-        {\r
-          endRes += start - 1;\r
-        }\r
-\r
-        this.end = endRes;\r
-      }\r
-\r
-    }\r
-\r
-    /**\r
-     * Creates a new Sequence object.\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     * @param sequence DOCUMENT ME!\r
-     */\r
-    public Sequence(String name, String sequence)\r
-    {\r
-        this(name, sequence, 1, -1);\r
-    }\r
-\r
-    /**\r
-     * Creates a new Sequence object.\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    public Sequence(SequenceI seq)\r
-    {\r
-        this(seq.getName(), seq.getSequence(), seq.getStart(), seq.getEnd());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param v DOCUMENT ME!\r
-     */\r
-    public void setSequenceFeatures(SequenceFeature [] features)\r
-    {\r
-        sequenceFeatures = features;\r
-    }\r
-\r
-    public void addSequenceFeature(SequenceFeature sf)\r
-    {\r
-      if(sequenceFeatures==null)\r
-      {\r
-        sequenceFeatures = new SequenceFeature[0];\r
-      }\r
-\r
-      for(int i=0; i<sequenceFeatures.length; i++)\r
-      {\r
-        if(sequenceFeatures[i].equals(sf))\r
-        {\r
-          return;\r
-        }\r
-      }\r
-\r
-      SequenceFeature [] temp = new SequenceFeature[sequenceFeatures.length+1];\r
-      System.arraycopy(sequenceFeatures, 0, temp, 0, sequenceFeatures.length);\r
-      temp[sequenceFeatures.length] = sf;\r
-\r
-\r
-      sequenceFeatures = temp;\r
-    }\r
-\r
-    SequenceFeature [] sfarray;\r
-\r
-        public SequenceFeature[] getsfarray()\r
-        {\r
-          return sfarray;\r
-        }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceFeature [] getSequenceFeatures()\r
-    {\r
-        return sequenceFeatures;\r
-    }\r
-\r
-    public void addPDBId(PDBEntry entry)\r
-    {\r
-      if(pdbIds == null)\r
-        pdbIds = new Vector();\r
-\r
-      pdbIds.addElement(entry);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param id DOCUMENT ME!\r
-     */\r
-    public void setPDBId(Vector id)\r
-    {\r
-        pdbIds = id;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getPDBId()\r
-    {\r
-        return pdbIds;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getDisplayId(boolean jvsuffix)\r
-    {\r
-      StringBuffer result = new StringBuffer(name);\r
-      if (jvsuffix)\r
-      {\r
-        result.append("/" + start + "-" + end);\r
-      }\r
-\r
-      return result.toString();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     */\r
-    public void setName(String name)\r
-    {\r
-      this.name = name;\r
-      this.parseId();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getName()\r
-    {\r
-       return this.name;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param start DOCUMENT ME!\r
-     */\r
-    public void setStart(int start)\r
-    {\r
-        this.start = start;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getStart()\r
-    {\r
-        return this.start;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public void setEnd(int end)\r
-    {\r
-        this.end = end;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getEnd()\r
-    {\r
-        return this.end;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getLength()\r
-    {\r
-        return this.sequence.length();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    public void setSequence(String seq)\r
-    {\r
-        this.sequence = seq;\r
-        checkValidRange();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getSequence()\r
-    {\r
-        return this.sequence;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getSequence(int start, int end)\r
-    {\r
-        // JBPNote - left to user to pad the result here (TODO:Decide on this policy)\r
-        if (start >= sequence.length())\r
-        {\r
-            return "";\r
-        }\r
-\r
-        if (end >= sequence.length())\r
-        {\r
-            end = sequence.length();\r
-        }\r
-\r
-        return this.sequence.substring(start, end);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public char getCharAt(int i)\r
-    {\r
-        if (i < sequence.length())\r
-        {\r
-            return sequence.charAt(i);\r
-        }\r
-        else\r
-        {\r
-            return ' ';\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param desc DOCUMENT ME!\r
-     */\r
-    public void setDescription(String desc)\r
-    {\r
-        this.description = desc;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getDescription()\r
-    {\r
-        return this.description;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param pos DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int findIndex(int pos)\r
-    {\r
-        // returns the alignment position for a residue\r
-        int j = start;\r
-        int i = 0;\r
-\r
-        while ((i < sequence.length()) && (j <= end) && (j <= pos))\r
-        {\r
-            if (!jalview.util.Comparison.isGap(sequence.charAt(i)))\r
-            {\r
-                j++;\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        if ((j == end) && (j < pos))\r
-        {\r
-            return end + 1;\r
-        }\r
-        else\r
-        {\r
-            return i;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int findPosition(int i)\r
-    {\r
-        // Returns the sequence position for an alignment position\r
-        int j = 0;\r
-        int pos = start;\r
-\r
-        while ((j < i) && (j < sequence.length()))\r
-        {\r
-            if (!jalview.util.Comparison.isGap((sequence.charAt(j))))\r
-            {\r
-                pos++;\r
-            }\r
-\r
-            j++;\r
-        }\r
-\r
-        return pos;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int[] gapMap()\r
-    {\r
-        // Returns an int array giving the position of each residue in the sequence in the alignment\r
-        String seq = jalview.analysis.AlignSeq.extractGaps("-. ", sequence);\r
-        int[] map = new int[seq.length()];\r
-        int j = 0;\r
-        int p = 0;\r
-\r
-        while (j < sequence.length())\r
-        {\r
-            if (!jalview.util.Comparison.isGap(sequence.charAt(j)))\r
-            {\r
-                map[p++] = j;\r
-            }\r
-\r
-            j++;\r
-        }\r
-\r
-        return map;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void deleteCharAt(int i)\r
-    {\r
-        if (i >= sequence.length())\r
-        {\r
-            return;\r
-        }\r
-\r
-        sequence = sequence.substring(0, i) + sequence.substring(i + 1);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     */\r
-    public void deleteChars(int i, int j)\r
-    {\r
-        if (i >= sequence.length())\r
-        {\r
-            return;\r
-        }\r
-\r
-        if (j >= sequence.length())\r
-        {\r
-            sequence = sequence.substring(0, i);\r
-        }\r
-        else\r
-        {\r
-            sequence = sequence.substring(0, i) + sequence.substring(j);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param c DOCUMENT ME!\r
-     * @param chop DOCUMENT ME!\r
-     */\r
-    public void insertCharAt(int i, char c)\r
-    {\r
-        String tmp = new String(sequence);\r
-\r
-        if (i < sequence.length())\r
-        {\r
-            sequence = tmp.substring(0, i) + String.valueOf(c) +\r
-                tmp.substring(i);\r
-        }\r
-        else\r
-        {\r
-            // JBPNote : padding char at end of sequence. We'll not get away with this when we insert residues, I bet!\r
-            char[] ch = new char[(1 + i) - sequence.length()];\r
-\r
-            for (int j = 0, k = ch.length; j < k; j++)\r
-                ch[j] = c;\r
-\r
-            sequence = tmp + String.valueOf(ch);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     */\r
-    public void setColor(Color c)\r
-    {\r
-        this.color = c;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color getColor()\r
-    {\r
-        return color;\r
-    }\r
-\r
-    public String getVamsasId()\r
-    {\r
-      return vamsasId;\r
-    }\r
-\r
-    public void setVamsasId(String id)\r
-    {\r
-      vamsasId = id;\r
-    }\r
-\r
-    public void setDBRef(Vector dbref)\r
-    {\r
-      dbrefs = dbref;\r
-    }\r
-    public Vector getDBRef()\r
-    {\r
-      return dbrefs;\r
-    }\r
-\r
-    public void addDBRef(DBRefEntry entry)\r
-    {\r
-      if(dbrefs == null)\r
-        dbrefs = new Vector();\r
-\r
-      dbrefs.addElement(entry);\r
-    }\r
-\r
-    public void setDatasetSequence(SequenceI seq)\r
-    {\r
-      datasetSequence = seq;\r
-    }\r
-\r
-    public SequenceI getDatasetSequence()\r
-    {\r
-      return datasetSequence;\r
-    }\r
-\r
-    public AlignmentAnnotation [] getAnnotation()\r
-    {\r
-      if(annotation==null)\r
-        return null;\r
-\r
-      AlignmentAnnotation [] ret = new AlignmentAnnotation[annotation.size()];\r
-      for(int r = 0; r<ret.length; r++)\r
-        ret[r] = (AlignmentAnnotation)annotation.elementAt(r);\r
-\r
-      return ret;\r
-    }\r
-\r
-    public void addAlignmentAnnotation(AlignmentAnnotation annotation)\r
-    {\r
-      if(this.annotation==null)\r
-        this.annotation = new Vector();\r
-\r
-      this.annotation.addElement( annotation );\r
-    }\r
-\r
-    public SequenceGroup getHiddenSequences()\r
-    {\r
-      return hiddenSequences;\r
-    }\r
-\r
-    public void addHiddenSequence(SequenceI seq)\r
-    {\r
-      if(hiddenSequences==null)\r
-      {\r
-        hiddenSequences = new SequenceGroup();\r
-      }\r
-      hiddenSequences.addSequence(seq, false);\r
-    }\r
-\r
-    public void showHiddenSequence(SequenceI seq)\r
-    {\r
-      hiddenSequences.deleteSequence(seq, false);\r
-      if (hiddenSequences.getSize() < 1)\r
-      {\r
-        hiddenSequences = null;\r
-      }\r
-\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.datamodel;
+
+import java.awt.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Sequence implements SequenceI
+{
+    SequenceI datasetSequence;
+    String name;
+    private String sequence;
+    String description;
+    int start;
+    int end;
+    Color color = Color.white;
+    Vector pdbIds;
+    String vamsasId;
+    DBRefEntry [] dbrefs;
+
+    /** This annotation is displayed below the alignment but the
+     * positions are tied to the residues of this sequence */
+    Vector annotation;
+
+    /** DOCUMENT ME!! */
+    public SequenceFeature [] sequenceFeatures;
+
+    /** This array holds hidden sequences
+     * of which this sequence is the representitive member of a group
+     */
+    SequenceGroup hiddenSequences;
+
+    /**
+     * Creates a new Sequence object.
+     *
+     * @param name DOCUMENT ME!
+     * @param sequence DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     */
+    public Sequence(String name, String sequence, int start, int end)
+    {
+      this.name = name;
+      this.sequence = sequence;
+      this.start = start;
+      this.end = end;
+
+      parseId();
+
+      checkValidRange();
+    }
+
+    com.stevesoft.pat.Regex limitrx = new com.stevesoft.pat.Regex(
+                        "[/][0-9]{1,}[-][0-9]{1,}$");
+    com.stevesoft.pat.Regex endrx = new com.stevesoft.pat.Regex(
+                        "[0-9]{1,}$");
+
+    void parseId()
+    {
+        // Does sequence have the /start-end signiature?
+         if(limitrx.search(name))
+         {
+            name = limitrx.left();
+            endrx.search(limitrx.stringMatched());
+            setStart( Integer.parseInt( limitrx.stringMatched().substring(1,endrx.matchedFrom()-1 )));
+            setEnd(   Integer.parseInt( endrx.stringMatched() ));
+         }
+    }
+
+    void checkValidRange()
+    {
+      if (end < 1)
+      {
+        int endRes = 0;
+        char ch;
+        for (int j = 0; j < sequence.length(); j++)
+        {
+          ch = sequence.charAt(j);
+          if (!jalview.util.Comparison.isGap( (ch)))
+          {
+            endRes++;
+          }
+        }
+        if (endRes > 0)
+        {
+          endRes += start - 1;
+        }
+
+        this.end = endRes;
+      }
+
+    }
+
+    /**
+     * Creates a new Sequence object.
+     *
+     * @param name DOCUMENT ME!
+     * @param sequence DOCUMENT ME!
+     */
+    public Sequence(String name, String sequence)
+    {
+        this(name, sequence, 1, -1);
+    }
+
+    /**
+     * Creates a new Sequence object.
+     *
+     * @param seq DOCUMENT ME!
+     */
+    public Sequence(SequenceI seq)
+    {
+        this(seq.getName(), seq.getSequence(), seq.getStart(), seq.getEnd());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param v DOCUMENT ME!
+     */
+    public void setSequenceFeatures(SequenceFeature [] features)
+    {
+        sequenceFeatures = features;
+    }
+
+    public synchronized void addSequenceFeature(SequenceFeature sf)
+    {
+      if(sequenceFeatures==null)
+      {
+        sequenceFeatures = new SequenceFeature[0];
+      }
+
+      for(int i=0; i<sequenceFeatures.length; i++)
+      {
+        if(sequenceFeatures[i].equals(sf))
+        {
+          return;
+        }
+      }
+
+      SequenceFeature [] temp = new SequenceFeature[sequenceFeatures.length+1];
+      System.arraycopy(sequenceFeatures, 0, temp, 0, sequenceFeatures.length);
+      temp[sequenceFeatures.length] = sf;
+
+      sequenceFeatures = temp;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceFeature [] getSequenceFeatures()
+    {
+        return sequenceFeatures;
+    }
+
+    public void addPDBId(PDBEntry entry)
+    {
+      if(pdbIds == null)
+        pdbIds = new Vector();
+
+      pdbIds.addElement(entry);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param id DOCUMENT ME!
+     */
+    public void setPDBId(Vector id)
+    {
+        pdbIds = id;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getPDBId()
+    {
+        return pdbIds;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getDisplayId(boolean jvsuffix)
+    {
+      StringBuffer result = new StringBuffer(name);
+      if (jvsuffix)
+      {
+        result.append("/" + start + "-" + end);
+      }
+
+      return result.toString();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     */
+    public void setName(String name)
+    {
+      this.name = name;
+      this.parseId();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getName()
+    {
+       return this.name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param start DOCUMENT ME!
+     */
+    public void setStart(int start)
+    {
+        this.start = start;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getStart()
+    {
+        return this.start;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param end DOCUMENT ME!
+     */
+    public void setEnd(int end)
+    {
+        this.end = end;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getEnd()
+    {
+        return this.end;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getLength()
+    {
+        return this.sequence.length();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     */
+    public void setSequence(String seq)
+    {
+        this.sequence = seq;
+        checkValidRange();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getSequence()
+    {
+        return this.sequence;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getSequence(int start, int end)
+    {
+        // JBPNote - left to user to pad the result here (TODO:Decide on this policy)
+        if (start >= sequence.length())
+        {
+            return "";
+        }
+
+        if (end >= sequence.length())
+        {
+            end = sequence.length();
+        }
+
+        return this.sequence.substring(start, end);
+    }
+    /**
+     * make a new Sequence object from start to end (including gaps) over this seqeunce
+     * @param start int
+     * @param end int
+     * @return SequenceI
+     */
+    public SequenceI getSubSequence(int start, int end) {
+      if (start<0)
+        start = 0;
+      String seq = getSequence(start, end);
+      if (seq=="")
+        return null;
+      int nstart = findPosition(start);
+      int nend=findPosition(end)-1;
+      // JBPNote - this is an incomplete copy.
+      SequenceI nseq = new Sequence(this.getName(), seq, nstart, nend);
+      nseq.setDatasetSequence(getDatasetSequence());
+      return nseq;
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public char getCharAt(int i)
+    {
+        if (i < sequence.length())
+        {
+            return sequence.charAt(i);
+        }
+        else
+        {
+            return ' ';
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param desc DOCUMENT ME!
+     */
+    public void setDescription(String desc)
+    {
+        this.description = desc;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getDescription()
+    {
+        return this.description;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pos DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int findIndex(int pos)
+    {
+        // returns the alignment position for a residue
+        int j = start;
+        int i = 0;
+
+        while ((i < sequence.length()) && (j <= end) && (j <= pos))
+        {
+            if (!jalview.util.Comparison.isGap(sequence.charAt(i)))
+            {
+                j++;
+            }
+
+            i++;
+        }
+
+        if ((j == end) && (j < pos))
+        {
+            return end + 1;
+        }
+        else
+        {
+            return i;
+        }
+    }
+
+    /**
+     * Returns the sequence position for an alignment position
+     *
+     * @param i column index in alignment (from 1)
+     *
+     * @return residue number for residue (left of and) nearest ith column
+     */
+    public int findPosition(int i)
+    {
+        int j = 0;
+        int pos = start;
+        int seqlen=sequence.length();
+        while ((j < i) && (j < seqlen))
+        {
+            if (!jalview.util.Comparison.isGap((sequence.charAt(j))))
+            {
+                pos++;
+            }
+
+            j++;
+        }
+
+        return pos;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int[] gapMap()
+    {
+        // Returns an int array giving the position of each residue in the sequence in the alignment
+        String seq = jalview.analysis.AlignSeq.extractGaps(jalview.util.Comparison.GapChars, sequence);
+        int[] map = new int[seq.length()];
+        int j = 0;
+        int p = 0;
+
+        while (j < sequence.length())
+        {
+            if (!jalview.util.Comparison.isGap(sequence.charAt(j)))
+            {
+                map[p++] = j;
+            }
+
+            j++;
+        }
+
+        return map;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void deleteCharAt(int i)
+    {
+        if (i >= sequence.length())
+        {
+            return;
+        }
+
+        sequence = sequence.substring(0, i) + sequence.substring(i + 1);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     */
+    public void deleteChars(int i, int j)
+    {
+        if (i >= sequence.length())
+        {
+            return;
+        }
+
+        if (j >= sequence.length())
+        {
+            sequence = sequence.substring(0, i);
+        }
+        else
+        {
+            sequence = sequence.substring(0, i) + sequence.substring(j);
+        }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param c DOCUMENT ME!
+     * @param chop DOCUMENT ME!
+     */
+    public void insertCharAt(int i, char c)
+    {
+        String tmp = new String(sequence);
+
+        if (i < sequence.length())
+        {
+            sequence = tmp.substring(0, i) + String.valueOf(c) +
+                tmp.substring(i);
+        }
+        else
+        {
+            // JBPNote : padding char at end of sequence. We'll not get away with this when we insert residues, I bet!
+            char[] ch = new char[(1 + i) - sequence.length()];
+
+            for (int j = 0, k = ch.length; j < k; j++)
+                ch[j] = c;
+
+            sequence = tmp + String.valueOf(ch);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     */
+    public void setColor(Color c)
+    {
+        this.color = c;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color getColor()
+    {
+        return color;
+    }
+
+    public String getVamsasId()
+    {
+      return vamsasId;
+    }
+
+    public void setVamsasId(String id)
+    {
+      vamsasId = id;
+    }
+
+    public void setDBRef(DBRefEntry [] dbref)
+    {
+      dbrefs = dbref;
+    }
+
+    public DBRefEntry [] getDBRef()
+    {
+      return dbrefs;
+    }
+
+    public void addDBRef(DBRefEntry entry)
+    {
+      if(dbrefs == null)
+        dbrefs = new DBRefEntry[0];
+
+      DBRefEntry [] temp = new DBRefEntry[dbrefs.length+1];
+      System.arraycopy(dbrefs, 0, temp, 0, dbrefs.length);
+
+      temp[temp.length-1] = entry;
+
+      dbrefs = temp;
+    }
+
+    public void setDatasetSequence(SequenceI seq)
+    {
+      datasetSequence = seq;
+    }
+
+    public SequenceI getDatasetSequence()
+    {
+      return datasetSequence;
+    }
+
+    public AlignmentAnnotation [] getAnnotation()
+    {
+      if(annotation==null)
+        return null;
+
+      AlignmentAnnotation [] ret = new AlignmentAnnotation[annotation.size()];
+      for(int r = 0; r<ret.length; r++)
+        ret[r] = (AlignmentAnnotation)annotation.elementAt(r);
+
+      return ret;
+    }
+
+    public void addAlignmentAnnotation(AlignmentAnnotation annotation)
+    {
+      if(this.annotation==null)
+        this.annotation = new Vector();
+
+      this.annotation.addElement( annotation );
+    }
+
+    public SequenceGroup getHiddenSequences()
+    {
+      return hiddenSequences;
+    }
+
+    public void addHiddenSequence(SequenceI seq)
+    {
+      if(hiddenSequences==null)
+      {
+        hiddenSequences = new SequenceGroup();
+      }
+      hiddenSequences.addSequence(seq, false);
+    }
+
+    public void showHiddenSequence(SequenceI seq)
+    {
+      hiddenSequences.deleteSequence(seq, false);
+      if (hiddenSequences.getSize(false) < 1)
+      {
+        hiddenSequences = null;
+      }
+    }
+
+    public void changeCase(boolean toUpper, int start, int end)
+    {
+      StringBuffer newSeq = new StringBuffer();
+
+      if(end>sequence.length())
+        end = sequence.length();
+
+      if (start > 0)
+      {
+        newSeq.append(sequence.substring(0, start));
+      }
+
+      if (toUpper)
+        newSeq.append(sequence.substring(start, end).toUpperCase());
+      else
+        newSeq.append(sequence.substring(start, end).toLowerCase());
+
+      if (end < sequence.length())
+        newSeq.append(sequence.substring(end));
+
+      sequence = newSeq.toString();
+    }
+
+    public void toggleCase(int start, int end)
+    {
+      StringBuffer newSeq = new StringBuffer();
+
+     if(end>sequence.length())
+       end = sequence.length();
+
+     if (start > 0)
+     {
+       newSeq.append(sequence.substring(0, start));
+     }
+
+     char nextChar;
+     for(int c=start; c<end; c++)
+     {
+       nextChar = sequence.charAt(c);
+       if(Character.isLetter(nextChar))
+       {
+         if(Character.isUpperCase(nextChar))
+           nextChar = Character.toLowerCase(nextChar);
+         else
+           nextChar = Character.toUpperCase(nextChar);
+       }
+
+
+       newSeq.append(nextChar);
+     }
+
+     if (end < sequence.length())
+       newSeq.append(sequence.substring(end));
+
+     sequence = newSeq.toString();
+    }
+
+  public SequenceI getSubSequence(int start)
+  {
+    int e=getLength();
+    if (start>=e)
+      return null;
+    return getSubSequence(start, getLength());
+  }
+
+  public int removeGaps() {
+    if (sequence!=null)
+      return removeGaps(0, getLength());
+    return 0;
+  }
+
+  public int removeGaps(int start, int end) {
+    int jSize = getLength();
+    int oSize=jSize;
+    if (jSize<=start)
+      return 0;
+    if (end>jSize)
+      end = jSize;
+
+    // Removing a range is much quicker than removing gaps
+    // one by one for long sequences
+    int j = start;
+    int rangeStart=-1, rangeEnd=-1;
+
+    do
+    {
+      if (jalview.util.Comparison.isGap(getCharAt(j)))
+      {
+        if(rangeStart==-1)
+         {
+           rangeStart = j;
+           rangeEnd = j+1;
+         }
+         else
+         {
+           rangeEnd++;
+         }
+         j++;
+      }
+      else
+      {
+        if(rangeStart>-1)
+        {
+          deleteChars(rangeStart, rangeEnd);
+          j-=rangeEnd-rangeStart;
+          jSize-=rangeEnd-rangeStart;
+          rangeStart = -1;
+          rangeEnd = -1;
+        }
+        else
+          j++;
+      }
+    }
+    while (j < end && j < jSize);
+    if(rangeStart>-1)
+    {
+     deleteChars(rangeStart, rangeEnd);
+     jSize-=rangeEnd-rangeStart;
+    }
+    return oSize-jSize; // number of deleted characters.
+  }
+
+}
index f8444a0..7d644e8 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SequenceFeature\r
-{\r
-    public int position;\r
-    public int begin;\r
-    public int end;\r
-    public String type;\r
-    public String description;\r
-    public String status;\r
-\r
-    // Feature group can be set from a features file\r
-    // as a group of features between STARTGROUP and ENDGROUP markers\r
-    public String featureGroup;\r
-\r
-    public SequenceFeature()\r
-    {}\r
-\r
-    public SequenceFeature(String type,\r
-                           String desc,\r
-                           String status,\r
-                           int begin, int end,\r
-                           String featureGroup)\r
-    {\r
-      this.type = type;\r
-      this.description = desc;\r
-      this.status = status;\r
-      this.position = begin;\r
-      this.begin = begin;\r
-      this.end = end;\r
-      this.featureGroup = featureGroup;\r
-    }\r
-\r
-    public boolean equals(SequenceFeature sf)\r
-    {\r
-      if(begin != sf.begin\r
-      || end != sf.end)\r
-     return false;\r
-\r
-\r
-      if(!(type+description+status).equals\r
-         (sf.type+sf.description+sf.status))\r
-        return false;\r
-\r
-      return true;\r
-    }\r
-\r
-\r
-    public int getPosition()\r
-    {\r
-      return position;\r
-    }\r
-\r
-    public void setPosition(int pos)\r
-    {\r
-      position = pos;\r
-      begin = pos;\r
-      end = pos;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getBegin()\r
-    {\r
-        return begin;\r
-    }\r
-\r
-    public void setBegin(int start)\r
-    {\r
-      this.begin = start;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getEnd()\r
-    {\r
-        return end;\r
-    }\r
-\r
-    public void setEnd(int end)\r
-    {\r
-      this.end = end;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getType()\r
-    {\r
-        return type;\r
-    }\r
-\r
-    public void setType(String type)\r
-    {\r
-      this.type = type;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getDescription()\r
-    {\r
-        return description;\r
-    }\r
-\r
-    public void setDescription(String desc)\r
-    {\r
-      description = desc;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getStatus()\r
-    {\r
-        return status;\r
-    }\r
-\r
-    public void setStatus(String status)\r
-    {\r
-      this.status = status;\r
-    }\r
-\r
-    public String getFeatureGroup()\r
-    {\r
-      return featureGroup;\r
-    }\r
-\r
-    public void setFeatureGroup(String featureGroup)\r
-    {\r
-      this.featureGroup = featureGroup;\r
-    }\r
-\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import java.util.Hashtable;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SequenceFeature
+{
+    public int begin;
+    public int end;
+    public float score;
+    public String type;
+    public String description;
+    public Hashtable otherDetails;
+    public java.util.Vector links;
+
+    // Feature group can be set from a features file
+    // as a group of features between STARTGROUP and ENDGROUP markers
+    public String featureGroup;
+
+    public SequenceFeature()
+    {}
+
+    public SequenceFeature(String type,
+                           String desc,
+                           String status,
+                           int begin, int end,
+                           String featureGroup)
+    {
+      this.type = type;
+      this.description = desc;
+      setValue("status", status);
+      this.begin = begin;
+      this.end = end;
+      this.featureGroup = featureGroup;
+    }
+
+    public SequenceFeature(String type,
+                           String desc,
+                           int begin, int end,
+                           float score,
+                           String featureGroup)
+    {
+      this.type = type;
+      this.description = desc;
+      this.begin = begin;
+      this.end = end;
+      this.score = score;
+      this.featureGroup = featureGroup;
+    }
+
+    public boolean equals(SequenceFeature sf)
+    {
+      if (begin != sf.begin
+          || end != sf.end
+          || score != sf.score)
+        return false;
+
+      if(!(type+description+featureGroup).equals
+         (sf.type+sf.description+sf.featureGroup))
+        return false;
+
+      return true;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getBegin()
+    {
+        return begin;
+    }
+
+    public void setBegin(int start)
+    {
+      this.begin = start;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getEnd()
+    {
+        return end;
+    }
+
+    public void setEnd(int end)
+    {
+      this.end = end;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getType()
+    {
+        return type;
+    }
+
+    public void setType(String type)
+    {
+      this.type = type;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public void setDescription(String desc)
+    {
+      description = desc;
+    }
+
+    public String getFeatureGroup()
+    {
+      return featureGroup;
+    }
+
+    public void setFeatureGroup(String featureGroup)
+    {
+      this.featureGroup = featureGroup;
+    }
+
+    public void addLink(String labelLink)
+    {
+      if(links==null)
+        links = new java.util.Vector();
+
+      links.insertElementAt(labelLink,0);
+    }
+
+    public float getScore()
+    {
+      return score;
+    }
+
+    public void setScore(float value)
+    {
+      score = value;
+    }
+
+    /**
+     * Used for getting values which are not in the
+     * basic set. eg STRAND, FRAME for GFF file
+     * @param key String
+     */
+    public Object getValue(String key)
+    {
+      if(otherDetails==null)
+        return null;
+      else
+        return otherDetails.get(key);
+    }
+
+    /**
+     * Used for setting values which are not in the
+     * basic set. eg STRAND, FRAME for GFF file
+     * @param key   eg STRAND
+     * @param value eg +
+     */
+    public void setValue(String key, Object value)
+    {
+      if(value!=null)
+      {
+        if (otherDetails == null)
+          otherDetails = new Hashtable();
+
+        otherDetails.put(key, value);
+      }
+    }
+
+
+    /*
+     * The following methods are added to maintain
+     * the castor Uniprot mapping file for the moment.
+     */
+    public void setStatus(String status)
+    {
+      setValue("status", status);
+    }
+
+    public String getStatus()
+    {
+      if (otherDetails != null)
+        return otherDetails.get("status").toString();
+      else
+        return null;
+    }
+
+    public void setPosition(int pos)
+    {
+      begin = pos;
+      end = pos;
+    }
+
+    public int getPosition()
+    {
+      return begin;
+    }
+
+}
index 6de42b9..7bb8ce0 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SequenceGroup\r
-{\r
-    String groupName;\r
-    Conservation conserve;\r
-    Vector aaFrequency;\r
-    boolean displayBoxes;\r
-    boolean displayText;\r
-    boolean colourText;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public Vector sequences = new Vector();\r
-    int width = -1;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public ColourSchemeI cs;\r
-    int startRes = 0;\r
-    int endRes = 0;\r
-    Color outlineColour = Color.black;\r
-\r
-    /**\r
-     * Creates a new SequenceGroup object.\r
-     */\r
-    public SequenceGroup()\r
-    {\r
-        groupName = "Group";\r
-        this.displayBoxes = true;\r
-        this.displayText = true;\r
-        this.colourText = false;\r
-        cs = null;\r
-    }\r
-\r
-    /**\r
-     * Creates a new SequenceGroup object.\r
-     *\r
-     * @param sequences DOCUMENT ME!\r
-     * @param groupName DOCUMENT ME!\r
-     * @param scheme DOCUMENT ME!\r
-     * @param displayBoxes DOCUMENT ME!\r
-     * @param displayText DOCUMENT ME!\r
-     * @param colourText DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public SequenceGroup(Vector sequences, String groupName,\r
-        ColourSchemeI scheme, boolean displayBoxes, boolean displayText,\r
-        boolean colourText, int start, int end)\r
-    {\r
-        this.sequences = sequences;\r
-        this.groupName = groupName;\r
-        this.displayBoxes = displayBoxes;\r
-        this.displayText = displayText;\r
-        this.colourText = colourText;\r
-        this.cs = scheme;\r
-        startRes = start;\r
-        endRes = end;\r
-        recalcConservation();\r
-    }\r
-\r
-    /**\r
-     * Creates a new SequenceGroup object.\r
-     *\r
-     * @param groupName DOCUMENT ME!\r
-     * @param scheme DOCUMENT ME!\r
-     * @param displayBoxes DOCUMENT ME!\r
-     * @param displayText DOCUMENT ME!\r
-     * @param colourText DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public SequenceGroup(String groupName, ColourSchemeI scheme,\r
-        boolean displayBoxes, boolean displayText, boolean colourText,\r
-        int start, int end)\r
-    {\r
-        this.groupName = groupName;\r
-        this.displayBoxes = displayBoxes;\r
-        this.displayText = displayText;\r
-        this.colourText = colourText;\r
-        this.cs = scheme;\r
-        startRes = start;\r
-        endRes = end;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param col DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean adjustForRemoveLeft(int col)\r
-    {\r
-        // return value is true if the group still exists\r
-        if (startRes >= col)\r
-        {\r
-            startRes = startRes - col;\r
-        }\r
-\r
-        if (endRes >= col)\r
-        {\r
-            endRes = endRes - col;\r
-\r
-            if (startRes > endRes)\r
-            {\r
-                startRes = 0;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            // must delete this group!!\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param col DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean adjustForRemoveRight(int col)\r
-    {\r
-        if (startRes > col)\r
-        {\r
-            // delete this group\r
-            return false;\r
-        }\r
-\r
-        if (endRes >= col)\r
-        {\r
-            endRes = col;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getName()\r
-    {\r
-        return groupName;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     */\r
-    public void setName(String name)\r
-    {\r
-        groupName = name;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Conservation getConservation()\r
-    {\r
-        return conserve;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     */\r
-    public void setConservation(Conservation c)\r
-    {\r
-        conserve = c;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param recalc DOCUMENT ME!\r
-     */\r
-    public void addSequence(SequenceI s, boolean recalc)\r
-    {\r
-        if (!sequences.contains(s))\r
-        {\r
-            sequences.addElement(s);\r
-        }\r
-\r
-        if (recalc)\r
-        {\r
-            recalcConservation();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void recalcConservation()\r
-    {\r
-        if(cs == null)\r
-          return;\r
-\r
-        cs.setConsensus(AAFrequency.calculate(sequences, 0, getWidth()));\r
-\r
-\r
-        if (cs instanceof ClustalxColourScheme)\r
-        {\r
-            ((ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());\r
-        }\r
-\r
-\r
-        if (cs.conservationApplied())\r
-        {\r
-            Conservation c = new Conservation(groupName,\r
-                    ResidueProperties.propHash, 3, sequences, 0, getWidth());\r
-            c.calculate();\r
-            c.verdict(false, 25);\r
-\r
-\r
-            cs.setConservation(c);\r
-\r
-            if (cs instanceof ClustalxColourScheme)\r
-            {\r
-                ((ClustalxColourScheme) cs).resetClustalX(sequences,\r
-                    getWidth());\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param recalc DOCUMENT ME!\r
-     */\r
-    public void addOrRemove(SequenceI s, boolean recalc)\r
-    {\r
-        if (sequences.contains(s))\r
-        {\r
-            deleteSequence(s, recalc);\r
-        }\r
-        else\r
-        {\r
-            addSequence(s, recalc);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param recalc DOCUMENT ME!\r
-     */\r
-    public void deleteSequence(SequenceI s, boolean recalc)\r
-    {\r
-        sequences.removeElement(s);\r
-\r
-        if (recalc)\r
-        {\r
-            recalcConservation();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getStartRes()\r
-    {\r
-        return startRes;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getEndRes()\r
-    {\r
-        return endRes;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void setStartRes(int i)\r
-    {\r
-        startRes = i;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void setEndRes(int i)\r
-    {\r
-        endRes = i;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getSize()\r
-    {\r
-        return sequences.size();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceI getSequenceAt(int i)\r
-    {\r
-        return (SequenceI) sequences.elementAt(i);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setColourText(boolean state)\r
-    {\r
-        colourText = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getColourText()\r
-    {\r
-        return colourText;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setDisplayText(boolean state)\r
-    {\r
-        displayText = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getDisplayText()\r
-    {\r
-        return displayText;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setDisplayBoxes(boolean state)\r
-    {\r
-        displayBoxes = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getDisplayBoxes()\r
-    {\r
-        return displayBoxes;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getWidth()\r
-    {\r
-        // MC This needs to get reset when characters are inserted and deleted\r
-        if (sequences.size() > 0)\r
-        {\r
-            width = ((SequenceI) sequences.elementAt(0)).getLength();\r
-        }\r
-\r
-        for (int i = 1; i < sequences.size(); i++)\r
-        {\r
-            SequenceI seq = (SequenceI) sequences.elementAt(i);\r
-\r
-            if (seq.getLength() > width)\r
-            {\r
-                width = seq.getLength();\r
-            }\r
-        }\r
-\r
-        return width;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     */\r
-    public void setOutlineColour(Color c)\r
-    {\r
-        outlineColour = c;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color getOutlineColour()\r
-    {\r
-        return outlineColour;\r
-    }\r
-\r
-    /**\r
-     *\r
-     * returns the sequences in the group ordered by the ordering given by al\r
-     *\r
-     * @param al Alignment\r
-     * @return SequenceI[]\r
-     */\r
-    public SequenceI[] getSequencesInOrder(AlignmentI al)\r
-    {\r
-        int sz = sequences.size();\r
-        java.util.Hashtable orderedSeqs = new java.util.Hashtable();\r
-        SequenceI[] seqs = new SequenceI[sz];\r
-\r
-        for (int i = 0; i < sz; i++)\r
-        {\r
-            SequenceI seq = (SequenceI) sequences.elementAt(i);\r
-            int index = al.findIndex(seq);\r
-            orderedSeqs.put(index + "", seq);\r
-        }\r
-\r
-        int index = 0;\r
-\r
-        for (int i = 0; i < al.getHeight(); i++)\r
-        {\r
-            if (orderedSeqs.containsKey(i + ""))\r
-            {\r
-                seqs[index++] = (SequenceI) orderedSeqs.get(i + "");\r
-            }\r
-        }\r
-\r
-        return seqs;\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import jalview.analysis.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SequenceGroup
+{
+    String groupName;
+    Conservation conserve;
+    Vector aaFrequency;
+    boolean displayBoxes;
+    boolean displayText;
+    boolean colourText;
+    private Vector sequences = new Vector();
+    int width = -1;
+
+    /** DOCUMENT ME!! */
+    public ColourSchemeI cs;
+    int startRes = 0;
+    int endRes = 0;
+    Color outlineColour = Color.black;
+
+    /**
+     * Creates a new SequenceGroup object.
+     */
+    public SequenceGroup()
+    {
+        groupName = "Group";
+        this.displayBoxes = true;
+        this.displayText = true;
+        this.colourText = false;
+        cs = null;
+    }
+
+    /**
+     * Creates a new SequenceGroup object.
+     *
+     * @param sequences DOCUMENT ME!
+     * @param groupName DOCUMENT ME!
+     * @param scheme DOCUMENT ME!
+     * @param displayBoxes DOCUMENT ME!
+     * @param displayText DOCUMENT ME!
+     * @param colourText DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     */
+    public SequenceGroup(Vector sequences, String groupName,
+        ColourSchemeI scheme, boolean displayBoxes, boolean displayText,
+        boolean colourText, int start, int end)
+    {
+        this.sequences = sequences;
+        this.groupName = groupName;
+        this.displayBoxes = displayBoxes;
+        this.displayText = displayText;
+        this.colourText = colourText;
+        this.cs = scheme;
+        startRes = start;
+        endRes = end;
+        recalcConservation();
+    }
+
+    /**
+     * Creates a new SequenceGroup object.
+     *
+     * @param groupName DOCUMENT ME!
+     * @param scheme DOCUMENT ME!
+     * @param displayBoxes DOCUMENT ME!
+     * @param displayText DOCUMENT ME!
+     * @param colourText DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     */
+    public SequenceGroup(String groupName, ColourSchemeI scheme,
+        boolean displayBoxes, boolean displayText, boolean colourText,
+        int start, int end)
+    {
+        this.groupName = groupName;
+        this.displayBoxes = displayBoxes;
+        this.displayText = displayText;
+        this.colourText = colourText;
+        this.cs = scheme;
+        startRes = start;
+        endRes = end;
+    }
+
+    public SequenceI [] getSelectionAsNewSequences(AlignmentI align)
+    {
+      int iSize = sequences.size();
+      SequenceI [] seqs = new SequenceI[iSize];
+      SequenceI [] inorder = getSequencesInOrder(align);
+
+    char ch;
+    int sres, eres;
+
+    for (int i = 0; i < iSize; i++)
+    {
+      SequenceI seq = inorder[i];
+
+      //FIND START RES
+      //Returns residue following index if gap
+      sres = seq.findPosition(startRes);
+
+      //FIND END RES
+      //Need to find the residue preceeding index if gap
+      eres = 0;
+
+      for (int j = 0; j < endRes + 1 && j < seq.getLength(); j++)
+      {
+        ch = seq.getCharAt(j);
+        if (!jalview.util.Comparison.isGap( (ch)))
+        {
+          eres++;
+        }
+      }
+
+      if (eres > 0)
+      {
+        eres += seq.getStart() - 1;
+      }
+
+      seqs[i] = new Sequence(seq.getName(),
+                             seq.getSequence(startRes, endRes + 1),
+                             sres,
+                             eres);
+      seqs[i].setDescription(seq.getDescription());
+      seqs[i].setDBRef(seq.getDBRef());
+      seqs[i].setSequenceFeatures(seq.getSequenceFeatures());
+      if (seq.getDatasetSequence() != null)
+        seqs[i].setDatasetSequence(seq.getDatasetSequence());
+
+      if(seq.getAnnotation()!=null)
+      {
+        for(int a=0; a<seq.getAnnotation().length; a++)
+          seqs[i].addAlignmentAnnotation(seq.getAnnotation()[a]);
+      }
+    }
+
+    return seqs;
+
+    }
+
+    public Vector getSequences(boolean includeHidden)
+    {
+      if(!includeHidden)
+        return sequences;
+      else
+      {
+        Vector allSequences = new Vector();
+        SequenceI seq;
+        for (int i = 0; i < sequences.size(); i++)
+        {
+          seq = (SequenceI) sequences.elementAt(i);
+          allSequences.addElement(seq);
+          if (seq.getHiddenSequences() != null)
+          {
+            for (int h = 0; h < seq.getHiddenSequences().getSize(false); h++)
+            {
+              allSequences.addElement(
+                  seq.getHiddenSequences().getSequenceAt(h)
+                  );
+            }
+          }
+        }
+
+        return allSequences;
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param col DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean adjustForRemoveLeft(int col)
+    {
+        // return value is true if the group still exists
+        if (startRes >= col)
+        {
+            startRes = startRes - col;
+        }
+
+        if (endRes >= col)
+        {
+            endRes = endRes - col;
+
+            if (startRes > endRes)
+            {
+                startRes = 0;
+            }
+        }
+        else
+        {
+            // must delete this group!!
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param col DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean adjustForRemoveRight(int col)
+    {
+        if (startRes > col)
+        {
+            // delete this group
+            return false;
+        }
+
+        if (endRes >= col)
+        {
+            endRes = col;
+        }
+
+        return true;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getName()
+    {
+        return groupName;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     */
+    public void setName(String name)
+    {
+        groupName = name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Conservation getConservation()
+    {
+        return conserve;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     */
+    public void setConservation(Conservation c)
+    {
+        conserve = c;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param recalc DOCUMENT ME!
+     */
+    public void addSequence(SequenceI s, boolean recalc)
+    {
+        if (!sequences.contains(s))
+        {
+            sequences.addElement(s);
+        }
+
+        if (recalc)
+        {
+            recalcConservation();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void recalcConservation()
+    {
+        if(cs == null)
+          return;
+
+        try
+        {
+          cs.setConsensus(AAFrequency.calculate(sequences, 0, getWidth()));
+
+          if (cs instanceof ClustalxColourScheme)
+          {
+            ( (ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());
+          }
+
+          if (cs.conservationApplied())
+          {
+            Conservation c = new Conservation(groupName,
+                                              ResidueProperties.propHash, 3, sequences,
+                                              0, getWidth());
+            c.calculate();
+            c.verdict(false, 25);
+
+            cs.setConservation(c);
+
+            if (cs instanceof ClustalxColourScheme)
+            {
+              ( (ClustalxColourScheme) cs).resetClustalX(sequences,
+                                                         getWidth());
+            }
+          }
+        }
+        catch (java.lang.OutOfMemoryError err)
+        {
+          System.out.println("Out of memory loading groups: " + err);
+        }
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param recalc DOCUMENT ME!
+     */
+    public void addOrRemove(SequenceI s, boolean recalc)
+    {
+        if (sequences.contains(s))
+        {
+            deleteSequence(s, recalc);
+        }
+        else
+        {
+            addSequence(s, recalc);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param recalc DOCUMENT ME!
+     */
+    public void deleteSequence(SequenceI s, boolean recalc)
+    {
+        sequences.removeElement(s);
+
+        if (recalc)
+        {
+            recalcConservation();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getStartRes()
+    {
+        return startRes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getEndRes()
+    {
+        return endRes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void setStartRes(int i)
+    {
+        startRes = i;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void setEndRes(int i)
+    {
+        endRes = i;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getSize(boolean includeHidden)
+    {
+      if(!includeHidden)
+        return sequences.size();
+      else
+      {
+        int total = sequences.size();
+        SequenceI seq;
+        for (int i = 0; i < sequences.size(); i++)
+        {
+          seq = (SequenceI) sequences.elementAt(i);
+          if (seq.getHiddenSequences() != null)
+          {
+            total += seq.getHiddenSequences().getSize(false);
+          }
+        }
+        return total;
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceI getSequenceAt(int i)
+    {
+        return (SequenceI) sequences.elementAt(i);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param state DOCUMENT ME!
+     */
+    public void setColourText(boolean state)
+    {
+        colourText = state;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean getColourText()
+    {
+        return colourText;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param state DOCUMENT ME!
+     */
+    public void setDisplayText(boolean state)
+    {
+        displayText = state;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean getDisplayText()
+    {
+        return displayText;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param state DOCUMENT ME!
+     */
+    public void setDisplayBoxes(boolean state)
+    {
+        displayBoxes = state;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean getDisplayBoxes()
+    {
+        return displayBoxes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getWidth()
+    {
+        // MC This needs to get reset when characters are inserted and deleted
+        if (sequences.size() > 0)
+        {
+            width = ((SequenceI) sequences.elementAt(0)).getLength();
+        }
+
+        for (int i = 1; i < sequences.size(); i++)
+        {
+            SequenceI seq = (SequenceI) sequences.elementAt(i);
+
+            if (seq.getLength() > width)
+            {
+                width = seq.getLength();
+            }
+        }
+
+        return width;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     */
+    public void setOutlineColour(Color c)
+    {
+        outlineColour = c;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color getOutlineColour()
+    {
+        return outlineColour;
+    }
+
+    /**
+     *
+     * returns the sequences in the group ordered by the ordering given by al
+     *
+     * @param al Alignment
+     * @return SequenceI[]
+     */
+    public SequenceI[] getSequencesInOrder(AlignmentI al)
+    {
+        int sz = sequences.size();
+        java.util.Hashtable orderedSeqs = new java.util.Hashtable();
+        SequenceI[] seqs = new SequenceI[sz];
+
+        for (int i = 0; i < sz; i++)
+        {
+            SequenceI seq = (SequenceI) sequences.elementAt(i);
+            int index = al.findIndex(seq);
+            orderedSeqs.put(index + "", seq);
+        }
+
+        int index = 0;
+
+        for (int i = 0; i < al.getHeight(); i++)
+        {
+            if (orderedSeqs.containsKey(i + ""))
+            {
+                seqs[index++] = (SequenceI) orderedSeqs.get(i + "");
+            }
+        }
+
+        return seqs;
+    }
+}
index 1f7a232..f2d9e74 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public interface SequenceI\r
-{\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     */\r
-    public void setName(String name);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getName();\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param start DOCUMENT ME!\r
-     */\r
-    public void setStart(int start);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getStart();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getDisplayId(boolean jvsuffix);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    public void setEnd(int end);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getEnd();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getLength();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param sequence DOCUMENT ME!\r
-     */\r
-    public void setSequence(String sequence);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getSequence();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getSequence(int start, int end);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public char getCharAt(int i);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param desc DOCUMENT ME!\r
-     */\r
-    public void setDescription(String desc);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getDescription();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param pos DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int findIndex(int pos);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int findPosition(int i);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int[] gapMap();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     */\r
-    public void deleteChars(int i, int j);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void deleteCharAt(int i);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param c DOCUMENT ME!\r
-     */\r
-    public void insertCharAt(int i, char c);\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     */\r
-    public void setColor(Color c);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color getColor();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceFeature[] getSequenceFeatures();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param v DOCUMENT ME!\r
-     */\r
-    public void setSequenceFeatures(SequenceFeature [] features);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param id DOCUMENT ME!\r
-     */\r
-    public void setPDBId(Vector ids);\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Vector getPDBId();\r
-\r
-    public void addPDBId(PDBEntry entry);\r
-\r
-    public String getVamsasId();\r
-\r
-    public void setVamsasId(String id);\r
-\r
-    public void setDBRef(Vector dbs);\r
-\r
-    public Vector getDBRef();\r
-\r
-    public void addDBRef(DBRefEntry entry);\r
-\r
-    public void addSequenceFeature(SequenceFeature sf);\r
-\r
-    public void setDatasetSequence(SequenceI seq);\r
-\r
-    public SequenceI getDatasetSequence();\r
-\r
-    public AlignmentAnnotation [] getAnnotation();\r
-\r
-    public void addAlignmentAnnotation(AlignmentAnnotation annotation);\r
-\r
-    public SequenceGroup getHiddenSequences();\r
-\r
-    public void addHiddenSequence(SequenceI seq);\r
-\r
-    public void showHiddenSequence(SequenceI seq);\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import java.util.*;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public interface SequenceI
+{
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     */
+    public void setName(String name);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getName();
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param start DOCUMENT ME!
+     */
+    public void setStart(int start);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getStart();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getDisplayId(boolean jvsuffix);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param end DOCUMENT ME!
+     */
+    public void setEnd(int end);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getEnd();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getLength();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param sequence DOCUMENT ME!
+     */
+    public void setSequence(String sequence);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getSequence();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getSequence(int start, int end);
+    /**
+     * create a new sequence object from start to end of this sequence
+     * @param start int
+     * @param end int
+     * @return SequenceI
+     */
+    public SequenceI getSubSequence(int start, int end);
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public char getCharAt(int i);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param desc DOCUMENT ME!
+     */
+    public void setDescription(String desc);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getDescription();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pos DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int findIndex(int pos);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int findPosition(int i);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int[] gapMap();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     */
+    public void deleteChars(int i, int j);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void deleteCharAt(int i);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param c DOCUMENT ME!
+     */
+    public void insertCharAt(int i, char c);
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     */
+    public void setColor(Color c);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color getColor();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceFeature[] getSequenceFeatures();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param v DOCUMENT ME!
+     */
+    public void setSequenceFeatures(SequenceFeature [] features);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param id DOCUMENT ME!
+     */
+    public void setPDBId(Vector ids);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Vector getPDBId();
+
+    public void addPDBId(PDBEntry entry);
+
+    public String getVamsasId();
+
+    public void setVamsasId(String id);
+
+    public void setDBRef(DBRefEntry[] dbs);
+
+    public DBRefEntry [] getDBRef();
+
+    public void addDBRef(DBRefEntry entry);
+
+    public void addSequenceFeature(SequenceFeature sf);
+
+    public void setDatasetSequence(SequenceI seq);
+
+    public SequenceI getDatasetSequence();
+
+    public AlignmentAnnotation [] getAnnotation();
+
+    public void addAlignmentAnnotation(AlignmentAnnotation annotation);
+
+    public SequenceGroup getHiddenSequences();
+
+    public void addHiddenSequence(SequenceI seq);
+
+    public void showHiddenSequence(SequenceI seq);
+
+    public void changeCase(boolean toUpper, int start, int end);
+
+    public void toggleCase(int start, int end);
+
+  /**
+   * getSubSequence from start to end of sequence
+   * @param start first residue in subSequence
+   * @return SequenceI
+   */
+  public SequenceI getSubSequence(int start);
+  /**
+   * remove all gaps in the sequence
+   * @return number of gaps removed
+   */
+  public int removeGaps();
+  /**
+   * remove all gaps from start to end columns in sequence
+   * @param start
+   * @param end
+   * @return number of gaps removed
+   */
+  public int removeGaps(int start, int end);
+
+}
index ac2e9e2..c29a6e0 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SequenceNode extends BinaryNode\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public float dist;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int count;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public float height;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public float ycount;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public Color color = Color.black;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public boolean dummy = false;\r
-    private boolean placeholder = false;\r
-\r
-    /**\r
-     * Creates a new SequenceNode object.\r
-     */\r
-    public SequenceNode()\r
-    {\r
-        super();\r
-    }\r
-\r
-    /**\r
-     * Creates a new SequenceNode object.\r
-     *\r
-     * @param val DOCUMENT ME!\r
-     * @param parent DOCUMENT ME!\r
-     * @param dist DOCUMENT ME!\r
-     * @param name DOCUMENT ME!\r
-     */\r
-    public SequenceNode(Object val, SequenceNode parent, float dist, String name)\r
-    {\r
-        super(val, parent, name);\r
-        this.dist = dist;\r
-    }\r
-\r
-    /**\r
-     * Creates a new SequenceNode object.\r
-     *\r
-     * @param val DOCUMENT ME!\r
-     * @param parent DOCUMENT ME!\r
-     * @param name DOCUMENT ME!\r
-     * @param dist DOCUMENT ME!\r
-     * @param bootstrap DOCUMENT ME!\r
-     * @param dummy DOCUMENT ME!\r
-     */\r
-    public SequenceNode(Object val, SequenceNode parent, String name,\r
-        float dist, int bootstrap, boolean dummy)\r
-    {\r
-        super(val, parent, name);\r
-        this.dist = dist;\r
-        this.bootstrap = bootstrap;\r
-        this.dummy = dummy;\r
-    }\r
-\r
-    /**\r
-     * @param dummy true if node is created for the representation of polytomous trees\r
-     */\r
-    public boolean isDummy()\r
-    {\r
-        return dummy;\r
-    }\r
-\r
-    /* @param placeholder is true if the sequence refered to in the\r
-     *  element node is not actually present in the associated alignment\r
-     */\r
-    public boolean isPlaceholder()\r
-    {\r
-        return placeholder;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param newstate DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean setDummy(boolean newstate)\r
-    {\r
-        boolean oldstate = dummy;\r
-        dummy = newstate;\r
-\r
-        return oldstate;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param Placeholder DOCUMENT ME!\r
-     */\r
-    public void setPlaceholder(boolean Placeholder)\r
-    {\r
-        this.placeholder = Placeholder;\r
-    }\r
-\r
-    /**\r
-     * ascends the tree but doesn't stop until a non-dummy node is discovered.\r
-     * This will probably break if the tree is a mixture of BinaryNodes and SequenceNodes.\r
-     */\r
-    public SequenceNode AscendTree()\r
-    {\r
-        SequenceNode c = this;\r
-\r
-        do\r
-        {\r
-            c = (SequenceNode) c.parent();\r
-        }\r
-        while ((c != null) && c.dummy);\r
-\r
-        return c;\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SequenceNode extends BinaryNode
+{
+    /** DOCUMENT ME!! */
+    public float dist;
+
+    /** DOCUMENT ME!! */
+    public int count;
+
+    /** DOCUMENT ME!! */
+    public float height;
+
+    /** DOCUMENT ME!! */
+    public float ycount;
+
+    /** DOCUMENT ME!! */
+    public Color color = Color.black;
+
+    /** DOCUMENT ME!! */
+    public boolean dummy = false;
+    private boolean placeholder = false;
+
+    /**
+     * Creates a new SequenceNode object.
+     */
+    public SequenceNode()
+    {
+        super();
+    }
+
+    /**
+     * Creates a new SequenceNode object.
+     *
+     * @param val DOCUMENT ME!
+     * @param parent DOCUMENT ME!
+     * @param dist DOCUMENT ME!
+     * @param name DOCUMENT ME!
+     */
+    public SequenceNode(Object val, SequenceNode parent, float dist, String name)
+    {
+        super(val, parent, name);
+        this.dist = dist;
+    }
+
+    /**
+     * Creates a new SequenceNode object.
+     *
+     * @param val DOCUMENT ME!
+     * @param parent DOCUMENT ME!
+     * @param name DOCUMENT ME!
+     * @param dist DOCUMENT ME!
+     * @param bootstrap DOCUMENT ME!
+     * @param dummy DOCUMENT ME!
+     */
+    public SequenceNode(Object val, SequenceNode parent, String name,
+        float dist, int bootstrap, boolean dummy)
+    {
+        super(val, parent, name);
+        this.dist = dist;
+        this.bootstrap = bootstrap;
+        this.dummy = dummy;
+    }
+
+    /**
+     * @param dummy true if node is created for the representation of polytomous trees
+     */
+    public boolean isDummy()
+    {
+        return dummy;
+    }
+
+    /* @param placeholder is true if the sequence refered to in the
+     *  element node is not actually present in the associated alignment
+     */
+    public boolean isPlaceholder()
+    {
+        return placeholder;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param newstate DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean setDummy(boolean newstate)
+    {
+        boolean oldstate = dummy;
+        dummy = newstate;
+
+        return oldstate;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param Placeholder DOCUMENT ME!
+     */
+    public void setPlaceholder(boolean Placeholder)
+    {
+        this.placeholder = Placeholder;
+    }
+
+    /**
+     * ascends the tree but doesn't stop until a non-dummy node is discovered.
+     * This will probably break if the tree is a mixture of BinaryNodes and SequenceNodes.
+     */
+    public SequenceNode AscendTree()
+    {
+        SequenceNode c = this;
+
+        do
+        {
+            c = (SequenceNode) c.parent();
+        }
+        while ((c != null) && c.dummy);
+
+        return c;
+    }
+}
index 2c5d2a3..546dc1a 100755 (executable)
@@ -1,43 +1,43 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SequencePoint\r
-{\r
-    // SMJS PUBLIC\r
-\r
-    /** DOCUMENT ME!! */\r
-    public SequenceI sequence;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public float[] coord;\r
-\r
-    // SMJS ENDPUBLIC\r
-    public SequencePoint(SequenceI sequence, float[] coord)\r
-    {\r
-        this.sequence = sequence;\r
-        this.coord = coord;\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SequencePoint
+{
+    // SMJS PUBLIC
+
+    /** DOCUMENT ME!! */
+    public SequenceI sequence;
+
+    /** DOCUMENT ME!! */
+    public float[] coord;
+
+    // SMJS ENDPUBLIC
+    public SequencePoint(SequenceI sequence, float[] coord)
+    {
+        this.sequence = sequence;
+        this.coord = coord;
+    }
+}
index d2f4dcf..851cb7c 100755 (executable)
@@ -1,92 +1,93 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-import java.util.*;\r
-\r
-public class UniprotEntry\r
-{\r
-\r
-  UniprotSequence sequence;\r
-  Vector name;\r
-  Vector accession;\r
-  Vector feature;\r
-  Vector dbrefs;\r
-  Vector proteinName;\r
-\r
-  public void setAccession(Vector items)\r
-  {\r
-    accession = items;\r
-  }\r
-\r
-  public void setFeature(Vector items)\r
-  {\r
-       feature = items;\r
-   }\r
-\r
-   public Vector getFeature() {\r
-       return feature;\r
-   }\r
-\r
-\r
-   public Vector getAccession()\r
-   {\r
-     return accession;\r
-   }\r
-\r
-   public void setProteinName(Vector items)\r
-   {\r
-     proteinName = items;\r
-   }\r
-\r
-   public Vector getProteinName()\r
-   {\r
-     return proteinName;\r
-   }\r
-\r
-  public void setName(Vector na)\r
-  {\r
-    name = na;\r
-  }\r
-  public Vector getName()\r
-  {\r
-    return name;\r
-  }\r
-\r
-  public UniprotSequence getUniprotSequence()\r
-  {\r
-    return sequence;\r
-  }\r
-\r
-  public void setUniprotSequence(UniprotSequence seq)\r
-  {\r
-    sequence = seq;\r
-  }\r
-\r
-  public Vector getDbReference()\r
-  {\r
-    return dbrefs;\r
-  }\r
-\r
-  public void setDbReference(Vector dbref)\r
-  {\r
-   this.dbrefs = dbref;\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+import java.util.*;
+
+public class UniprotEntry
+{
+
+  UniprotSequence sequence;
+  Vector name;
+  Vector accession;
+  Vector feature;
+  Vector dbrefs;
+  UniprotProteinName protName;
+
+  public void setAccession(Vector items)
+  {
+    accession = items;
+  }
+
+  public void setFeature(Vector items)
+  {
+       feature = items;
+   }
+
+   public Vector getFeature() {
+       return feature;
+   }
+
+
+   public Vector getAccession()
+   {
+     return accession;
+   }
+
+   public void setProtein(UniprotProteinName names)
+   {
+     protName = names;
+   }
+
+
+   public UniprotProteinName getProtein()
+   {
+     return protName;
+   }
+
+  public void setName(Vector na)
+  {
+    name = na;
+  }
+  public Vector getName()
+  {
+    return name;
+  }
+
+  public UniprotSequence getUniprotSequence()
+  {
+    return sequence;
+  }
+
+  public void setUniprotSequence(UniprotSequence seq)
+  {
+    sequence = seq;
+  }
+
+  public Vector getDbReference()
+  {
+    return dbrefs;
+  }
+
+  public void setDbReference(Vector dbref)
+  {
+   this.dbrefs = dbref;
+  }
+
+}
index fd15da4..22678ce 100755 (executable)
@@ -1,33 +1,33 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-import java.util.Vector;\r
-\r
-public class UniprotFile\r
-{\r
-  Vector _items;\r
-\r
-  public void setUniprotEntries(Vector items) {\r
-       _items = items;\r
-   }\r
-\r
-   public Vector getUniprotEntries() {\r
-       return _items;\r
-   }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+import java.util.Vector;
+
+public class UniprotFile
+{
+  Vector _items;
+
+  public void setUniprotEntries(Vector items) {
+       _items = items;
+   }
+
+   public Vector getUniprotEntries() {
+       return _items;
+   }
+}
index 96fe38e..8658855 100755 (executable)
@@ -1,42 +1,42 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.datamodel;\r
-\r
-public class UniprotSequence\r
-{\r
-    /**\r
-   * internal content storage\r
-   */\r
-  private java.lang.String _content = "";\r
-\r
-  public void setContent(String seq)\r
-  {\r
-    StringBuffer sb = new StringBuffer();\r
-    for(int i=0; i<seq.length(); i++)\r
-      if(seq.charAt(i)!=' ')\r
-      {\r
-        sb.append(seq.charAt(i));\r
-      }\r
-    _content = sb.toString();\r
-  }\r
-\r
-  public String getContent()\r
-  { return _content; }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.datamodel;
+
+public class UniprotSequence
+{
+    /**
+   * internal content storage
+   */
+  private java.lang.String _content = "";
+
+  public void setContent(String seq)
+  {
+    StringBuffer sb = new StringBuffer();
+    for(int i=0; i<seq.length(); i++)
+      if(seq.charAt(i)!=' ')
+      {
+        sb.append(seq.charAt(i));
+      }
+    _content = sb.toString();
+  }
+
+  public String getContent()
+  { return _content; }
+
+}
index b2c8901..78f34cb 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Softwarechang\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import java.beans.*;\r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.datatransfer.*;\r
-import java.awt.event.*;\r
-import java.awt.print.*;\r
-import javax.swing.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-import jalview.io.*;\r
-import jalview.jbgui.*;\r
-import jalview.schemes.*;\r
-import jalview.ws.*;\r
-import java.awt.dnd.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AlignFrame\r
-    extends GAlignFrame implements ClipboardOwner, DropTargetListener\r
-{\r
-  /** DOCUMENT ME!! */\r
-  public static final int NEW_WINDOW_WIDTH = 700;\r
-\r
-  /** DOCUMENT ME!! */\r
-  public static final int NEW_WINDOW_HEIGHT = 500;\r
-  AlignmentPanel alignPanel;\r
-  AlignViewport viewport;\r
-\r
-  Vector viewports = new Vector();\r
-  Vector alignPanels = new Vector();\r
-\r
-  /** DOCUMENT ME!! */\r
-  public String currentFileFormat = null;\r
-  Stack historyList = new Stack();\r
-  Stack redoList = new Stack();\r
-  private int treeCount = 0;\r
-\r
-\r
-  /**\r
-   * Creates a new AlignFrame object.\r
-   *\r
-   * @param al DOCUMENT ME!\r
-   */\r
-  public AlignFrame(AlignmentI al)\r
-  {\r
-    viewport = new AlignViewport(al);\r
-    viewports.add(viewport);\r
-\r
-    this.setDropTarget(new java.awt.dnd.DropTarget(this, this));\r
-\r
-    if(viewport.vconsensus==null)\r
-    {\r
-      //Out of memory calculating consensus.\r
-      BLOSUM62Colour.setEnabled(false);\r
-      PIDColour.setEnabled(false);\r
-      conservationMenuItem.setEnabled(false);\r
-      modifyConservation.setEnabled(false);\r
-      abovePIDThreshold.setEnabled(false);\r
-      modifyPID.setEnabled(false);\r
-    }\r
-\r
-    alignPanel = new AlignmentPanel(this, viewport);\r
-    alignPanels.add(alignPanel);\r
-\r
-    String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT", "No sort");\r
-\r
-    if(sortby.equals("Id"))\r
-      sortIDMenuItem_actionPerformed(null);\r
-    else if(sortby.equals("Pairwise Identity"))\r
-      sortPairwiseMenuItem_actionPerformed(null);\r
-\r
-   // remove(tabbedPane);\r
-    getContentPane().add(alignPanel, BorderLayout.CENTER);\r
-\r
-\r
-\r
-  //  tabbedPane.add(al.isNucleotide() ? "DNA":"Protein", alignPanel);\r
-\r
-    ///Dataset tab\r
-    /////////////////////////\r
-    if(al.getDataset()==null)\r
-    {\r
-      al.setDataset(null);\r
-    }\r
-   // AlignViewport ds = new AlignViewport(al.getDataset(), true);\r
-   // AlignmentPanel dap = new AlignmentPanel(this, ds);\r
-  //  tabbedPane.add("Dataset", dap);\r
-  //  viewports.add(ds);\r
-  //  alignPanels.add(dap);\r
-    /////////////////////////\r
-\r
-\r
-    viewport.addPropertyChangeListener(new PropertyChangeListener()\r
-    {\r
-     public void propertyChange(PropertyChangeEvent evt)\r
-     {\r
-       if (evt.getPropertyName().equals("alignment"))\r
-       {\r
-         alignmentChanged();\r
-       }\r
-     }\r
-   });\r
-\r
-\r
-  if (Desktop.desktop != null)\r
-  {\r
-    addServiceListeners();\r
-    setGUINucleotide(al.isNucleotide());\r
-  }\r
-  }\r
-\r
-  /* Set up intrinsic listeners for dynamically generated GUI bits. */\r
-  private void addServiceListeners()\r
-  {\r
-    final java.beans.PropertyChangeListener thisListener;\r
-    // Do this once to get current state\r
-    BuildWebServiceMenu();\r
-    Desktop.discoverer.addPropertyChangeListener(\r
-        thisListener = new java.beans.PropertyChangeListener()\r
-    {\r
-      public void propertyChange(PropertyChangeEvent evt)\r
-      {\r
-        // System.out.println("Discoverer property change.");\r
-        if (evt.getPropertyName().equals("services"))\r
-        {\r
-          // System.out.println("Rebuilding web service menu");\r
-          BuildWebServiceMenu();\r
-        }\r
-      }\r
-    });\r
-    addInternalFrameListener(new javax.swing.event.\r
-                             InternalFrameAdapter()\r
-    {\r
-      public void internalFrameClosed(\r
-          javax.swing.event.InternalFrameEvent evt)\r
-      {\r
-        // System.out.println("deregistering discoverer listener");\r
-        Desktop.discoverer.removePropertyChangeListener(thisListener);\r
-        closeMenuItem_actionPerformed(null);\r
-      }\r
-      ;\r
-    });\r
-\r
-  }\r
-\r
-  public void setGUINucleotide(boolean nucleotide)\r
-  {\r
-    showTranslation.setVisible( nucleotide );\r
-    //sequenceFeatures.setVisible(!nucleotide );\r
-    //featureSettings.setVisible( !nucleotide );\r
-    conservationMenuItem.setVisible( !nucleotide );\r
-    modifyConservation.setVisible(   !nucleotide );\r
-\r
-    //Remember AlignFrame always starts as protein\r
-    if(!nucleotide)\r
-    {\r
-      calculateMenu.remove(calculateMenu.getItemCount()-2);\r
-    }\r
-  }\r
-\r
-\r
-  /*\r
-   Added so Castor Mapping file can obtain Jalview Version\r
-  */\r
-  public String getVersion()\r
-  {\r
-    return  jalview.bin.Cache.getProperty("VERSION");\r
-  }\r
-\r
-\r
-  public void fetchSequence_actionPerformed(ActionEvent e)\r
-  {\r
-    new SequenceFetcher(this);\r
-  }\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
-  {\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
-        getProperty(\r
-            "LAST_DIRECTORY"),\r
-        new String[]\r
-        {\r
-        "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
-        "jar"\r
-    },\r
-        new String[]\r
-        {\r
-        "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
-    }, currentFileFormat);\r
-\r
-    chooser.setAcceptAllFileFilterUsed(false);\r
-    chooser.setFileView(new JalviewFileView());\r
-    chooser.setDialogTitle("Save Alignment to file");\r
-    chooser.setToolTipText("Save");\r
-\r
-    int value = chooser.showSaveDialog(this);\r
-\r
-    if (value == JalviewFileChooser.APPROVE_OPTION)\r
-    {\r
-        currentFileFormat = chooser.getSelectedFormat();\r
-\r
-        if (currentFileFormat == null)\r
-        {\r
-          JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                                "You must select a file format before saving!",\r
-                                                "File format not specified",\r
-                                                JOptionPane.WARNING_MESSAGE);\r
-          value = chooser.showSaveDialog(this);\r
-          return;\r
-        }\r
-\r
-      jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",\r
-                                    currentFileFormat);\r
-\r
-      String choice = chooser.getSelectedFile().getPath();\r
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
-\r
-      saveAlignment(choice, currentFileFormat);\r
-    }\r
-  }\r
-\r
-  public boolean saveAlignment(String file, String format)\r
-  {\r
-    if (format.equalsIgnoreCase("Jalview"))\r
-    {\r
-      String shortName = title;\r
-\r
-      if (shortName.indexOf(java.io.File.separatorChar) > -1)\r
-      {\r
-        shortName = shortName.substring(shortName.lastIndexOf(\r
-            java.io.File.separatorChar) + 1);\r
-      }\r
-\r
-      Jalview2XML.SaveAlignment(this, file, shortName);\r
-\r
-      // USE Jalview2XML to save this file\r
-      return true;\r
-    }\r
-    else\r
-    {\r
-      String output = new FormatAdapter().formatSequences(format,\r
-          viewport.getAlignment().\r
-          getSequences());\r
-      if (output == null)\r
-      {\r
-        return false;\r
-      }\r
-\r
-      try\r
-      {\r
-        java.io.PrintWriter out = new java.io.PrintWriter(\r
-            new java.io.FileWriter(file));\r
-\r
-        out.print(output);\r
-        out.close();\r
-        return true;\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-    return false;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void outputText_actionPerformed(ActionEvent e)\r
-  {\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
-    Desktop.addInternalFrame(cap,\r
-                             "Alignment output - " + e.getActionCommand(), 600,\r
-                             500);\r
-    cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(),\r
-                                              viewport.getAlignment().\r
-                                              getSequences()));\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    new HTMLOutput(viewport,\r
-                   alignPanel.seqPanel.seqCanvas.getSequenceRenderer(),\r
-        alignPanel.seqPanel.seqCanvas.getFeatureRenderer());\r
-  }\r
-\r
-  public void createImageMap(File file, String image)\r
-  {\r
-    alignPanel.makePNGImageMap(file, image);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void createPNG(File f)\r
-  {\r
-    alignPanel.makePNG(f);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void createEPS(File f)\r
-  {\r
-    alignPanel.makeEPS(f);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void printMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    //Putting in a thread avoids Swing painting problems\r
-    PrintThread thread = new PrintThread();\r
-    thread.start();\r
-  }\r
-\r
-  public void associatedData_actionPerformed(ActionEvent e)\r
-  {\r
-    // Pick the tree file\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
-        getProperty(\r
-            "LAST_DIRECTORY"));\r
-    chooser.setFileView(new JalviewFileView());\r
-    chooser.setDialogTitle("Load Jalview Annotations or Features File");\r
-    chooser.setToolTipText("Load Jalview Annotations / Features file");\r
-\r
-    int value = chooser.showOpenDialog(null);\r
-\r
-    if (value == JalviewFileChooser.APPROVE_OPTION)\r
-    {\r
-      String choice = chooser.getSelectedFile().getPath();\r
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
-      loadJalviewDataFile(choice);\r
-    }\r
-\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void closeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    try\r
-    {\r
-      PaintRefresher.components.remove(viewport.alignment);\r
-      this.setClosed(true);\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  void updateEditMenuBar()\r
-  {\r
-    if (historyList.size() > 0)\r
-    {\r
-      undoMenuItem.setEnabled(true);\r
-\r
-      HistoryItem hi = (HistoryItem) historyList.peek();\r
-      undoMenuItem.setText("Undo " + hi.getDescription());\r
-    }\r
-    else\r
-    {\r
-      undoMenuItem.setEnabled(false);\r
-      undoMenuItem.setText("Undo");\r
-    }\r
-\r
-    if (redoList.size() > 0)\r
-    {\r
-      redoMenuItem.setEnabled(true);\r
-\r
-      HistoryItem hi = (HistoryItem) redoList.peek();\r
-      redoMenuItem.setText("Redo " + hi.getDescription());\r
-    }\r
-    else\r
-    {\r
-      redoMenuItem.setEnabled(false);\r
-      redoMenuItem.setText("Redo");\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param hi DOCUMENT ME!\r
-   */\r
-  public void addHistoryItem(HistoryItem hi)\r
-  {\r
-    historyList.push(hi);\r
-    updateEditMenuBar();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void undoMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    HistoryItem hi = (HistoryItem) historyList.pop();\r
-    redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
-                                  HistoryItem.HIDE));\r
-    restoreHistoryItem(hi);\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void redoMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    HistoryItem hi = (HistoryItem) redoList.pop();\r
-    restoreHistoryItem(hi);\r
-    updateEditMenuBar();\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  // used by undo and redo\r
-  void restoreHistoryItem(HistoryItem hi)\r
-  {\r
-\r
-    hi.restore();\r
-\r
-    updateEditMenuBar();\r
-\r
-    viewport.firePropertyChange("alignment", null,\r
-                                viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param up DOCUMENT ME!\r
-   */\r
-  public void moveSelectedSequences(boolean up)\r
-  {\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-\r
-    if (sg == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    if (up)\r
-    {\r
-      for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
-      {\r
-        SequenceI seq = viewport.alignment.getSequenceAt(i);\r
-\r
-        if (!sg.sequences.contains(seq))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
-\r
-        if (sg.sequences.contains(temp))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        viewport.alignment.getSequences().setElementAt(temp, i);\r
-        viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
-      {\r
-        SequenceI seq = viewport.alignment.getSequenceAt(i);\r
-\r
-        if (!sg.sequences.contains(seq))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
-\r
-        if (sg.sequences.contains(temp))\r
-        {\r
-          continue;\r
-        }\r
-\r
-        viewport.alignment.getSequences().setElementAt(temp, i);\r
-        viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
-      }\r
-    }\r
-\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void lostOwnership(Clipboard clipboard, Transferable contents)\r
-  {\r
-    Desktop.jalviewClipboard = null;\r
-  }\r
-\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void copy_actionPerformed(ActionEvent e)\r
-  {\r
-    if (viewport.getSelectionGroup() == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-\r
-    Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
-\r
-    Hashtable orderedSeqs = new Hashtable();\r
-    SequenceI[] seqs = new SequenceI[sg.getSize()];\r
-\r
-    for (int i = 0; i < sg.getSize(); i++)\r
-    {\r
-      SequenceI seq = sg.getSequenceAt(i);\r
-      int index = viewport.alignment.findIndex(seq);\r
-      orderedSeqs.put(index + "", seq);\r
-    }\r
-\r
-    int index = 0, startRes, endRes;\r
-    char ch;\r
-\r
-    for (int i = 0; i < sg.getSize(); i++)\r
-    {\r
-      SequenceI seq = null;\r
-\r
-      while (seq == null)\r
-      {\r
-        if (orderedSeqs.containsKey(index + ""))\r
-        {\r
-          seq = (SequenceI) orderedSeqs.get(index + "");\r
-          index++;\r
-\r
-          break;\r
-        }\r
-        else\r
-        {\r
-          index++;\r
-        }\r
-      }\r
-\r
-      //FIND START RES\r
-      //Returns residue following index if gap\r
-      startRes = seq.findPosition(sg.getStartRes());\r
-\r
-      //FIND END RES\r
-      //Need to find the residue preceeding index if gap\r
-      endRes = 0;\r
-\r
-      for (int j = 0; j < sg.getEndRes() + 1 && j < seq.getLength(); j++)\r
-      {\r
-        ch = seq.getCharAt(j);\r
-        if (!jalview.util.Comparison.isGap( (ch)))\r
-        {\r
-          endRes++;\r
-        }\r
-      }\r
-\r
-      if (endRes > 0)\r
-      {\r
-        endRes += seq.getStart() - 1;\r
-      }\r
-\r
-      seqs[i] = new Sequence(seq.getName(),\r
-                             seq.getSequence(sg.getStartRes(), sg.getEndRes() + 1),\r
-                             startRes,\r
-                             endRes);\r
-      seqs[i].setDescription(seq.getDescription());\r
-      seqs[i].setDBRef(seq.getDBRef());\r
-      seqs[i].setSequenceFeatures(seq.getSequenceFeatures());\r
-      seqs[i].setDatasetSequence(seq.getDatasetSequence());\r
-\r
-    }\r
-\r
-    FastaFile ff = new FastaFile();\r
-    ff.addJVSuffix( viewport.showJVSuffix );\r
-    c.setContents(new StringSelection( ff.print(seqs)), this);\r
-    Desktop.jalviewClipboard = new Object[]{seqs,  viewport.alignment.getDataset()};\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void pasteNew_actionPerformed(ActionEvent e)\r
-  {\r
-    paste(true);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void pasteThis_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
-                                   HistoryItem.PASTE));\r
-    paste(false);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param newAlignment DOCUMENT ME!\r
-   */\r
-  void paste(boolean newAlignment)\r
-  {\r
-    try\r
-    {\r
-      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
-      Transferable contents = c.getContents(this);\r
-\r
-      if (contents == null)\r
-      {\r
-        return;\r
-      }\r
-\r
-      String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
-      if(str.length()<1)\r
-        return;\r
-\r
-      String format = new IdentifyFile().Identify(str, "Paste");\r
-      SequenceI[] sequences;\r
-\r
-     if(Desktop.jalviewClipboard!=null)\r
-     {\r
-       // The clipboard was filled from within Jalview, we must use the sequences\r
-       // And dataset from the copied alignment\r
-       sequences = (SequenceI[])Desktop.jalviewClipboard[0];\r
-     }\r
-     else\r
-     {\r
-       sequences = new FormatAdapter().readFile(str, "Paste", format);\r
-     }\r
-\r
-      if (newAlignment)\r
-      {\r
-\r
-        Alignment alignment = new Alignment(sequences);\r
-\r
-        if(Desktop.jalviewClipboard!=null)\r
-           alignment.setDataset( (Alignment)Desktop.jalviewClipboard[1] );\r
-        else\r
-           alignment.setDataset( null );\r
-\r
-\r
-        AlignFrame af = new AlignFrame(alignment);\r
-        String newtitle = new String("Copied sequences");\r
-\r
-        //>>>This is a fix for the moment, until a better solution is found!!<<<\r
-        FeatureRenderer fr = af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer();\r
-        fr.featureColours = alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureColours;\r
-\r
-        if (title.startsWith("Copied sequences"))\r
-        {\r
-          newtitle = title;\r
-        }\r
-        else\r
-        {\r
-          newtitle = newtitle.concat("- from " + title);\r
-        }\r
-\r
-        Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
-                                 NEW_WINDOW_HEIGHT);\r
-      }\r
-      else\r
-      {\r
-        //!newAlignment\r
-        for (int i = 0; i < sequences.length; i++)\r
-        {\r
-          Sequence newseq = new Sequence(sequences[i].getName(),\r
-              sequences[i].getSequence(), sequences[i].getStart(),\r
-              sequences[i].getEnd());\r
-          viewport.alignment.addSequence(newseq);\r
-          if(sequences[i].getDatasetSequence()==null)\r
-          {\r
-             ////////////////////////////\r
-            //Datset needs extension;\r
-            /////////////////////////////\r
-            Sequence ds = new Sequence(sequences[i].getName(),\r
-                                       AlignSeq.extractGaps("-. ", sequences[i].getSequence()),\r
-                                       sequences[i].getStart(),\r
-                                       sequences[i].getEnd());\r
-            newseq.setDatasetSequence(ds);\r
-            viewport.alignment.getDataset().addSequence(ds);\r
-          }\r
-          else\r
-          {\r
-            newseq.setDatasetSequence(sequences[i].getDatasetSequence());\r
-            if(sequences[i].getDatasetSequence().getAnnotation()!=null)\r
-            {\r
-              for(int aa=0; aa<sequences[i].getDatasetSequence().getAnnotation().length; aa++)\r
-              {\r
-                viewport.alignment.addAnnotation(sequences[i].getDatasetSequence().getAnnotation()[aa]);\r
-              }\r
-            }\r
-          }\r
-        }\r
-        viewport.setEndSeq(viewport.alignment.getHeight());\r
-        viewport.alignment.getWidth();\r
-        viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-      }\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-        System.out.println("Exception whilst pasting: "+ex);\r
-        // could be anything being pasted in here\r
-    }\r
-\r
-\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void cut_actionPerformed(ActionEvent e)\r
-  {\r
-    copy_actionPerformed(null);\r
-    delete_actionPerformed(null);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void delete_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-    if (viewport.getSelectionGroup() == null)\r
-    {\r
-      return;\r
-    }\r
-\r
-\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-\r
-\r
-\r
-    //Jalview no longer allows deletion of residues.\r
-    //Check here whether any residues are in selection area\r
-    if( sg.getEndRes()-sg.getStartRes() < viewport.alignment.getWidth()-1)\r
-    {\r
-      for (int i = 0; i < sg.sequences.size(); i++)\r
-      {\r
-        SequenceI seq = sg.getSequenceAt(i);\r
-        int j = sg.getStartRes();\r
-        do\r
-        {\r
-          if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))\r
-          {\r
-            JOptionPane.showInternalMessageDialog(\r
-                Desktop.desktop, "Cannot delete residues from alignment!\n"\r
-                + "Try hiding columns instead.",\r
-                "Deletion of residues not permitted",\r
-                JOptionPane.WARNING_MESSAGE);\r
-\r
-            return;\r
-          }\r
-          j++;\r
-        }while(j<=sg.getEndRes());\r
-      }\r
-    }\r
-\r
-\r
-    addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
-                                   HistoryItem.HIDE));\r
-\r
-\r
-    for (int i = 0; i < sg.sequences.size(); i++)\r
-    {\r
-      SequenceI seq = sg.getSequenceAt(i);\r
-      int index = viewport.getAlignment().findIndex(seq);\r
-\r
-      seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
-\r
-      // If the cut affects all sequences, remove highlighted columns\r
-      if (sg.sequences.size() == viewport.alignment.getHeight())\r
-      {\r
-        viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
-            sg.getEndRes() + 1);\r
-      }\r
-\r
-      if (seq.getSequence().length() < 1)\r
-      {\r
-        viewport.getAlignment().deleteSequence(seq);\r
-      }\r
-      else\r
-      {\r
-        viewport.getAlignment().getSequences().setElementAt(seq, index);\r
-      }\r
-    }\r
-\r
-    viewport.setSelectionGroup(null);\r
-    viewport.alignment.deleteGroup(sg);\r
-\r
-    viewport.firePropertyChange("alignment", null,\r
-                                  viewport.getAlignment().getSequences());\r
-\r
-\r
-\r
-    if (viewport.getAlignment().getHeight() < 1)\r
-    {\r
-      try\r
-      {\r
-        this.setClosed(true);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void deleteGroups_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.alignment.deleteAllGroups();\r
-    viewport.setSelectionGroup(null);\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    SequenceGroup sg = new SequenceGroup();\r
-\r
-    for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
-         i++)\r
-    {\r
-      sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
-    }\r
-\r
-    sg.setEndRes(viewport.alignment.getWidth() - 1);\r
-    viewport.setSelectionGroup(sg);\r
-    PaintRefresher.Refresh(null, viewport.alignment);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setSelectionGroup(null);\r
-    viewport.getColumnSelection().clear();\r
-    viewport.setSelectionGroup(null);\r
-    alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);\r
-    alignPanel.idPanel.idCanvas.searchResults = null;\r
-    PaintRefresher.Refresh(null, viewport.alignment);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    SequenceGroup sg = viewport.getSelectionGroup();\r
-\r
-    if (sg == null)\r
-    {\r
-      selectAllSequenceMenuItem_actionPerformed(null);\r
-\r
-      return;\r
-    }\r
-\r
-    for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
-         i++)\r
-    {\r
-      sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
-    }\r
-\r
-    PaintRefresher.Refresh(null, viewport.alignment);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    ColumnSelection colSel = viewport.getColumnSelection();\r
-\r
-    if (colSel.size() > 0)\r
-    {\r
-      addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
-                                     HistoryItem.HIDE));\r
-\r
-      int min = colSel.getMin();\r
-      viewport.getAlignment().trimLeft(min);\r
-      colSel.compensateForEdit(0, min);\r
-\r
-      if (viewport.getSelectionGroup() != null)\r
-      {\r
-        viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
-      }\r
-\r
-      Vector groups = viewport.alignment.getGroups();\r
-\r
-      for (int i = 0; i < groups.size(); i++)\r
-      {\r
-        SequenceGroup sg = (SequenceGroup) groups.get(i);\r
-\r
-        if (!sg.adjustForRemoveLeft(min))\r
-        {\r
-          viewport.alignment.deleteGroup(sg);\r
-        }\r
-      }\r
-\r
-      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    ColumnSelection colSel = viewport.getColumnSelection();\r
-\r
-    if (colSel.size() > 0)\r
-    {\r
-      addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
-                                     HistoryItem.HIDE));\r
-\r
-      int max = colSel.getMax();\r
-      viewport.getAlignment().trimRight(max);\r
-\r
-      if (viewport.getSelectionGroup() != null)\r
-      {\r
-        viewport.getSelectionGroup().adjustForRemoveRight(max);\r
-      }\r
-\r
-      Vector groups = viewport.alignment.getGroups();\r
-\r
-      for (int i = 0; i < groups.size(); i++)\r
-      {\r
-        SequenceGroup sg = (SequenceGroup) groups.get(i);\r
-\r
-        if (!sg.adjustForRemoveRight(max))\r
-        {\r
-          viewport.alignment.deleteGroup(sg);\r
-        }\r
-      }\r
-\r
-      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
-                                   viewport.alignment, HistoryItem.HIDE));\r
-\r
-    //This is to maintain viewport position on first residue\r
-    //of first sequence\r
-    SequenceI seq = viewport.alignment.getSequenceAt(0);\r
-    int startRes = seq.findPosition(viewport.startRes);\r
-\r
-    viewport.getAlignment().removeGaps();\r
-\r
-    viewport.setStartRes(seq.findIndex(startRes)-1);\r
-\r
-   viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
-                                   HistoryItem.HIDE));\r
-\r
-    //This is to maintain viewport position on first residue\r
-    //of first sequence\r
-    SequenceI seq = viewport.alignment.getSequenceAt(0);\r
-    int startRes = seq.findPosition(viewport.startRes);\r
-\r
-\r
-    SequenceI current;\r
-    int jSize;\r
-\r
-    Vector seqs = null;\r
-\r
-    int start = 0;\r
-    int end = viewport.alignment.getWidth();\r
-\r
-    if (viewport.getSelectionGroup() != null\r
-        && viewport.getSelectionGroup().sequences != null\r
-        && viewport.getSelectionGroup().sequences.size() > 0)\r
-    {\r
-      seqs = viewport.getSelectionGroup().sequences;\r
-      start = viewport.getSelectionGroup().getStartRes();\r
-      end = viewport.getSelectionGroup().getEndRes()+1;\r
-    }\r
-    else\r
-    {\r
-      seqs = viewport.alignment.getSequences();\r
-    }\r
-\r
-    for (int i = 0; i < seqs.size(); i++)\r
-    {\r
-      current = (SequenceI) seqs.elementAt(i);\r
-      jSize = current.getLength();\r
-\r
-      // Removing a range is much quicker than removing gaps\r
-      // one by one for long sequences\r
-      int j = start;\r
-      int rangeStart=-1, rangeEnd=-1;\r
-\r
-      do\r
-      {\r
-        if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
-        {\r
-          if(rangeStart==-1)\r
-           {\r
-             rangeStart = j;\r
-             rangeEnd = j+1;\r
-           }\r
-           else\r
-           {\r
-             rangeEnd++;\r
-           }\r
-           j++;\r
-        }\r
-        else\r
-        {\r
-          if(rangeStart>-1)\r
-          {\r
-            current.deleteChars(rangeStart, rangeEnd);\r
-            j-=rangeEnd-rangeStart;\r
-            jSize-=rangeEnd-rangeStart;\r
-            rangeStart = -1;\r
-            rangeEnd = -1;\r
-          }\r
-          else\r
-            j++;\r
-        }\r
-      }\r
-      while (j < end && j < jSize);\r
-      if(rangeStart>-1)\r
-      {\r
-       current.deleteChars(rangeStart, rangeEnd);\r
-      }\r
-    }\r
-\r
-    viewport.setStartRes(seq.findIndex(startRes)-1);\r
-\r
-    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
-  }\r
-\r
- public void alignmentChanged()\r
- {\r
-   if(viewport.vconsensus!=null)\r
-   {\r
-     viewport.updateConsensus();\r
-     viewport.updateConservation();\r
-   }\r
-   resetAllColourSchemes();\r
-   if(alignPanel.overviewPanel!=null)\r
-     alignPanel.overviewPanel.updateOverviewImage();\r
-\r
-   viewport.alignment.adjustSequenceAnnotations();\r
-\r
-   alignPanel.repaint();\r
- }\r
-\r
-  void resetAllColourSchemes()\r
-  {\r
-    ColourSchemeI cs = viewport.globalColourScheme;\r
-    if(cs!=null)\r
-    {\r
-      if (cs instanceof ClustalxColourScheme)\r
-      {\r
-        ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
-            resetClustalX(viewport.alignment.getSequences(),\r
-                          viewport.alignment.getWidth());\r
-      }\r
-\r
-      cs.setConsensus(viewport.vconsensus);\r
-      if (cs.conservationApplied())\r
-      {\r
-        Alignment al = (Alignment) viewport.alignment;\r
-        Conservation c = new Conservation("All",\r
-                                          ResidueProperties.propHash, 3,\r
-                                          al.getSequences(), 0,\r
-                                          al.getWidth() - 1);\r
-        c.calculate();\r
-        c.verdict(false, viewport.ConsPercGaps);\r
-\r
-        cs.setConservation(c);\r
-      }\r
-    }\r
-\r
-    int s, sSize = viewport.alignment.getGroups().size();\r
-    for(s=0; s<sSize; s++)\r
-    {\r
-      SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
-      if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
-      {\r
-        ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
-      }\r
-      sg.recalcConservation();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
-                                   HistoryItem.HIDE));\r
-    if (viewport.getAlignment().padGaps())\r
-      alignmentChanged();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void findMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    JInternalFrame frame = new JInternalFrame();\r
-    Finder finder = new Finder(viewport, alignPanel, frame);\r
-    frame.setContentPane(finder);\r
-    frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
-    Desktop.addInternalFrame(frame, "Find", 340, 110);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void font_actionPerformed(ActionEvent e)\r
-  {\r
-    new FontChooser(alignPanel);\r
-  }\r
-\r
-  public void smoothFont_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.antiAlias = smoothFont.isSelected();\r
-    alignPanel.annotationPanel.image = null;\r
-    alignPanel.repaint();\r
-  }\r
-\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void seqLimit_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setShowJVSuffix(seqLimits.isSelected());\r
-\r
-    alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setColourText(colourTextMenuItem.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
-    alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
-    scaleAbove.setVisible(wrapMenuItem.isSelected());\r
-    scaleLeft.setVisible(wrapMenuItem.isSelected());\r
-    scaleRight.setVisible(wrapMenuItem.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void scaleAbove_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void scaleLeft_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void scaleRight_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setScaleRightWrapped(scaleRight.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setShowText(viewTextMenuItem.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  public void fetchSeqFeatures_actionPerformed(ActionEvent e)\r
-  {\r
-    if (!viewport.alignment.isNucleotide())\r
-    {\r
-      new SequenceFeatureFetcher(viewport.\r
-                                 alignment,\r
-                                 alignPanel);\r
-      viewport.setShowSequenceFeatures(true);\r
-      showSeqFeatures.setSelected(true);\r
-    }\r
-  }\r
-\r
-\r
-  public void featureSettings_actionPerformed(ActionEvent e)\r
-  {\r
-    new FeatureSettings(viewport, alignPanel);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param evt DOCUMENT ME!\r
-   */\r
-  public void showSeqFeatures_actionPerformed(ActionEvent evt)\r
-  {\r
-    viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());\r
-    alignPanel.repaint();\r
-    if (alignPanel.getOverviewPanel() != null)\r
-    {\r
-      alignPanel.getOverviewPanel().updateOverviewImage();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
-    alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void overviewMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    if (alignPanel.overviewPanel != null)\r
-    {\r
-      return;\r
-    }\r
-\r
-    JInternalFrame frame = new JInternalFrame();\r
-    OverviewPanel overview = new OverviewPanel(alignPanel);\r
-    frame.setContentPane(overview);\r
-    Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
-                             frame.getWidth(), frame.getHeight());\r
-    frame.pack();\r
-    frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
-    frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
-    {\r
-      public void internalFrameClosed(\r
-          javax.swing.event.InternalFrameEvent evt)\r
-      {\r
-        alignPanel.setOverviewPanel(null);\r
-      }\r
-      ;\r
-    });\r
-\r
-    alignPanel.setOverviewPanel(overview);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(null);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void clustalColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new ClustalxColourScheme(\r
-        viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void zappoColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new ZappoColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void taylorColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new TaylorColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new HydrophobicColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void helixColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new HelixColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void strandColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new StrandColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void turnColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new TurnColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void buriedColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new BuriedColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void nucleotideColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new NucleotideColourScheme());\r
-  }\r
-\r
-  public void annotationColour_actionPerformed(ActionEvent e)\r
-  {\r
-    new AnnotationColourChooser(viewport, alignPanel);\r
-  }\r
-\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param cs DOCUMENT ME!\r
-   */\r
-  void changeColour(ColourSchemeI cs)\r
-  {\r
-    int threshold = 0;\r
-\r
-    if(cs!=null)\r
-    {\r
-      if (viewport.getAbovePIDThreshold())\r
-      {\r
-        threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
-                                                   "Background");\r
-\r
-        cs.setThreshold(threshold,\r
-                        viewport.getIgnoreGapsConsensus());\r
-\r
-        viewport.setGlobalColourScheme(cs);\r
-      }\r
-      else\r
-      {\r
-        cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
-      }\r
-\r
-      if (viewport.getConservationSelected())\r
-      {\r
-\r
-        Alignment al = (Alignment) viewport.alignment;\r
-        Conservation c = new Conservation("All",\r
-                                          ResidueProperties.propHash, 3,\r
-                                          al.getSequences(), 0,\r
-                                          al.getWidth() - 1);\r
-\r
-        c.calculate();\r
-        c.verdict(false, viewport.ConsPercGaps);\r
-\r
-        cs.setConservation(c);\r
-\r
-        cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
-            "Background"));\r
-      }\r
-      else\r
-      {\r
-        cs.setConservation(null);\r
-      }\r
-\r
-      cs.setConsensus(viewport.vconsensus);\r
-    }\r
-\r
-    viewport.setGlobalColourScheme(cs);\r
-\r
-    if (viewport.getColourAppliesToAllGroups())\r
-    {\r
-      Vector groups = viewport.alignment.getGroups();\r
-\r
-      for (int i = 0; i < groups.size(); i++)\r
-      {\r
-        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
-\r
-        if (cs == null)\r
-        {\r
-          sg.cs = null;\r
-          continue;\r
-        }\r
-\r
-        if (cs instanceof ClustalxColourScheme)\r
-        {\r
-          sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
-        }\r
-        else if (cs instanceof UserColourScheme)\r
-        {\r
-          sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
-        }\r
-        else\r
-        {\r
-          try\r
-          {\r
-            sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
-          }\r
-          catch (Exception ex)\r
-          {\r
-          }\r
-        }\r
-\r
-        if (viewport.getAbovePIDThreshold()\r
-            || cs instanceof PIDColourScheme\r
-            || cs instanceof Blosum62ColourScheme)\r
-        {\r
-         sg.cs.setThreshold(threshold,\r
-                viewport.getIgnoreGapsConsensus());\r
-\r
-          sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-              sg.getWidth()));\r
-        }\r
-        else\r
-          sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
-\r
-\r
-        if (viewport.getConservationSelected())\r
-        {\r
-          Conservation c = new Conservation("Group",\r
-                                            ResidueProperties.propHash, 3,\r
-                                            sg.sequences, 0,\r
-                                            viewport.alignment.getWidth() - 1);\r
-          c.calculate();\r
-          c.verdict(false, viewport.ConsPercGaps);\r
-          sg.cs.setConservation(c);\r
-        }\r
-        else\r
-          sg.cs.setConservation(null);\r
-      }\r
-    }\r
-\r
-    if (alignPanel.getOverviewPanel() != null)\r
-    {\r
-      alignPanel.getOverviewPanel().updateOverviewImage();\r
-    }\r
-\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void modifyPID_actionPerformed(ActionEvent e)\r
-  {\r
-    if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
-    {\r
-      SliderPanel.setPIDSliderSource(alignPanel,\r
-                                     viewport.getGlobalColourScheme(),\r
-                                     "Background");\r
-      SliderPanel.showPIDSlider();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void modifyConservation_actionPerformed(ActionEvent e)\r
-  {\r
-    if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
-    {\r
-      SliderPanel.setConservationSlider(alignPanel,\r
-                                        viewport.globalColourScheme,\r
-                                        "Background");\r
-      SliderPanel.showConservationSlider();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setConservationSelected(conservationMenuItem.isSelected());\r
-\r
-    viewport.setAbovePIDThreshold(false);\r
-    abovePIDThreshold.setSelected(false);\r
-\r
-    changeColour(viewport.getGlobalColourScheme());\r
-\r
-    modifyConservation_actionPerformed(null);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
-  {\r
-    viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
-\r
-    conservationMenuItem.setSelected(false);\r
-    viewport.setConservationSelected(false);\r
-\r
-    changeColour(viewport.getGlobalColourScheme());\r
-\r
-    modifyPID_actionPerformed(null);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void userDefinedColour_actionPerformed(ActionEvent e)\r
-  {\r
-    if (e.getActionCommand().equals("User Defined..."))\r
-    {\r
-      new UserDefinedColours(alignPanel, null);\r
-    }\r
-    else\r
-    {\r
-      UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
-          getUserColourSchemes().get(e.getActionCommand());\r
-\r
-      changeColour(udc);\r
-    }\r
-  }\r
-\r
-  public void updateUserColourMenu()\r
-  {\r
-\r
-    Component[] menuItems = colourMenu.getMenuComponents();\r
-    int i, iSize = menuItems.length;\r
-    for (i = 0; i < iSize; i++)\r
-    {\r
-      if (menuItems[i].getName() != null &&\r
-          menuItems[i].getName().equals("USER_DEFINED"))\r
-      {\r
-        colourMenu.remove(menuItems[i]);\r
-        iSize--;\r
-      }\r
-    }\r
-    if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)\r
-    {\r
-      java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
-          getUserColourSchemes().keys();\r
-\r
-      while (userColours.hasMoreElements())\r
-      {\r
-        final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
-            nextElement().toString());\r
-        radioItem.setName("USER_DEFINED");\r
-        radioItem.addMouseListener(new MouseAdapter()\r
-            {\r
-              public void mousePressed(MouseEvent evt)\r
-              {\r
-                if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
-                {\r
-                  radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
-\r
-                  int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
-                      "Remove from default list?",\r
-                      "Remove user defined colour",\r
-                      JOptionPane.YES_NO_OPTION);\r
-                  if(option == JOptionPane.YES_OPTION)\r
-                  {\r
-                    jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
-                    colourMenu.remove(radioItem);\r
-                  }\r
-                  else\r
-                    radioItem.addActionListener(new ActionListener()\r
-                    {\r
-                      public void actionPerformed(ActionEvent evt)\r
-                      {\r
-                        userDefinedColour_actionPerformed(evt);\r
-                      }\r
-                    });\r
-                }\r
-              }\r
-            });\r
-        radioItem.addActionListener(new ActionListener()\r
-        {\r
-          public void actionPerformed(ActionEvent evt)\r
-          {\r
-            userDefinedColour_actionPerformed(evt);\r
-          }\r
-        });\r
-\r
-        colourMenu.insert(radioItem, 15);\r
-        colours.add(radioItem);\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void PIDColour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new PIDColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour(new Blosum62ColourScheme());\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
-                                   HistoryItem.SORT));\r
-    AlignmentSorter.sortByPID(viewport.getAlignment(),\r
-                              viewport.getAlignment().getSequenceAt(0));\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
-                                   HistoryItem.SORT));\r
-    AlignmentSorter.sortByID(viewport.getAlignment());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
-                                   HistoryItem.SORT));\r
-\r
-    AlignmentSorter.sortByGroup(viewport.getAlignment());\r
-    alignPanel.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
-    JInternalFrame frame = new JInternalFrame();\r
-    frame.setContentPane(sp);\r
-    Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
-                             100, false);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    if ( (viewport.getSelectionGroup() == null) ||\r
-        (viewport.getSelectionGroup().getSize() < 2))\r
-    {\r
-      JOptionPane.showInternalMessageDialog(this,\r
-                                            "You must select at least 2 sequences.",\r
-                                            "Invalid Selection",\r
-                                            JOptionPane.WARNING_MESSAGE);\r
-    }\r
-    else\r
-    {\r
-      JInternalFrame frame = new JInternalFrame();\r
-      frame.setContentPane(new PairwiseAlignPanel(viewport));\r
-      Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void PCAMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    if ( ( (viewport.getSelectionGroup() != null) &&\r
-          (viewport.getSelectionGroup().getSize() < 4) &&\r
-          (viewport.getSelectionGroup().getSize() > 0)) ||\r
-        (viewport.getAlignment().getHeight() < 4))\r
-    {\r
-      JOptionPane.showInternalMessageDialog(this,\r
-                                            "Principal component analysis must take\n" +\r
-                                            "at least 4 input sequences.",\r
-                                            "Sequence selection insufficient",\r
-                                            JOptionPane.WARNING_MESSAGE);\r
-\r
-      return;\r
-    }\r
-\r
-     new PCAPanel(viewport);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    NewTreePanel("AV", "PID", "Average distance tree using PID");\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param type DOCUMENT ME!\r
-   * @param pwType DOCUMENT ME!\r
-   * @param title DOCUMENT ME!\r
-   */\r
-  void NewTreePanel(String type, String pwType, String title)\r
-  {\r
-    final TreePanel tp;\r
-\r
-    if ( (viewport.getSelectionGroup() != null) &&\r
-        (viewport.getSelectionGroup().getSize() > 3))\r
-    {\r
-      int s = 0;\r
-      SequenceGroup sg = viewport.getSelectionGroup();\r
-\r
-      /* Decide if the selection is a column region */\r
-      while (s < sg.sequences.size())\r
-      {\r
-        if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
-            sg.getEndRes())\r
-        {\r
-          JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                        "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
-                                        "Try using the Pad function in the edit menu,\n" +\r
-                                        "or one of the multiple sequence alignment web services.",\r
-                                        "Sequences in selection are not aligned",\r
-                                        JOptionPane.WARNING_MESSAGE);\r
-\r
-          return;\r
-        }\r
-      }\r
-\r
-      title = title + " on region";\r
-      tp = new TreePanel(viewport,\r
-                         viewport.getSelectionGroup().sequences, type, pwType,\r
-                         sg.getStartRes(), sg.getEndRes());\r
-    }\r
-    else\r
-    {\r
-      //are the sequences aligned?\r
-      if (!viewport.alignment.isAligned())\r
-      {\r
-        JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                      "The sequences must be aligned before creating a tree.\n" +\r
-                                      "Try using the Pad function in the edit menu,\n" +\r
-                                      "or one of the multiple sequence alignment web services.",\r
-                                      "Sequences not aligned",\r
-                                      JOptionPane.WARNING_MESSAGE);\r
-\r
-        return;\r
-      }\r
-\r
-      tp = new TreePanel(viewport,\r
-                         viewport.getAlignment().getSequences(), type, pwType,\r
-                         0,\r
-                         viewport.alignment.getWidth());\r
-    }\r
-\r
-    addTreeMenuItem(tp, title);\r
-    viewport.setCurrentTree(tp.getTree());\r
-\r
-    Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param title DOCUMENT ME!\r
-   * @param order DOCUMENT ME!\r
-   */\r
-  public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
-  {\r
-    final JMenuItem item = new JMenuItem("by " + title);\r
-    sort.add(item);\r
-    item.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
-                                       HistoryItem.SORT));\r
-\r
-        // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
-        AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
-        alignPanel.repaint();\r
-      }\r
-    });\r
-  }\r
-\r
-  /**\r
-   * Maintain the Order by->Displayed Tree menu.\r
-   * Creates a new menu item for a TreePanel with an appropriate\r
-   * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added\r
-   * to remove the menu item when the treePanel is closed, and adjust\r
-   * the tree leaf to sequence mapping when the alignment is modified.\r
-   * @param treePanel Displayed tree window.\r
-   * @param title SortBy menu item title.\r
-   */\r
-  void addTreeMenuItem(final TreePanel treePanel, String title)\r
-  {\r
-    final JMenuItem item = new JMenuItem(title);\r
-\r
-    treeCount++;\r
-\r
-    if (treeCount == 1)\r
-    {\r
-      sort.add(sortByTreeMenu);\r
-    }\r
-\r
-    sortByTreeMenu.add(item);\r
-    item.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        addHistoryItem(new HistoryItem("Tree Sort",\r
-                                       viewport.alignment, HistoryItem.SORT));\r
-        AlignmentSorter.sortByTree(viewport.getAlignment(),\r
-                                   treePanel.getTree());\r
-        alignPanel.repaint();\r
-      }\r
-    });\r
-\r
-    treePanel.addInternalFrameListener(new javax.swing.event.\r
-                                       InternalFrameAdapter()\r
-    {\r
-      public void internalFrameClosed(\r
-          javax.swing.event.InternalFrameEvent evt)\r
-      {\r
-        treeCount--;\r
-        sortByTreeMenu.remove(item);\r
-\r
-        if (treeCount == 0)\r
-        {\r
-          sort.remove(sortByTreeMenu);\r
-        }\r
-      }\r
-      ;\r
-    });\r
-  }\r
-\r
-  /**\r
-   * Work out whether the whole set of sequences\r
-   * or just the selected set will be submitted for multiple alignment.\r
-   *\r
-   */\r
-  private SequenceI[] gatherSequencesForAlignment()\r
-  {\r
-    // Now, check we have enough sequences\r
-    SequenceI[] msa = null;\r
-\r
-    if ( (viewport.getSelectionGroup() != null) &&\r
-        (viewport.getSelectionGroup().getSize() > 1))\r
-    {\r
-      // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
-      SequenceGroup seqs = viewport.getSelectionGroup();\r
-      int sz;\r
-      msa = new SequenceI[sz = seqs.getSize()];\r
-\r
-      for (int i = 0; i < sz; i++)\r
-      {\r
-        msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      Vector seqs = viewport.getAlignment().getSequences();\r
-\r
-      if (seqs.size() > 1)\r
-      {\r
-        msa = new SequenceI[seqs.size()];\r
-\r
-        for (int i = 0; i < seqs.size(); i++)\r
-        {\r
-          msa[i] = (SequenceI) seqs.elementAt(i);\r
-        }\r
-      }\r
-    }\r
-    return msa;\r
-  }\r
-\r
-  /**\r
-   * Decides what is submitted to a secondary structure prediction service,\r
-   * the currently selected sequence, or the currently selected alignment\r
-   * (where the first sequence in the set is the one that the prediction\r
-   * will be for).\r
-   */\r
-  SequenceI[] gatherSeqOrMsaForSecStrPrediction()\r
-  {\r
-    SequenceI seq = null;\r
-    SequenceI[] msa = null;\r
-\r
-    if ( (viewport.getSelectionGroup() != null) &&\r
-        (viewport.getSelectionGroup().getSize() > 0))\r
-    {\r
-      // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
-      SequenceGroup seqs = viewport.getSelectionGroup();\r
-\r
-      if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
-      {\r
-        seq = (SequenceI) seqs.getSequenceAt(0);\r
-      }\r
-      else\r
-      {\r
-        int sz;\r
-        msa = new SequenceI[sz = seqs.getSize()];\r
-\r
-        for (int i = 0; i < sz; i++)\r
-        {\r
-          msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
-        }\r
-      }\r
-    }\r
-    else\r
-    {\r
-      Vector seqs = viewport.getAlignment().getSequences();\r
-\r
-      if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
-      {\r
-        seq = (SequenceI) seqs.elementAt(0);\r
-      }\r
-      else\r
-      {\r
-        msa = new SequenceI[seqs.size()];\r
-\r
-        for (int i = 0; i < seqs.size(); i++)\r
-        {\r
-          msa[i] = (SequenceI) seqs.elementAt(i);\r
-        }\r
-      }\r
-    }\r
-    if (msa != null)\r
-    {\r
-      return msa;\r
-    }\r
-    else\r
-    {\r
-      if (seq != null)\r
-      {\r
-        return new SequenceI[]\r
-            {\r
-            seq};\r
-      }\r
-    }\r
-    return null;\r
-  }\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param e DOCUMENT ME!\r
-   */\r
-  protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    // Pick the tree file\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
-        getProperty(\r
-            "LAST_DIRECTORY"));\r
-    chooser.setFileView(new JalviewFileView());\r
-    chooser.setDialogTitle("Select a newick-like tree file");\r
-    chooser.setToolTipText("Load a tree file");\r
-\r
-    int value = chooser.showOpenDialog(null);\r
-\r
-    if (value == JalviewFileChooser.APPROVE_OPTION)\r
-    {\r
-      String choice = chooser.getSelectedFile().getPath();\r
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
-\r
-      try\r
-      {\r
-        jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
-            "File");\r
-        viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                      "Problem reading tree file",\r
-                                      ex.getMessage(),\r
-                                      JOptionPane.WARNING_MESSAGE);\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-  }\r
-\r
-\r
-  public TreePanel ShowNewickTree(NewickFile nf, String title)\r
-  {\r
-    return ShowNewickTree(nf,title,600,500,4,5);\r
-  }\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param nf DOCUMENT ME!\r
-   * @param title DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public TreePanel ShowNewickTree(NewickFile nf, String title, int w,int h,int x, int y)\r
-  {\r
-    TreePanel tp = null;\r
-\r
-    try\r
-    {\r
-      nf.parse();\r
-\r
-      if (nf.getTree() != null)\r
-      {\r
-        tp = new TreePanel(viewport,\r
-                           viewport.getAlignment().getSequences(), nf,\r
-                           "FromFile",\r
-                           title);\r
-\r
-        tp.setSize(w,h);\r
-\r
-        if(x>0 && y>0)\r
-          tp.setLocation(x,y);\r
-\r
-\r
-        Desktop.addInternalFrame(tp, title, w, h);\r
-        addTreeMenuItem(tp, title);\r
-      }\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    return tp;\r
-  }\r
-\r
-  class PrintThread\r
-      extends Thread\r
-  {\r
-    public void run()\r
-    {\r
-      PrinterJob printJob = PrinterJob.getPrinterJob();\r
-      PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
-      printJob.setPrintable(alignPanel, pf);\r
-\r
-      if (printJob.printDialog())\r
-      {\r
-        try\r
-        {\r
-          printJob.print();\r
-        }\r
-        catch (Exception PrintException)\r
-        {\r
-          PrintException.printStackTrace();\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Generates menu items and listener event actions for web service clients\r
-   *\r
-   */\r
-  public void BuildWebServiceMenu()\r
-  {\r
-    if ( (Discoverer.services != null)\r
-        && (Discoverer.services.size() > 0))\r
-    {\r
-      Vector msaws = (Vector) Discoverer.services.get("MsaWS");\r
-      Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");\r
-      Vector wsmenu = new Vector();\r
-      if (msaws != null)\r
-      {\r
-        // Add any Multiple Sequence Alignment Services\r
-        final JMenu msawsmenu = new JMenu("Alignment");\r
-        for (int i = 0, j = msaws.size(); i < j; i++)\r
-        {\r
-          final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.\r
-              get(i);\r
-          final JMenuItem method = new JMenuItem(sh.getName());\r
-          method.addActionListener(new ActionListener()\r
-          {\r
-            public void actionPerformed(ActionEvent e)\r
-            {\r
-              SequenceI[] msa = gatherSequencesForAlignment();\r
-              new jalview.ws.MsaWSClient(sh, title, msa,\r
-                  false, true, viewport.getAlignment().getDataset());\r
-\r
-            }\r
-\r
-          });\r
-          msawsmenu.add(method);\r
-          // Deal with services that we know accept partial alignments.\r
-          if (sh.getName().indexOf("lustal") > -1)\r
-          {\r
-            // We know that ClustalWS can accept partial alignments for refinement.\r
-            final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");\r
-            methodR.addActionListener(new ActionListener()\r
-            {\r
-              public void actionPerformed(ActionEvent e)\r
-              {\r
-                SequenceI[] msa = gatherSequencesForAlignment();\r
-                new jalview.ws.MsaWSClient(sh, title, msa,\r
-                    true, true, viewport.getAlignment().getDataset());\r
-\r
-              }\r
-\r
-            });\r
-            msawsmenu.add(methodR);\r
-\r
-          }\r
-        }\r
-        wsmenu.add(msawsmenu);\r
-      }\r
-      if (secstrpr != null)\r
-      {\r
-        // Add any secondary structure prediction services\r
-        final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");\r
-        for (int i = 0, j = secstrpr.size(); i < j; i++)\r
-        {\r
-          final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)\r
-              secstrpr.get(i);\r
-          final JMenuItem method = new JMenuItem(sh.getName());\r
-          method.addActionListener(new ActionListener()\r
-          {\r
-            public void actionPerformed(ActionEvent e)\r
-            {\r
-              SequenceI[] msa = gatherSeqOrMsaForSecStrPrediction();\r
-              if (msa.length == 1)\r
-              {\r
-                // Single Sequence prediction\r
-                new jalview.ws.JPredClient(sh,title, msa[0]);\r
-              }\r
-              else\r
-              {\r
-                if (msa.length > 1)\r
-                {\r
-                  // Single Sequence prediction\r
-                  jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
-                      title, msa);\r
-                }\r
-              }\r
-            }\r
-          });\r
-          secstrmenu.add(method);\r
-        }\r
-        wsmenu.add(secstrmenu);\r
-      }\r
-      this.webService.removeAll();\r
-      for (int i = 0, j = wsmenu.size(); i < j; i++)\r
-      {\r
-        webService.add( (JMenu) wsmenu.get(i));\r
-      }\r
-    }\r
-    else\r
-    {\r
-      this.webService.removeAll();\r
-      this.webService.add(this.webServiceNoServices);\r
-    }\r
-    // TODO: add in rediscovery function\r
-    // TODO: reduce code redundancy.\r
-    // TODO: group services by location as well as function.\r
-  }\r
-\r
- /* public void vamsasStore_actionPerformed(ActionEvent e)\r
-  {\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
-        getProperty("LAST_DIRECTORY"));\r
-\r
-    chooser.setFileView(new JalviewFileView());\r
-    chooser.setDialogTitle("Export to Vamsas file");\r
-    chooser.setToolTipText("Export");\r
-\r
-    int value = chooser.showSaveDialog(this);\r
-\r
-    if (value == JalviewFileChooser.APPROVE_OPTION)\r
-    {\r
-      jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(viewport);\r
-      //vs.store(chooser.getSelectedFile().getAbsolutePath()   );\r
-      vs.storeJalview( chooser.getSelectedFile().getAbsolutePath(), this);\r
-    }\r
-  }*/\r
-\r
-\r
-\r
-\r
-\r
-public void showTranslation_actionPerformed(ActionEvent e)\r
-{\r
-  int s, sSize = viewport.alignment.getHeight();\r
-  SequenceI [] newSeq = new SequenceI[sSize];\r
-\r
-  int res, resSize;\r
-  StringBuffer protein;\r
-  String seq;\r
-  for(s=0; s<sSize; s++)\r
-  {\r
-    protein = new StringBuffer();\r
-    seq = AlignSeq.extractGaps("-. ", viewport.alignment.getSequenceAt(s).getSequence());\r
-    resSize = seq.length();\r
-    resSize -= resSize%3;\r
-\r
-    for(res = 0; res < resSize; res+=3)\r
-    {\r
-      String codon = seq.substring(res, res+3);\r
-      codon = codon.replace('U', 'T');\r
-      String aa = ResidueProperties.codonTranslate(codon);\r
-      if(aa==null)\r
-        protein.append(viewport.getGapCharacter());\r
-      else if(aa.equals("STOP"))\r
-        protein.append("X");\r
-      else\r
-        protein.append( aa );\r
-    }\r
-    newSeq[s] = new Sequence(viewport.alignment.getSequenceAt(s).getName(), protein.toString());\r
-  }\r
-\r
-\r
-  AlignmentI al = new Alignment(newSeq);\r
-  al.setDataset(null);\r
-\r
-\r
-  ////////////////////////////////\r
-  // Copy annotations across\r
-  jalview.datamodel.AlignmentAnnotation[] annotations\r
-      = viewport.alignment.getAlignmentAnnotation();\r
-  int a, aSize;\r
-  for (int i = 0; i < annotations.length; i++)\r
-  {\r
-\r
-    if (annotations[i].label.equals("Quality") ||\r
-        annotations[i].label.equals("Conservation") ||\r
-        annotations[i].label.equals("Consensus"))\r
-    {\r
-      continue;\r
-    }\r
-\r
-\r
-    aSize = viewport.alignment.getWidth()/3;\r
-    jalview.datamodel.Annotation [] anots =\r
-        new jalview.datamodel.Annotation[aSize];\r
-\r
-    for(a=0; a<viewport.alignment.getWidth(); a++)\r
-    {\r
-     if( annotations[i].annotations[a]==null\r
-      || annotations[i].annotations[a]==null)\r
-       continue;\r
-\r
-      anots[a/3] = new Annotation(\r
-     annotations[i].annotations[a].displayCharacter,\r
-     annotations[i].annotations[a].description,\r
-     annotations[i].annotations[a].secondaryStructure,\r
-     annotations[i].annotations[a].value,\r
-     annotations[i].annotations[a].colour);\r
-    }\r
-\r
-    jalview.datamodel.AlignmentAnnotation aa\r
-          = new jalview.datamodel.AlignmentAnnotation(annotations[i].label,\r
-       annotations[i].description, anots );\r
-     al.addAnnotation(aa);\r
-  }\r
-\r
-\r
-    AlignFrame af = new AlignFrame(al);\r
-    Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),\r
-                             NEW_WINDOW_WIDTH,\r
-                             NEW_WINDOW_HEIGHT);\r
-\r
-\r
-   // AlignViewport newViewport = new AlignViewport(al);\r
-   // AlignmentPanel ap = new AlignmentPanel(this, newViewport);\r
-   // tabbedPane.add("Protein", ap);\r
-   // viewports.add(newViewport);\r
-  //  alignPanels.add(ap);\r
-\r
-    ///Dataset tab\r
-  /////////////////////////\r
-\r
-  //  AlignViewport ds = new AlignViewport(al.getDataset());\r
-  //  ds.setDataset(true);\r
-  //  AlignmentPanel dap = new AlignmentPanel(this, ds);\r
-  //  tabbedPane.add("Dataset", dap);\r
-  //  viewports.add(ds);\r
-  //  alignPanels.add(dap);\r
-  /////////////////////////\r
-\r
-\r
-}\r
-\r
-/*public void tabSelected()\r
- {\r
-  int index = tabbedPane.getSelectedIndex();\r
-  viewport = (AlignViewport)viewports.elementAt(index);\r
-  alignPanel = (AlignmentPanel)alignPanels.elementAt(index);\r
- }*/\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @param String DOCUMENT ME!\r
- */\r
-public boolean parseGroupsFile(String file)\r
-{\r
-    String line = null;\r
-    try\r
-    {\r
-      BufferedReader in = new BufferedReader(new FileReader(file));\r
-      SequenceI seq = null;\r
-      String type, desc, token;\r
-\r
-      int index, start, end;\r
-      StringTokenizer st;\r
-      SequenceFeature sf;\r
-      int lineNo = 0;\r
-      String featureGroup = null;\r
-      while ( (line = in.readLine()) != null)\r
-      {\r
-        lineNo++;\r
-        st = new StringTokenizer(line, "\t");\r
-        if (st.countTokens() == 2)\r
-        {\r
-          type = st.nextToken();\r
-          if (type.equalsIgnoreCase("startgroup"))\r
-          {\r
-            featureGroup = st.nextToken();\r
-          }\r
-          else if (type.equalsIgnoreCase("endgroup"))\r
-          {\r
-            //We should check whether this is the current group,\r
-            //but at present theres no way of showing more than 1 group\r
-            st.nextToken();\r
-            featureGroup = null;\r
-          }\r
-          else\r
-          {\r
-            UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
-            alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(type,\r
-                ucs.findColour("A"));\r
-          }\r
-          continue;\r
-        }\r
-\r
-        while (st.hasMoreElements())\r
-        {\r
-          desc = st.nextToken();\r
-          token = st.nextToken();\r
-          if (!token.equals("ID_NOT_SPECIFIED"))\r
-          {\r
-            index = viewport.alignment.findIndex(viewport.alignment.findName(token));\r
-            st.nextToken();\r
-          }\r
-          else\r
-          {\r
-            index = Integer.parseInt(st.nextToken());\r
-          }\r
-\r
-          start = Integer.parseInt(st.nextToken());\r
-          end = Integer.parseInt(st.nextToken());\r
-\r
-          seq = viewport.alignment.getSequenceAt(index);\r
-\r
-          type = st.nextToken();\r
-\r
-          if (alignPanel.seqPanel.seqCanvas.getFeatureRenderer().getColour(type) == null)\r
-          {\r
-            // Probably the old style groups file\r
-            UserColourScheme ucs = new UserColourScheme(type);\r
-            alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(type, ucs.findColour("A"));\r
-          }\r
-\r
-          sf = new SequenceFeature(type, desc, "", start, end, featureGroup);\r
-\r
-          seq.getDatasetSequence().addSequenceFeature(sf);\r
-        }\r
-      }\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      System.out.println(line);\r
-      ex.printStackTrace();\r
-      System.out.println("Error parsing groups file: " + ex +"\n"+line);\r
-      return false;\r
-    }\r
-\r
-    viewport.showSequenceFeatures = true;\r
-    showSeqFeatures.setSelected(true);\r
-    alignPanel.repaint();\r
-    return true;\r
-}\r
-\r
-public void dragEnter(DropTargetDragEvent evt)\r
-{}\r
-\r
-public void dragExit(DropTargetEvent evt)\r
-{}\r
-\r
-public void dragOver(DropTargetDragEvent evt)\r
-{}\r
-\r
-public void dropActionChanged(DropTargetDragEvent evt)\r
-{}\r
-\r
-public void drop(DropTargetDropEvent evt)\r
-{\r
-    Transferable t = evt.getTransferable();\r
-    java.util.List files = null;\r
-\r
-    try\r
-    {\r
-      DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");\r
-      if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))\r
-      {\r
-        //Works on Windows and MacOSX\r
-        evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
-        files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);\r
-      }\r
-      else if (t.isDataFlavorSupported(uriListFlavor))\r
-      {\r
-        // This is used by Unix drag system\r
-        evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
-        String data = (String) t.getTransferData(uriListFlavor);\r
-        files = new java.util.ArrayList(1);\r
-        for (java.util.StringTokenizer st = new java.util.StringTokenizer(\r
-            data,\r
-            "\r\n");\r
-             st.hasMoreTokens(); )\r
-        {\r
-          String s = st.nextToken();\r
-          if (s.startsWith("#"))\r
-          {\r
-            // the line is a comment (as per the RFC 2483)\r
-            continue;\r
-          }\r
-\r
-          java.net.URI uri = new java.net.URI(s);\r
-          java.io.File file = new java.io.File(uri);\r
-          files.add(file);\r
-        }\r
-      }\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-    if (files != null)\r
-    {\r
-      try\r
-      {\r
-\r
-        for (int i = 0; i < files.size(); i++)\r
-        {\r
-          loadJalviewDataFile(files.get(i).toString());\r
-        }\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-}\r
-\r
-  // This method will attempt to load a "dropped" file first by testing\r
-  // whether its and Annotation file, then group file. If both are\r
-  // false then the user may have dropped an alignment file onto this\r
-  // AlignFrame\r
-   void loadJalviewDataFile(String file)\r
-  {\r
-    try{\r
-      boolean isAnnotation = new AnnotationReader().readAnnotationFile(viewport.\r
-          alignment, file);\r
-\r
-      if (!isAnnotation)\r
-      {\r
-        boolean isGroupsFile = parseGroupsFile(file);\r
-        if (!isGroupsFile)\r
-        {\r
-          String protocol = "File";\r
-          String format = new IdentifyFile().Identify(file, protocol);\r
-          SequenceI[] sequences = new FormatAdapter().readFile(file, protocol,\r
-              format);\r
-\r
-          FastaFile ff = new FastaFile();\r
-          Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
-          c.setContents(new StringSelection(ff.print(sequences)), this);\r
-\r
-          this.paste(false);\r
-        }\r
-      }\r
-\r
-      if (isAnnotation)\r
-      {\r
-        int height = alignPanel.annotationPanel.adjustPanelHeight();\r
-        alignPanel.annotationScroller.setPreferredSize(\r
-            new Dimension(alignPanel.annotationScroller.getWidth(),\r
-                          height));\r
-\r
-        alignPanel.annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
-            alignPanel.annotationSpaceFillerHolder.getWidth(),\r
-            height));\r
-\r
-        alignPanel.addNotify();\r
-      }\r
-\r
-    }catch(Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Softwarechang
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import java.beans.*;
+import java.io.*;
+import java.util.*;
+
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.event.*;
+import java.awt.print.*;
+import javax.swing.*;
+
+import jalview.analysis.*;
+import jalview.datamodel.*;
+import jalview.io.*;
+import jalview.jbgui.*;
+import jalview.schemes.*;
+import jalview.util.ShiftList;
+import jalview.ws.*;
+import java.awt.dnd.*;
+import org.biojava.dasobert.eventmodel.*;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AlignFrame
+    extends GAlignFrame implements DropTargetListener, FeatureListener
+{
+  /** DOCUMENT ME!! */
+  public static final int NEW_WINDOW_WIDTH = 700;
+
+  /** DOCUMENT ME!! */
+  public static final int NEW_WINDOW_HEIGHT = 500;
+  AlignmentPanel alignPanel;
+  AlignViewport viewport;
+
+  // Vector viewports = new Vector();
+  // Vector alignPanels = new Vector();
+  /** DOCUMENT ME!! */
+  public String currentFileFormat = null;
+  Stack historyList = new Stack();
+  Stack redoList = new Stack();
+  private int treeCount = 0;
+
+  /**
+   * new alignment window with hidden columns
+   * @param al AlignmentI
+   * @param hiddenColumns ColumnSelection or null
+   */
+  public AlignFrame(AlignmentI al, ColumnSelection hiddenColumns) {
+
+    viewport = new AlignViewport(al, hiddenColumns);
+
+    this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
+
+    if(viewport.vconsensus==null)
+    {
+      //Out of memory calculating consensus.
+      BLOSUM62Colour.setEnabled(false);
+      PIDColour.setEnabled(false);
+      conservationMenuItem.setEnabled(false);
+      modifyConservation.setEnabled(false);
+      abovePIDThreshold.setEnabled(false);
+      modifyPID.setEnabled(false);
+    }
+
+    alignPanel = new AlignmentPanel(this, viewport);
+
+    String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT", "No sort");
+
+    if(sortby.equals("Id"))
+      sortIDMenuItem_actionPerformed(null);
+    else if(sortby.equals("Pairwise Identity"))
+      sortPairwiseMenuItem_actionPerformed(null);
+
+   // remove(tabbedPane);
+    getContentPane().add(alignPanel, BorderLayout.CENTER);
+
+
+
+  //  tabbedPane.add(al.isNucleotide() ? "DNA":"Protein", alignPanel);
+
+    ///Dataset tab
+    /////////////////////////
+    if(al.getDataset()==null)
+    {
+      al.setDataset(null);
+    }
+   // AlignViewport ds = new AlignViewport(al.getDataset(), true);
+   // AlignmentPanel dap = new AlignmentPanel(this, ds);
+  //  tabbedPane.add("Dataset", dap);
+  //  viewports.add(ds);
+  //  alignPanels.add(dap);
+    /////////////////////////
+
+
+    viewport.addPropertyChangeListener(new PropertyChangeListener()
+    {
+     public void propertyChange(PropertyChangeEvent evt)
+     {
+       if (evt.getPropertyName().equals("alignment"))
+       {
+         alignmentChanged();
+       }
+     }
+   });
+
+
+    if (Desktop.desktop != null)
+    {
+      addServiceListeners();
+      setGUINucleotide(al.isNucleotide());
+    }
+
+
+    if (jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false))
+    {
+      wrapMenuItem.setSelected(true);
+      wrapMenuItem_actionPerformed(null);
+    }
+
+  }
+
+
+  /**
+   * Creates a new AlignFrame object.
+   *
+   * @param al DOCUMENT ME!
+   */
+  public AlignFrame(AlignmentI al)
+  {
+    this(al, null);
+  }
+
+  public AlignViewport getViewport()
+  {
+    return viewport;
+  }
+
+  /* Set up intrinsic listeners for dynamically generated GUI bits. */
+  private void addServiceListeners()
+  {
+    final java.beans.PropertyChangeListener thisListener;
+    // Do this once to get current state
+    BuildWebServiceMenu();
+    Desktop.discoverer.addPropertyChangeListener(
+        thisListener = new java.beans.PropertyChangeListener()
+    {
+      public void propertyChange(PropertyChangeEvent evt)
+      {
+        // System.out.println("Discoverer property change.");
+        if (evt.getPropertyName().equals("services"))
+        {
+          // System.out.println("Rebuilding web service menu");
+          BuildWebServiceMenu();
+        }
+      }
+    });
+    addInternalFrameListener(new javax.swing.event.
+                             InternalFrameAdapter()
+    {
+      public void internalFrameClosed(
+          javax.swing.event.InternalFrameEvent evt)
+      {
+        // System.out.println("deregistering discoverer listener");
+        Desktop.discoverer.removePropertyChangeListener(thisListener);
+        closeMenuItem_actionPerformed(null);
+      }
+      ;
+    });
+  }
+
+  public void setGUINucleotide(boolean nucleotide)
+  {
+    showTranslation.setVisible( nucleotide );
+    //sequenceFeatures.setVisible(!nucleotide );
+    //featureSettings.setVisible( !nucleotide );
+    conservationMenuItem.setVisible( !nucleotide );
+    modifyConservation.setVisible(   !nucleotide );
+
+    //Remember AlignFrame always starts as protein
+    if(!nucleotide)
+    {
+      calculateMenu.remove(calculateMenu.getItemCount()-2);
+    }
+  }
+
+  public void comeBackLater(FeatureEvent evt)
+  {}
+
+  public void newFeatures(FeatureEvent evt)
+  {
+    if (evt.getFeatures().length > 0)
+    {
+      alignPanel.seqPanel.seqCanvas.fr.featuresAdded();
+      alignPanel.repaint();
+    }
+  }
+
+  Hashtable progressBars;
+  public void setProgressBar(String message, long id)
+  {
+    if(progressBars == null)
+      progressBars = new Hashtable();
+
+    JPanel progressPanel;
+    GridLayout layout = (GridLayout) statusPanel.getLayout();
+    if(progressBars.get( new Long(id) )!=null)
+     {
+       progressPanel = (JPanel)progressBars.get( new Long(id) );
+       statusPanel.remove(progressPanel);
+       progressBars.remove( progressPanel );
+       progressPanel = null;
+       if(message!=null)
+         statusBar.setText(message);
+
+       layout.setRows(layout.getRows() - 1);
+     }
+    else
+    {
+      progressPanel = new JPanel(new BorderLayout(10, 5));
+
+      JProgressBar progressBar = new JProgressBar();
+      progressBar.setIndeterminate(true);
+
+      progressPanel.add(new JLabel(message), BorderLayout.WEST);
+      progressPanel.add(progressBar, BorderLayout.CENTER);
+
+      layout.setRows(layout.getRows() + 1);
+      statusPanel.add(progressPanel);
+
+      progressBars.put(new Long(id), progressPanel);
+    }
+
+    validate();
+  }
+
+
+  /*
+   Added so Castor Mapping file can obtain Jalview Version
+  */
+  public String getVersion()
+  {
+    return  jalview.bin.Cache.getProperty("VERSION");
+  }
+
+  public FeatureRenderer getFeatureRenderer()
+  {
+    return alignPanel.seqPanel.seqCanvas.getFeatureRenderer();
+  }
+
+
+  public void fetchSequence_actionPerformed(ActionEvent e)
+  {
+    new SequenceFetcher(this);
+  }
+
+  public void addFromFile_actionPerformed(ActionEvent e)
+  {
+    Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
+  }
+
+  public void addFromText_actionPerformed(ActionEvent e)
+  {
+    Desktop.instance.inputTextboxMenuItem_actionPerformed(viewport);
+  }
+
+  public void addFromURL_actionPerformed(ActionEvent e)
+  {
+    Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void saveAlignmentMenu_actionPerformed(ActionEvent e)
+  {
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+        getProperty( "LAST_DIRECTORY"),
+        new String[]
+        { "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc","jar" },
+        new String[]
+        { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview" },
+        currentFileFormat,
+        false);
+
+
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle("Save Alignment to file");
+    chooser.setToolTipText("Save");
+
+    int value = chooser.showSaveDialog(this);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+        currentFileFormat = chooser.getSelectedFormat();
+
+        if (currentFileFormat == null)
+        {
+          JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                                "You must select a file format before saving!",
+                                                "File format not specified",
+                                                JOptionPane.WARNING_MESSAGE);
+          value = chooser.showSaveDialog(this);
+          return;
+        }
+
+      jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",
+                                    currentFileFormat);
+
+      String choice = chooser.getSelectedFile().getPath();
+      jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
+
+      saveAlignment(choice, currentFileFormat);
+    }
+  }
+
+  public boolean saveAlignment(String file, String format)
+  {
+    if (format.equalsIgnoreCase("Jalview"))
+    {
+      String shortName = title;
+
+      if (shortName.indexOf(java.io.File.separatorChar) > -1)
+      {
+        shortName = shortName.substring(shortName.lastIndexOf(
+            java.io.File.separatorChar) + 1);
+      }
+
+      new Jalview2XML().SaveAlignment(this, file, shortName);
+
+      // USE Jalview2XML to save this file
+      return true;
+    }
+    else
+    {
+
+      String[] omitHidden = null;
+
+      if (viewport.hasHiddenColumns)
+      {
+        int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+            "The Alignment contains hidden columns."
+            + "\nDo you want to save only the visible alignment?",
+            "Save / Omit Hidden Columns",
+            JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+
+        if (reply == JOptionPane.YES_OPTION)
+          omitHidden = viewport.getViewAsString(false);
+      }
+
+      String output = new FormatAdapter().formatSequences(
+          format,
+          viewport.alignment.getSequencesArray(),
+          omitHidden);
+
+      if (output == null)
+      {
+        return false;
+      }
+
+      try
+      {
+        java.io.PrintWriter out = new java.io.PrintWriter(
+            new java.io.FileWriter(file));
+
+        out.print(output);
+        out.close();
+        this.setTitle(file);
+        return true;
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void outputText_actionPerformed(ActionEvent e)
+  {
+    String [] omitHidden = null;
+
+    if(viewport.hasHiddenColumns)
+    {
+      int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+          "The Alignment contains hidden columns."
+      +"\nDo you want to output only the visible alignment?",
+      "Save / Omit Hidden Columns",
+      JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+
+      if(reply==JOptionPane.YES_OPTION)
+      {
+        omitHidden = viewport.getViewAsString(false);
+      }
+    }
+
+    CutAndPasteTransfer cap = new CutAndPasteTransfer();
+    Desktop.addInternalFrame(cap,
+                             "Alignment output - " + e.getActionCommand(), 600,
+                             500);
+
+
+    cap.setText(new FormatAdapter().formatSequences(
+        e.getActionCommand(),
+        viewport.alignment.getSequencesArray(),
+        omitHidden));
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void htmlMenuItem_actionPerformed(ActionEvent e)
+  {
+    new HTMLOutput(viewport,
+                   alignPanel.seqPanel.seqCanvas.getSequenceRenderer(),
+        alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
+  }
+
+  public void createImageMap(File file, String image)
+  {
+    alignPanel.makePNGImageMap(file, image);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void createPNG(File f)
+  {
+    alignPanel.makePNG(f);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void createEPS(File f)
+  {
+    alignPanel.makeEPS(f);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void printMenuItem_actionPerformed(ActionEvent e)
+  {
+    //Putting in a thread avoids Swing painting problems
+    PrintThread thread = new PrintThread();
+    thread.start();
+  }
+
+  public void exportFeatures_actionPerformed(ActionEvent e)
+  {
+    new AnnotationExporter().exportFeatures(alignPanel);
+  }
+
+
+  public void exportAnnotations_actionPerformed(ActionEvent e)
+  {
+    new AnnotationExporter().exportAnnotations(
+      alignPanel,
+      viewport.alignment.getAlignmentAnnotation()
+        );
+  }
+
+
+  public void associatedData_actionPerformed(ActionEvent e)
+  {
+    // Pick the tree file
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+        getProperty(
+            "LAST_DIRECTORY"));
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle("Load Jalview Annotations or Features File");
+    chooser.setToolTipText("Load Jalview Annotations / Features file");
+
+    int value = chooser.showOpenDialog(null);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+      String choice = chooser.getSelectedFile().getPath();
+      jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
+      loadJalviewDataFile(choice);
+    }
+
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void closeMenuItem_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      PaintRefresher.components.remove(viewport.alignment);
+      this.setClosed(true);
+    }
+    catch (Exception ex)
+    {
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  void updateEditMenuBar()
+  {
+    if (historyList.size() > 0)
+    {
+      undoMenuItem.setEnabled(true);
+
+      HistoryItem hi = (HistoryItem) historyList.peek();
+      undoMenuItem.setText("Undo " + hi.getDescription());
+    }
+    else
+    {
+      undoMenuItem.setEnabled(false);
+      undoMenuItem.setText("Undo");
+    }
+
+    if (redoList.size() > 0)
+    {
+      redoMenuItem.setEnabled(true);
+
+      HistoryItem hi = (HistoryItem) redoList.peek();
+      redoMenuItem.setText("Redo " + hi.getDescription());
+    }
+    else
+    {
+      redoMenuItem.setEnabled(false);
+      redoMenuItem.setText("Redo");
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param hi DOCUMENT ME!
+   */
+  public void addHistoryItem(HistoryItem hi)
+  {
+    historyList.push(hi);
+    redoList.clear();
+    updateEditMenuBar();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void undoMenuItem_actionPerformed(ActionEvent e)
+  {
+    HistoryItem nh,hi = (HistoryItem) historyList.pop();
+    redoList.push(nh=new HistoryItem(hi.getDescription(), viewport.alignment,
+                                  HistoryItem.HIDE));
+    if (hi.alColumnChanges!=null)
+      nh.alColumnChanges = hi.alColumnChanges.getInverse();
+    restoreHistoryItem(hi);
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void redoMenuItem_actionPerformed(ActionEvent e)
+  {
+    HistoryItem nh,hi = (HistoryItem) redoList.pop();
+    historyList.push(nh=new HistoryItem(hi.getDescription(), viewport.alignment,
+        HistoryItem.HIDE));
+    if (hi.alColumnChanges!=null)
+      nh.alColumnChanges=hi.alColumnChanges.getInverse();
+    restoreHistoryItem(hi);
+    updateEditMenuBar();
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  // used by undo and redo
+  void restoreHistoryItem(HistoryItem hi)
+  {
+
+    hi.restore(viewport.getColumnSelection());
+
+    updateEditMenuBar();
+
+    viewport.firePropertyChange("alignment", null,
+                                viewport.getAlignment().getSequences());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param up DOCUMENT ME!
+   */
+  public void moveSelectedSequences(boolean up)
+  {
+    SequenceGroup sg = viewport.getSelectionGroup();
+
+    if (sg == null)
+    {
+      return;
+    }
+
+    if (up)
+    {
+      for (int i = 1; i < viewport.alignment.getHeight(); i++)
+      {
+        SequenceI seq = viewport.alignment.getSequenceAt(i);
+
+        if (!sg.getSequences(false).contains(seq))
+        {
+          continue;
+        }
+
+        SequenceI temp = viewport.alignment.getSequenceAt(i - 1);
+
+        if (sg.getSequences(false).contains(temp))
+        {
+          continue;
+        }
+
+        viewport.alignment.getSequences().setElementAt(temp, i);
+        viewport.alignment.getSequences().setElementAt(seq, i - 1);
+      }
+    }
+    else
+    {
+      for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)
+      {
+        SequenceI seq = viewport.alignment.getSequenceAt(i);
+
+        if (!sg.getSequences(false).contains(seq))
+        {
+          continue;
+        }
+
+        SequenceI temp = viewport.alignment.getSequenceAt(i + 1);
+
+        if (sg.getSequences(false).contains(temp))
+        {
+          continue;
+        }
+
+        viewport.alignment.getSequences().setElementAt(temp, i);
+        viewport.alignment.getSequences().setElementAt(seq, i + 1);
+      }
+    }
+
+    alignPanel.repaint();
+  }
+
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void copy_actionPerformed(ActionEvent e)
+  {
+    if (viewport.getSelectionGroup() == null)
+    {
+      return;
+    }
+
+    SequenceI [] seqs = viewport.getSelectionAsNewSequence();
+    String[] omitHidden = null;
+
+    if (viewport.hasHiddenColumns)
+    {
+      omitHidden = viewport.getViewAsString(true);
+    }
+
+    String output = new FormatAdapter().formatSequences(
+        "Fasta",
+        seqs,
+        omitHidden);
+
+
+    Toolkit.getDefaultToolkit().getSystemClipboard()
+        .setContents(new StringSelection(output), Desktop.instance);
+
+    Vector hiddenColumns = null;
+    if(viewport.hasHiddenColumns)
+    {
+      hiddenColumns =new Vector();
+      int hiddenOffset = viewport.getSelectionGroup().getStartRes();
+      for(int i=0; i<viewport.getColumnSelection().getHiddenColumns().size(); i++)
+      {
+        int[] region = (int[])
+            viewport.getColumnSelection().getHiddenColumns().elementAt(i);
+
+        hiddenColumns.addElement(new int[]{region[0]-hiddenOffset,
+                          region[1]-hiddenOffset});
+      }
+    }
+
+    Desktop.jalviewClipboard = new Object[]{ seqs,
+        viewport.alignment.getDataset(),
+        hiddenColumns};
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void pasteNew_actionPerformed(ActionEvent e)
+  {
+    paste(true);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void pasteThis_actionPerformed(ActionEvent e)
+  {
+    addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,
+                                   HistoryItem.PASTE));
+    paste(false);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param newAlignment DOCUMENT ME!
+   */
+  void paste(boolean newAlignment)
+  {
+    try
+    {
+      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
+      Transferable contents = c.getContents(this);
+
+      if (contents == null)
+      {
+        return;
+      }
+
+      String str = (String) contents.getTransferData(DataFlavor.stringFlavor);
+      if(str.length()<1)
+        return;
+
+      String format = new IdentifyFile().Identify(str, "Paste");
+      SequenceI[] sequences;
+
+
+     if(Desktop.jalviewClipboard!=null)
+     {
+       // The clipboard was filled from within Jalview, we must use the sequences
+       // And dataset from the copied alignment
+       sequences = (SequenceI[])Desktop.jalviewClipboard[0];
+     }
+     else
+     {
+       sequences = new FormatAdapter().readFile(str, "Paste", format);
+     }
+
+     AlignmentI alignment = null;
+
+      if (newAlignment)
+      {
+        alignment = new Alignment(sequences);
+
+        if(Desktop.jalviewClipboard!=null)
+           alignment.setDataset( (Alignment)Desktop.jalviewClipboard[1] );
+        else
+           alignment.setDataset( null );
+
+      }
+      else
+      {
+        alignment = viewport.getAlignment();
+
+        //!newAlignment
+        for (int i = 0; i < sequences.length; i++)
+        {
+          Sequence newseq = new Sequence(sequences[i].getName(),
+              sequences[i].getSequence(), sequences[i].getStart(),
+              sequences[i].getEnd());
+
+          alignment.addSequence(newseq);
+        }
+
+
+        viewport.setEndSeq(alignment.getHeight());
+        alignment.getWidth();
+        viewport.firePropertyChange("alignment", null, alignment.getSequences());
+      }
+
+
+
+
+
+      // Add any annotations attached to sequences
+      for (int i = 0; i < sequences.length; i++)
+     {
+       if (sequences[i].getAnnotation() != null)
+       {
+         for (int a = 0; a < sequences[i].getAnnotation().length; a++)
+         {
+           AlignmentAnnotation newAnnot =
+               new AlignmentAnnotation(
+                   sequences[i].getAnnotation()[a].label,
+                   sequences[i].getAnnotation()[a].description,
+                   sequences[i].getAnnotation()[a].annotations,
+                   sequences[i].getAnnotation()[a].graphMin,
+                   sequences[i].getAnnotation()[a].graphMax,
+                   sequences[i].getAnnotation()[a].graph);
+
+           sequences[i].getAnnotation()[a] = newAnnot;
+           newAnnot.sequenceMapping = sequences[i].getAnnotation()[a].
+               sequenceMapping;
+           newAnnot.sequenceRef = sequences[i];
+           newAnnot.adjustForAlignment();
+           alignment.addAnnotation(newAnnot);
+           alignment.setAnnotationIndex(newAnnot, a);
+         }
+
+         alignPanel.annotationPanel.adjustPanelHeight();
+       }
+     }
+
+     if(newAlignment)
+     {
+       AlignFrame af = new AlignFrame(alignment);
+       String newtitle = new String("Copied sequences");
+
+       if(Desktop.jalviewClipboard!=null && Desktop.jalviewClipboard[2]!=null)
+         {
+           Vector hc = (Vector)Desktop.jalviewClipboard[2];
+           for(int i=0; i<hc.size(); i++)
+           {
+             int [] region = (int[]) hc.elementAt(i);
+             af.viewport.hideColumns(region[0], region[1]);
+           }
+         }
+
+
+       //>>>This is a fix for the moment, until a better solution is found!!<<<
+       af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().transferSettings(
+           alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
+
+
+       if (title.startsWith("Copied sequences"))
+       {
+         newtitle = title;
+       }
+       else
+       {
+         newtitle = newtitle.concat("- from " + title);
+       }
+
+       Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,
+                                NEW_WINDOW_HEIGHT);
+
+     }
+
+
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+        System.out.println("Exception whilst pasting: "+ex);
+        // could be anything being pasted in here
+    }
+
+
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void cut_actionPerformed(ActionEvent e)
+  {
+    copy_actionPerformed(null);
+    delete_actionPerformed(null);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void delete_actionPerformed(ActionEvent e)
+  {
+
+    if (viewport.getSelectionGroup() == null)
+    {
+      return;
+    }
+
+
+    SequenceGroup sg = viewport.getSelectionGroup();
+
+
+
+    //Jalview no longer allows deletion of residues.
+    //Check here whether any residues are in selection area
+   /* if( sg.getEndRes()-sg.getStartRes() < viewport.alignment.getWidth()-1)
+    {
+      for (int i = 0; i < sg.sequences.size(); i++)
+      {
+        SequenceI seq = sg.getSequenceAt(i);
+        int j = sg.getStartRes();
+        do
+        {
+          if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))
+          {
+            JOptionPane.showInternalMessageDialog(
+                Desktop.desktop, "Cannot delete residues from alignment!\n"
+                + "Try hiding columns instead.",
+                "Deletion of residues not permitted",
+                JOptionPane.WARNING_MESSAGE);
+
+            return;
+          }
+          j++;
+        }while(j<=sg.getEndRes());
+      }
+    }*/
+
+
+    addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,
+                                   HistoryItem.HIDE));
+
+
+    for (int i = 0; i < sg.getSize(false); i++)
+    {
+      SequenceI seq = sg.getSequenceAt(i);
+      int index = viewport.getAlignment().findIndex(seq);
+
+      seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);
+
+      // If the cut affects all sequences, remove highlighted columns
+      if (sg.getSize(false) == viewport.alignment.getHeight())
+      {
+        viewport.getColumnSelection().removeElements(sg.getStartRes(),
+            sg.getEndRes() + 1);
+      }
+
+      if (seq.getSequence().length() < 1)
+      {
+        viewport.getAlignment().deleteSequence(seq);
+      }
+      else
+      {
+        viewport.getAlignment().getSequences().setElementAt(seq, index);
+      }
+    }
+
+    viewport.setSelectionGroup(null);
+    viewport.alignment.deleteGroup(sg);
+
+    viewport.firePropertyChange("alignment", null,
+                                  viewport.getAlignment().getSequences());
+
+
+
+    if (viewport.getAlignment().getHeight() < 1)
+    {
+      try
+      {
+        this.setClosed(true);
+      }
+      catch (Exception ex)
+      {
+      }
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void deleteGroups_actionPerformed(ActionEvent e)
+  {
+    viewport.alignment.deleteAllGroups();
+    viewport.setSelectionGroup(null);
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
+  {
+    SequenceGroup sg = new SequenceGroup();
+
+    for (int i = 0; i < viewport.getAlignment().getSequences().size();
+         i++)
+    {
+      sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
+    }
+
+    sg.setEndRes(viewport.alignment.getWidth() - 1);
+    viewport.setSelectionGroup(sg);
+    PaintRefresher.Refresh(null, viewport.alignment);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
+  {
+    if(viewport.cursorMode)
+    {
+      alignPanel.seqPanel.keyboardNo1 = null;
+      alignPanel.seqPanel.keyboardNo2 = null;
+    }
+    viewport.setSelectionGroup(null);
+    viewport.getColumnSelection().clear();
+    viewport.setSelectionGroup(null);
+    alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
+    alignPanel.idPanel.idCanvas.searchResults = null;
+    alignPanel.repaint();
+    PaintRefresher.Refresh(null, viewport.alignment);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
+  {
+    SequenceGroup sg = viewport.getSelectionGroup();
+
+    if (sg == null)
+    {
+      selectAllSequenceMenuItem_actionPerformed(null);
+
+      return;
+    }
+
+    for (int i = 0; i < viewport.getAlignment().getSequences().size();
+         i++)
+    {
+      sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
+    }
+
+    PaintRefresher.Refresh(null, viewport.alignment);
+  }
+
+  public void invertColSel_actionPerformed(ActionEvent e)
+  {
+    viewport.invertColumnSelection();
+    alignPanel.repaint();
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
+  {
+    ColumnSelection colSel = viewport.getColumnSelection();
+
+    if (colSel.size() > 0)
+    {
+      HistoryItem edit;
+      addHistoryItem(edit=new HistoryItem("Remove Left", viewport.alignment,
+                                     HistoryItem.HIDE));
+
+      int min = colSel.getMin();
+      viewport.getAlignment().trimLeft(min);
+      colSel.compensateForEdit(0, min);
+      edit.addShift(0,min);
+      if (viewport.getSelectionGroup() != null)
+      {
+        viewport.getSelectionGroup().adjustForRemoveLeft(min);
+      }
+
+      Vector groups = viewport.alignment.getGroups();
+
+      for (int i = 0; i < groups.size(); i++)
+      {
+        SequenceGroup sg = (SequenceGroup) groups.get(i);
+
+        if (!sg.adjustForRemoveLeft(min))
+        {
+          viewport.alignment.deleteGroup(sg);
+        }
+      }
+
+      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void remove2RightMenuItem_actionPerformed(ActionEvent e)
+  {
+    ColumnSelection colSel = viewport.getColumnSelection();
+
+    if (colSel.size() > 0)
+    {
+      addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,
+                                     HistoryItem.HIDE));
+
+      int max = colSel.getMax();
+      viewport.getAlignment().trimRight(max);
+      // TODO: delete hidden column entries in colSel to right of max
+      // TODO: record hidden columns in history for undo.
+      if (viewport.getSelectionGroup() != null)
+      {
+        viewport.getSelectionGroup().adjustForRemoveRight(max);
+      }
+
+      Vector groups = viewport.alignment.getGroups();
+
+      for (int i = 0; i < groups.size(); i++)
+      {
+        SequenceGroup sg = (SequenceGroup) groups.get(i);
+
+        if (!sg.adjustForRemoveRight(max))
+        {
+          viewport.alignment.deleteGroup(sg);
+        }
+      }
+
+      viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
+  {
+    HistoryItem edit;
+    addHistoryItem(edit=new HistoryItem("Remove Gapped Columns",
+                                   viewport.alignment, HistoryItem.HIDE));
+
+    //This is to maintain viewport position on first residue
+    //of first sequence
+    SequenceI seq = viewport.alignment.getSequenceAt(0);
+    int startRes = seq.findPosition(viewport.startRes);
+    ShiftList shifts;
+    viewport.getAlignment().removeGaps(shifts=new ShiftList());
+    edit.alColumnChanges=shifts.getInverse();
+    if (viewport.hasHiddenColumns)
+      viewport.getColumnSelection().compensateForEdits(shifts);
+    viewport.setStartRes(seq.findIndex(startRes)-1);
+   viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
+  {
+    // TODO: hidden regions should not be touched by removeAllGaps - a minimal number of gaps will remain in alignment segments containing uneven length subsequences
+    // TODO: columnSelection.compensateforedits should be called (and passed to history item)
+    addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,
+                                   HistoryItem.HIDE));
+
+    //This is to maintain viewport position on first residue
+    //of first sequence
+    SequenceI seq = viewport.alignment.getSequenceAt(0);
+    int startRes = seq.findPosition(viewport.startRes);
+
+
+    SequenceI current;
+    int jSize;
+
+    Vector seqs = null;
+
+    int start = 0;
+    int end = viewport.alignment.getWidth();
+
+    if (viewport.getSelectionGroup() != null
+        && viewport.getSelectionGroup().getSequences(true) != null
+        && viewport.getSelectionGroup().getSize(true) > 0)
+    {
+      seqs = viewport.getSelectionGroup().getSequences(true);
+      start = viewport.getSelectionGroup().getStartRes();
+      end = viewport.getSelectionGroup().getEndRes()+1;
+    }
+    else
+    {
+      seqs = viewport.alignment.getSequences();
+    }
+    /* Commented out regions below are partial implementation of todo above.
+       * divide start,end into visible chunks, and for each:
+      int diff=end-start+1;
+      int diffmax=0;
+      int dr[] = new int[seqs.size()];
+      */
+     for (int i = 0; i < seqs.size(); i++)
+     {
+       current = (SequenceI) seqs.elementAt(i);
+       //dr[i]=
+       current.removeGaps(start, end);
+       /*if (d<diff) // can only shift
+         diff=d;
+       if (diffmax<d)
+         diffmax=d;
+         */
+     }
+     /* // after the end of each chunk -
+      * if (diff>0) {
+      // record shift for history.
+       editgaps.addShift(start, diff);
+       if (viewport.hasHiddenColumns && diffmax>diff) {
+       // pad sequence
+        StringBuffer gaps=new StringBuffer(diffmax);
+        for (int i=0,j=diffmax-diff; i<j; i++)
+        gaps.append(viewport.getGapCharacter());
+        for (int i=0, j=seqs.size(); i<j; i++) {
+        current = (SequenceI) seqs.elementAt(i);
+        if (dr[i]-diff>0) {
+        String sq = current.getSequence();
+        current.setSequence(sq.substring(0, hcend-dr[i])+gaps.substring(0, dr[i]-diff)+sq.substring());
+        }
+        }
+       }
+       }*/
+
+    viewport.setStartRes(seq.findIndex(startRes)-1);
+
+    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+  }
+
+ public void alignmentChanged()
+ {
+   if(viewport.padGaps)
+     viewport.getAlignment().padGaps();
+
+   if(viewport.vconsensus!=null && viewport.autoCalculateConsensus)
+   {
+     viewport.updateConsensus();
+     viewport.updateConservation();
+   }
+
+   resetAllColourSchemes();
+   if(alignPanel.overviewPanel!=null)
+     alignPanel.overviewPanel.updateOverviewImage();
+
+   viewport.alignment.adjustSequenceAnnotations();
+
+   if(alignPanel.overviewPanel!=null)
+     alignPanel.overviewPanel.updateOverviewImage();
+   // JBPNote: could push a vamsas document update here.
+   alignPanel.repaint();
+ }
+
+  void resetAllColourSchemes()
+  {
+    ColourSchemeI cs = viewport.globalColourScheme;
+    if(cs!=null)
+    {
+      if (cs instanceof ClustalxColourScheme)
+      {
+        ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).
+            resetClustalX(viewport.alignment.getSequences(),
+                          viewport.alignment.getWidth());
+      }
+
+      cs.setConsensus(viewport.vconsensus);
+      if (cs.conservationApplied())
+      {
+        Alignment al = (Alignment) viewport.alignment;
+        Conservation c = new Conservation("All",
+                                          ResidueProperties.propHash, 3,
+                                          al.getSequences(), 0,
+                                          al.getWidth() - 1);
+        c.calculate();
+        c.verdict(false, viewport.ConsPercGaps);
+
+        cs.setConservation(c);
+      }
+    }
+
+    int s, sSize = viewport.alignment.getGroups().size();
+    for(s=0; s<sSize; s++)
+    {
+      SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);
+      if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)
+      {
+        ((ClustalxColourScheme)sg.cs).resetClustalX(
+            sg.getSequences(true), sg.getWidth());
+      }
+      sg.recalcConservation();
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void padGapsMenuitem_actionPerformed(ActionEvent e)
+  {
+    addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,
+                                   HistoryItem.HIDE));
+
+    viewport.padGaps = padGapsMenuitem.isSelected();
+
+   // if (viewport.padGaps)
+    alignmentChanged();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void findMenuItem_actionPerformed(ActionEvent e)
+  {
+    JInternalFrame frame = new JInternalFrame();
+    Finder finder = new Finder(viewport, alignPanel, frame);
+    frame.setContentPane(finder);
+    frame.setLayer(JLayeredPane.PALETTE_LAYER);
+    Desktop.addInternalFrame(frame, "Find", 340, 110);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void font_actionPerformed(ActionEvent e)
+  {
+    new FontChooser(alignPanel);
+  }
+
+  public void smoothFont_actionPerformed(ActionEvent e)
+  {
+    viewport.antiAlias = smoothFont.isSelected();
+    alignPanel.annotationPanel.image = null;
+    alignPanel.repaint();
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void seqLimit_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowJVSuffix(seqLimits.isSelected());
+
+    alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());
+    alignPanel.repaint();
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void colourTextMenuItem_actionPerformed(ActionEvent e)
+  {
+    viewport.setColourText(colourTextMenuItem.isSelected());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void wrapMenuItem_actionPerformed(ActionEvent e)
+  {
+    scaleAbove.setVisible(wrapMenuItem.isSelected());
+    scaleLeft.setVisible(wrapMenuItem.isSelected());
+    scaleRight.setVisible(wrapMenuItem.isSelected());
+    viewport.setWrapAlignment(wrapMenuItem.isSelected());
+    alignPanel.setWrapAlignment(wrapMenuItem.isSelected());
+  }
+
+  public void showAllSeqs_actionPerformed(ActionEvent e)
+  {
+    viewport.showAllHiddenSeqs();
+  }
+
+  public void showAllColumns_actionPerformed(ActionEvent e)
+  {
+    viewport.showAllHiddenColumns();
+    repaint();
+  }
+
+  public void hideSelSequences_actionPerformed(ActionEvent e)
+  {
+    viewport.hideAllSelectedSeqs();
+  }
+
+  public void hideSelColumns_actionPerformed(ActionEvent e)
+  {
+    viewport.hideSelectedColumns();
+    alignPanel.repaint();
+  }
+
+  public void hiddenMarkers_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
+    repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void scaleAbove_actionPerformed(ActionEvent e)
+  {
+    viewport.setScaleAboveWrapped(scaleAbove.isSelected());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void scaleLeft_actionPerformed(ActionEvent e)
+  {
+    viewport.setScaleLeftWrapped(scaleLeft.isSelected());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void scaleRight_actionPerformed(ActionEvent e)
+  {
+    viewport.setScaleRightWrapped(scaleRight.isSelected());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void viewTextMenuItem_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowText(viewTextMenuItem.isSelected());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
+  {
+    viewport.setRenderGaps(renderGapsMenuItem.isSelected());
+    alignPanel.repaint();
+  }
+
+
+  public FeatureSettings featureSettings;
+  public void featureSettings_actionPerformed(ActionEvent e)
+  {
+    if(featureSettings !=null )
+    {
+      featureSettings.close();
+      featureSettings = null;
+    }
+    featureSettings = new FeatureSettings(this);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param evt DOCUMENT ME!
+   */
+  public void showSeqFeatures_actionPerformed(ActionEvent evt)
+  {
+    viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
+    alignPanel.repaint();
+    if (alignPanel.getOverviewPanel() != null)
+    {
+      alignPanel.getOverviewPanel().updateOverviewImage();
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
+  {
+    viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());
+    alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void overviewMenuItem_actionPerformed(ActionEvent e)
+  {
+    if (alignPanel.overviewPanel != null)
+    {
+      return;
+    }
+
+    JInternalFrame frame = new JInternalFrame();
+    OverviewPanel overview = new OverviewPanel(alignPanel);
+    frame.setContentPane(overview);
+    Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),
+                             frame.getWidth(), frame.getHeight());
+    frame.pack();
+    frame.setLayer(JLayeredPane.PALETTE_LAYER);
+    frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+    {
+      public void internalFrameClosed(
+          javax.swing.event.InternalFrameEvent evt)
+      {
+        alignPanel.setOverviewPanel(null);
+      }
+      ;
+    });
+
+    alignPanel.setOverviewPanel(overview);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void noColourmenuItem_actionPerformed(ActionEvent e)
+  {
+    changeColour(null);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void clustalColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new ClustalxColourScheme(
+        viewport.alignment.getSequences(), viewport.alignment.getWidth()));
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void zappoColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new ZappoColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void taylorColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new TaylorColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void hydrophobicityColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new HydrophobicColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void helixColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new HelixColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void strandColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new StrandColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void turnColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new TurnColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void buriedColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new BuriedColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void nucleotideColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new NucleotideColourScheme());
+  }
+
+  public void annotationColour_actionPerformed(ActionEvent e)
+  {
+    new AnnotationColourChooser(viewport, alignPanel);
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void applyToAllGroups_actionPerformed(ActionEvent e)
+  {
+    viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param cs DOCUMENT ME!
+   */
+  public void changeColour(ColourSchemeI cs)
+  {
+    int threshold = 0;
+
+    if(cs!=null)
+    {
+      if (viewport.getAbovePIDThreshold())
+      {
+        threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
+                                                   "Background");
+
+        cs.setThreshold(threshold,
+                        viewport.getIgnoreGapsConsensus());
+
+        viewport.setGlobalColourScheme(cs);
+      }
+      else
+      {
+        cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
+      }
+
+      if (viewport.getConservationSelected())
+      {
+
+        Alignment al = (Alignment) viewport.alignment;
+        Conservation c = new Conservation("All",
+                                          ResidueProperties.propHash, 3,
+                                          al.getSequences(), 0,
+                                          al.getWidth() - 1);
+
+        c.calculate();
+        c.verdict(false, viewport.ConsPercGaps);
+
+        cs.setConservation(c);
+
+        cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,
+            "Background"));
+      }
+      else
+      {
+        cs.setConservation(null);
+      }
+
+      cs.setConsensus(viewport.vconsensus);
+    }
+
+    viewport.setGlobalColourScheme(cs);
+
+    if (viewport.getColourAppliesToAllGroups())
+    {
+      Vector groups = viewport.alignment.getGroups();
+
+      for (int i = 0; i < groups.size(); i++)
+      {
+        SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+
+        if (cs == null)
+        {
+          sg.cs = null;
+          continue;
+        }
+
+        if (cs instanceof ClustalxColourScheme)
+        {
+          sg.cs = new ClustalxColourScheme(
+              sg.getSequences(true), sg.getWidth());
+        }
+        else if (cs instanceof UserColourScheme)
+        {
+          sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());
+        }
+        else
+        {
+          try
+          {
+            sg.cs = (ColourSchemeI) cs.getClass().newInstance();
+          }
+          catch (Exception ex)
+          {
+          }
+        }
+
+        if (viewport.getAbovePIDThreshold()
+            || cs instanceof PIDColourScheme
+            || cs instanceof Blosum62ColourScheme)
+        {
+         sg.cs.setThreshold(threshold,
+                viewport.getIgnoreGapsConsensus());
+
+         sg.cs.setConsensus(AAFrequency.calculate(
+             sg.getSequences(true), 0,
+             sg.getWidth()));
+       }
+        else
+          sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
+
+
+        if (viewport.getConservationSelected())
+        {
+          Conservation c = new Conservation("Group",
+                                            ResidueProperties.propHash, 3,
+                                            sg.getSequences(true), 0,
+                                            viewport.alignment.getWidth() - 1);
+          c.calculate();
+          c.verdict(false, viewport.ConsPercGaps);
+          sg.cs.setConservation(c);
+        }
+        else
+          sg.cs.setConservation(null);
+      }
+    }
+
+    if (alignPanel.getOverviewPanel() != null)
+    {
+      alignPanel.getOverviewPanel().updateOverviewImage();
+    }
+
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void modifyPID_actionPerformed(ActionEvent e)
+  {
+    if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)
+    {
+      SliderPanel.setPIDSliderSource(alignPanel,
+                                     viewport.getGlobalColourScheme(),
+                                     "Background");
+      SliderPanel.showPIDSlider();
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void modifyConservation_actionPerformed(ActionEvent e)
+  {
+    if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)
+    {
+      SliderPanel.setConservationSlider(alignPanel,
+                                        viewport.globalColourScheme,
+                                        "Background");
+      SliderPanel.showConservationSlider();
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void conservationMenuItem_actionPerformed(ActionEvent e)
+  {
+    viewport.setConservationSelected(conservationMenuItem.isSelected());
+
+    viewport.setAbovePIDThreshold(false);
+    abovePIDThreshold.setSelected(false);
+
+    changeColour(viewport.getGlobalColourScheme());
+
+    modifyConservation_actionPerformed(null);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void abovePIDThreshold_actionPerformed(ActionEvent e)
+  {
+    viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());
+
+    conservationMenuItem.setSelected(false);
+    viewport.setConservationSelected(false);
+
+    changeColour(viewport.getGlobalColourScheme());
+
+    modifyPID_actionPerformed(null);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void userDefinedColour_actionPerformed(ActionEvent e)
+  {
+    if (e.getActionCommand().equals("User Defined..."))
+    {
+      new UserDefinedColours(alignPanel, null);
+    }
+    else
+    {
+      UserColourScheme udc = (UserColourScheme) UserDefinedColours.
+          getUserColourSchemes().get(e.getActionCommand());
+
+      changeColour(udc);
+    }
+  }
+
+  public void updateUserColourMenu()
+  {
+
+    Component[] menuItems = colourMenu.getMenuComponents();
+    int i, iSize = menuItems.length;
+    for (i = 0; i < iSize; i++)
+    {
+      if (menuItems[i].getName() != null &&
+          menuItems[i].getName().equals("USER_DEFINED"))
+      {
+        colourMenu.remove(menuItems[i]);
+        iSize--;
+      }
+    }
+    if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
+    {
+      java.util.Enumeration userColours = jalview.gui.UserDefinedColours.
+          getUserColourSchemes().keys();
+
+      while (userColours.hasMoreElements())
+      {
+        final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.
+            nextElement().toString());
+        radioItem.setName("USER_DEFINED");
+        radioItem.addMouseListener(new MouseAdapter()
+            {
+              public void mousePressed(MouseEvent evt)
+              {
+                if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))
+                {
+                  radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+                  int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,
+                      "Remove from default list?",
+                      "Remove user defined colour",
+                      JOptionPane.YES_NO_OPTION);
+                  if(option == JOptionPane.YES_OPTION)
+                  {
+                    jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());
+                    colourMenu.remove(radioItem);
+                  }
+                  else
+                    radioItem.addActionListener(new ActionListener()
+                    {
+                      public void actionPerformed(ActionEvent evt)
+                      {
+                        userDefinedColour_actionPerformed(evt);
+                      }
+                    });
+                }
+              }
+            });
+        radioItem.addActionListener(new ActionListener()
+        {
+          public void actionPerformed(ActionEvent evt)
+          {
+            userDefinedColour_actionPerformed(evt);
+          }
+        });
+
+        colourMenu.insert(radioItem, 15);
+        colours.add(radioItem);
+      }
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void PIDColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new PIDColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void BLOSUM62Colour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new Blosum62ColourScheme());
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
+  {
+    addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,
+                                   HistoryItem.SORT));
+    AlignmentSorter.sortByPID(viewport.getAlignment(),
+                              viewport.getAlignment().getSequenceAt(0));
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void sortIDMenuItem_actionPerformed(ActionEvent e)
+  {
+    addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,
+                                   HistoryItem.SORT));
+    AlignmentSorter.sortByID(viewport.getAlignment());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void sortGroupMenuItem_actionPerformed(ActionEvent e)
+  {
+    addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,
+                                   HistoryItem.SORT));
+
+    AlignmentSorter.sortByGroup(viewport.getAlignment());
+    alignPanel.repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
+  {
+    new RedundancyPanel(alignPanel, this);
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
+  {
+    if ( (viewport.getSelectionGroup() == null) ||
+        (viewport.getSelectionGroup().getSize(false) < 2))
+    {
+      JOptionPane.showInternalMessageDialog(this,
+                                            "You must select at least 2 sequences.",
+                                            "Invalid Selection",
+                                            JOptionPane.WARNING_MESSAGE);
+    }
+    else
+    {
+      JInternalFrame frame = new JInternalFrame();
+      frame.setContentPane(new PairwiseAlignPanel(viewport));
+      Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void PCAMenuItem_actionPerformed(ActionEvent e)
+  {
+    if ( ( (viewport.getSelectionGroup() != null) &&
+          (viewport.getSelectionGroup().getSize(false) < 4) &&
+          (viewport.getSelectionGroup().getSize(false) > 0)) ||
+        (viewport.getAlignment().getHeight() < 4))
+    {
+      JOptionPane.showInternalMessageDialog(this,
+                                            "Principal component analysis must take\n" +
+                                            "at least 4 input sequences.",
+                                            "Sequence selection insufficient",
+                                            JOptionPane.WARNING_MESSAGE);
+
+      return;
+    }
+
+     new PCAPanel(viewport);
+  }
+
+
+  public void autoCalculate_actionPerformed(ActionEvent e)
+  {
+    viewport.autoCalculateConsensus = autoCalculate.isSelected();
+    if(viewport.autoCalculateConsensus)
+    {
+      alignmentChanged();
+    }
+  }
+
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
+  {
+    NewTreePanel("AV", "PID", "Average distance tree using PID");
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
+  {
+    NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
+  {
+    NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
+  {
+    NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param type DOCUMENT ME!
+   * @param pwType DOCUMENT ME!
+   * @param title DOCUMENT ME!
+   */
+  void NewTreePanel(String type, String pwType, String title)
+  {
+    TreePanel tp;
+
+    if ( (viewport.getSelectionGroup() != null) &&
+        (viewport.getSelectionGroup().getSize(false) > 3))
+    {
+      int s = 0;
+      SequenceGroup sg = viewport.getSelectionGroup();
+
+      /* Decide if the selection is a column region */
+      while (s < sg.getSize(false))
+      {
+        if ( ( (SequenceI) sg.getSequences(false).elementAt(s++)).getLength() <
+            sg.getEndRes())
+        {
+          JOptionPane.showMessageDialog(Desktop.desktop,
+                                        "The selected region to create a tree may\nonly contain residues or gaps.\n" +
+                                        "Try using the Pad function in the edit menu,\n" +
+                                        "or one of the multiple sequence alignment web services.",
+                                        "Sequences in selection are not aligned",
+                                        JOptionPane.WARNING_MESSAGE);
+
+          return;
+        }
+      }
+
+      title = title + " on region";
+      tp = new TreePanel(viewport, type, pwType);
+    }
+    else
+    {
+      //are the sequences aligned?
+      if (!viewport.alignment.isAligned())
+      {
+        JOptionPane.showMessageDialog(Desktop.desktop,
+                                      "The sequences must be aligned before creating a tree.\n" +
+                                      "Try using the Pad function in the edit menu,\n" +
+                                      "or one of the multiple sequence alignment web services.",
+                                      "Sequences not aligned",
+                                      JOptionPane.WARNING_MESSAGE);
+
+        return;
+      }
+
+      if(viewport.alignment.getHeight()<2)
+        return;
+
+      tp = new TreePanel(viewport, type, pwType);
+    }
+
+    addTreeMenuItem(tp, title);
+
+    Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param title DOCUMENT ME!
+   * @param order DOCUMENT ME!
+   */
+  public void addSortByOrderMenuItem(String title, final AlignmentOrder order)
+  {
+    final JMenuItem item = new JMenuItem("by " + title);
+    sort.add(item);
+    item.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        addHistoryItem(new HistoryItem("Sort", viewport.alignment,
+                                       HistoryItem.SORT));
+
+        // TODO: JBPNote - have to map order entries to curent SequenceI pointers
+        AlignmentSorter.sortBy(viewport.getAlignment(), order);
+        alignPanel.repaint();
+      }
+    });
+  }
+
+  /**
+   * Maintain the Order by->Displayed Tree menu.
+   * Creates a new menu item for a TreePanel with an appropriate
+   * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added
+   * to remove the menu item when the treePanel is closed, and adjust
+   * the tree leaf to sequence mapping when the alignment is modified.
+   * @param treePanel Displayed tree window.
+   * @param title SortBy menu item title.
+   */
+  void addTreeMenuItem(final TreePanel treePanel, String title)
+  {
+    final JMenuItem item = new JMenuItem(title);
+
+    treeCount++;
+
+    if (treeCount == 1)
+    {
+      sort.add(sortByTreeMenu);
+    }
+
+    sortByTreeMenu.add(item);
+    item.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        addHistoryItem(new HistoryItem("Tree Sort",
+                                       viewport.alignment, HistoryItem.SORT));
+        AlignmentSorter.sortByTree(viewport.getAlignment(),
+                                   treePanel.getTree());
+        alignPanel.repaint();
+      }
+    });
+
+    treePanel.addInternalFrameListener(new javax.swing.event.
+                                       InternalFrameAdapter()
+    {
+      public void internalFrameClosed(
+          javax.swing.event.InternalFrameEvent evt)
+      {
+        treeCount--;
+        sortByTreeMenu.remove(item);
+
+        if (treeCount == 0)
+        {
+          sort.remove(sortByTreeMenu);
+        }
+      }
+      ;
+    });
+  }
+
+  /**
+   * Work out whether the whole set of sequences
+   * or just the selected set will be submitted for multiple alignment.
+   *
+   */
+  private jalview.datamodel.AlignmentView gatherSequencesForAlignment()
+  {
+    // Now, check we have enough sequences
+    AlignmentView msa = null;
+
+    if ( (viewport.getSelectionGroup() != null) &&
+        (viewport.getSelectionGroup().getSize(false) > 1))
+    {
+      // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!
+      /*SequenceGroup seqs = viewport.getSelectionGroup();
+      int sz;
+      msa = new SequenceI[sz = seqs.getSize(false)];
+
+      for (int i = 0; i < sz; i++)
+      {
+        msa[i] = (SequenceI) seqs.getSequenceAt(i);
+      } */
+      msa = viewport.getAlignmentView(true);
+    }
+    else
+    {
+      /*Vector seqs = viewport.getAlignment().getSequences();
+
+      if (seqs.size() > 1)
+      {
+        msa = new SequenceI[seqs.size()];
+
+        for (int i = 0; i < seqs.size(); i++)
+        {
+          msa[i] = (SequenceI) seqs.elementAt(i);
+        }
+      }*/
+      msa = viewport.getAlignmentView(false);
+    }
+    return msa;
+  }
+
+  /**
+   * Decides what is submitted to a secondary structure prediction service,
+   * the currently selected sequence, or the currently selected alignment
+   * (where the first sequence in the set is the one that the prediction
+   * will be for).
+   */
+  AlignmentView gatherSeqOrMsaForSecStrPrediction()
+  {
+   AlignmentView seqs = null;
+
+    if ( (viewport.getSelectionGroup() != null) &&
+        (viewport.getSelectionGroup().getSize(false) > 0))
+    {
+      seqs = viewport.getAlignmentView(true);
+    }
+    else
+    {
+      seqs = viewport.getAlignmentView(false);
+    }
+    // limit sequences - JBPNote in future - could spawn multiple prediction jobs
+    // TODO: viewport.alignment.isAligned is a global state - the local selection may well be aligned - we preserve 2.0.8 behaviour for moment.
+    if (!viewport.alignment.isAligned())
+    {
+      seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] } );
+    }
+    return seqs;
+  }
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)
+  {
+    // Pick the tree file
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+        getProperty(
+            "LAST_DIRECTORY"));
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle("Select a newick-like tree file");
+    chooser.setToolTipText("Load a tree file");
+
+    int value = chooser.showOpenDialog(null);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+      String choice = chooser.getSelectedFile().getPath();
+      jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
+
+      try
+      {
+        jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,
+            "File");
+        viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());
+      }
+      catch (Exception ex)
+      {
+        JOptionPane.showMessageDialog(Desktop.desktop,
+                                      "Problem reading tree file",
+                                      ex.getMessage(),
+                                      JOptionPane.WARNING_MESSAGE);
+        ex.printStackTrace();
+      }
+    }
+  }
+
+
+  public TreePanel ShowNewickTree(NewickFile nf, String title)
+  {
+    return ShowNewickTree(nf,title,600,500,4,5);
+  }
+  /**
+   * DOCUMENT ME!
+   *
+   * @param nf DOCUMENT ME!
+   * @param title DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public TreePanel ShowNewickTree(NewickFile nf, String title, int w,int h,int x, int y)
+  {
+    TreePanel tp = null;
+
+    try
+    {
+      nf.parse();
+
+      if (nf.getTree() != null)
+      {
+        tp = new TreePanel(viewport,
+                           "FromFile",
+                           title,
+                           nf);
+
+        tp.setSize(w,h);
+
+        if(x>0 && y>0)
+          tp.setLocation(x,y);
+
+
+        Desktop.addInternalFrame(tp, title, w, h);
+        addTreeMenuItem(tp, title);
+      }
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    return tp;
+  }
+
+  class PrintThread
+      extends Thread
+  {
+    public void run()
+    {
+      PrinterJob printJob = PrinterJob.getPrinterJob();
+      PageFormat pf = printJob.pageDialog(printJob.defaultPage());
+      printJob.setPrintable(alignPanel, pf);
+
+      if (printJob.printDialog())
+      {
+        try
+        {
+          printJob.print();
+        }
+        catch (Exception PrintException)
+        {
+          PrintException.printStackTrace();
+        }
+      }
+    }
+  }
+
+  /**
+   * Generates menu items and listener event actions for web service clients
+   *
+   */
+  public void BuildWebServiceMenu()
+  {
+    if ( (Discoverer.services != null)
+        && (Discoverer.services.size() > 0))
+    {
+      Vector msaws = (Vector) Discoverer.services.get("MsaWS");
+      Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");
+      Vector wsmenu = new Vector();
+      final AlignFrame af = this;
+      if (msaws != null)
+      {
+        // Add any Multiple Sequence Alignment Services
+        final JMenu msawsmenu = new JMenu("Alignment");
+        for (int i = 0, j = msaws.size(); i < j; i++)
+        {
+          final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.
+              get(i);
+          final JMenuItem method = new JMenuItem(sh.getName());
+          method.addActionListener(new ActionListener()
+          {
+            public void actionPerformed(ActionEvent e)
+            {
+              AlignmentView msa = gatherSequencesForAlignment();
+              new jalview.ws.MsaWSClient(sh, title, msa,
+                  false, true, viewport.getAlignment().getDataset(), af);
+
+            }
+
+          });
+          msawsmenu.add(method);
+          // Deal with services that we know accept partial alignments.
+          if (sh.getName().indexOf("lustal") > -1)
+          {
+            // We know that ClustalWS can accept partial alignments for refinement.
+            final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");
+            methodR.addActionListener(new ActionListener()
+            {
+              public void actionPerformed(ActionEvent e)
+              {
+                AlignmentView msa = gatherSequencesForAlignment();
+                new jalview.ws.MsaWSClient(sh, title, msa,
+                    true, true, viewport.getAlignment().getDataset(), af);
+
+              }
+
+            });
+            msawsmenu.add(methodR);
+
+          }
+        }
+        wsmenu.add(msawsmenu);
+      }
+      if (secstrpr != null)
+      {
+        // Add any secondary structure prediction services
+        final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");
+        for (int i = 0, j = secstrpr.size(); i < j; i++)
+        {
+          final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)
+              secstrpr.get(i);
+          final JMenuItem method = new JMenuItem(sh.getName());
+          method.addActionListener(new ActionListener()
+          {
+            public void actionPerformed(ActionEvent e)
+            {
+              AlignmentView msa = gatherSeqOrMsaForSecStrPrediction();
+              if (msa.getSequences().length == 1)
+              {
+                // Single Sequence prediction
+                new jalview.ws.JPredClient(sh, title, false, msa, af);
+              }
+              else
+              {
+                if (msa.getSequences().length > 1)
+                {
+                  // Sequence profile based prediction
+                  new jalview.ws.JPredClient(sh,
+                      title, true, msa, af);
+                }
+              }
+            }
+          });
+          secstrmenu.add(method);
+        }
+        wsmenu.add(secstrmenu);
+      }
+      this.webService.removeAll();
+      for (int i = 0, j = wsmenu.size(); i < j; i++)
+      {
+        webService.add( (JMenu) wsmenu.get(i));
+      }
+    }
+    else
+    {
+      this.webService.removeAll();
+      this.webService.add(this.webServiceNoServices);
+    }
+    // TODO: add in rediscovery function
+    // TODO: reduce code redundancy.
+    // TODO: group services by location as well as function.
+  }
+
+ /* public void vamsasStore_actionPerformed(ActionEvent e)
+  {
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+        getProperty("LAST_DIRECTORY"));
+
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle("Export to Vamsas file");
+    chooser.setToolTipText("Export");
+
+    int value = chooser.showSaveDialog(this);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+      jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(viewport);
+      //vs.store(chooser.getSelectedFile().getAbsolutePath()   );
+      vs.storeJalview( chooser.getSelectedFile().getAbsolutePath(), this);
+    }
+  }*/
+
+
+
+
+public void showTranslation_actionPerformed(ActionEvent e)
+{
+  SequenceI [] selection = viewport.getSelectionAsNewSequence();
+  String [] seqstring = viewport.getViewAsString(true);
+
+  int s, sSize = selection.length;
+  SequenceI [] newSeq = new SequenceI[sSize];
+
+  int res, resSize;
+  StringBuffer protein;
+  String seq;
+  for(s=0; s<sSize; s++)
+  {
+    protein = new StringBuffer();
+    seq = AlignSeq.extractGaps("-. ", seqstring[s]);
+    resSize = seq.length();
+    resSize -= resSize%3;
+
+    for(res = 0; res < resSize; res+=3)
+    {
+      String codon = seq.substring(res, res+3);
+      codon = codon.replace('U', 'T');
+      String aa = ResidueProperties.codonTranslate(codon);
+      if(aa==null)
+        protein.append(viewport.getGapCharacter());
+      else if(aa.equals("STOP"))
+        protein.append("X");
+      else
+        protein.append( aa );
+    }
+    newSeq[s] = new Sequence(selection[s].getName(),
+                             protein.toString());
+  }
+
+
+  AlignmentI al = new Alignment(newSeq);
+  al.setDataset(null);
+
+
+  ////////////////////////////////
+  // Copy annotations across
+  jalview.datamodel.AlignmentAnnotation[] annotations
+      = viewport.alignment.getAlignmentAnnotation();
+  int a, aSize;
+  if(annotations!=null)
+  {
+    for (int i = 0; i < annotations.length; i++)
+    {
+      if (annotations[i].label.equals("Quality") ||
+          annotations[i].label.equals("Conservation") ||
+          annotations[i].label.equals("Consensus"))
+      {
+        continue;
+      }
+
+      aSize = viewport.alignment.getWidth() / 3;
+      jalview.datamodel.Annotation[] anots =
+          new jalview.datamodel.Annotation[aSize];
+
+      for (a = 0; a < viewport.alignment.getWidth(); a++)
+      {
+        if (annotations[i].annotations[a] == null
+            || annotations[i].annotations[a] == null)
+          continue;
+
+        anots[a / 3] = new Annotation(
+            annotations[i].annotations[a].displayCharacter,
+            annotations[i].annotations[a].description,
+            annotations[i].annotations[a].secondaryStructure,
+            annotations[i].annotations[a].value,
+            annotations[i].annotations[a].colour);
+      }
+
+      jalview.datamodel.AlignmentAnnotation aa
+          = new jalview.datamodel.AlignmentAnnotation(annotations[i].label,
+          annotations[i].description, anots);
+      al.addAnnotation(aa);
+    }
+  }
+
+    AlignFrame af = new AlignFrame(al);
+    Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),
+                             NEW_WINDOW_WIDTH,
+                             NEW_WINDOW_HEIGHT);
+
+
+   // AlignViewport newViewport = new AlignViewport(al);
+   // AlignmentPanel ap = new AlignmentPanel(this, newViewport);
+   // tabbedPane.add("Protein", ap);
+   // viewports.add(newViewport);
+  //  alignPanels.add(ap);
+
+    ///Dataset tab
+  /////////////////////////
+
+  //  AlignViewport ds = new AlignViewport(al.getDataset());
+  //  ds.setDataset(true);
+  //  AlignmentPanel dap = new AlignmentPanel(this, ds);
+  //  tabbedPane.add("Dataset", dap);
+  //  viewports.add(ds);
+  //  alignPanels.add(dap);
+  /////////////////////////
+
+
+}
+
+/*public void tabSelected()
+ {
+  int index = tabbedPane.getSelectedIndex();
+  viewport = (AlignViewport)viewports.elementAt(index);
+  alignPanel = (AlignmentPanel)alignPanels.elementAt(index);
+ }*/
+
+/**
+ * DOCUMENT ME!
+ *
+ * @param String DOCUMENT ME!
+ */
+public boolean parseFeaturesFile(String file, String type)
+{
+    boolean featuresFile = false;
+    try{
+      featuresFile = new FeaturesFile(file, type).parse(viewport.alignment.getDataset(),
+                                         alignPanel.seqPanel.seqCanvas.
+                                         getFeatureRenderer().featureColours,
+                                         false);
+    }
+    catch(Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    if(featuresFile)
+    {
+      viewport.showSequenceFeatures = true;
+      showSeqFeatures.setSelected(true);
+      alignPanel.repaint();
+    }
+
+    return featuresFile;
+}
+
+public void dragEnter(DropTargetDragEvent evt)
+{}
+
+public void dragExit(DropTargetEvent evt)
+{}
+
+public void dragOver(DropTargetDragEvent evt)
+{}
+
+public void dropActionChanged(DropTargetDragEvent evt)
+{}
+
+public void drop(DropTargetDropEvent evt)
+{
+    Transferable t = evt.getTransferable();
+    java.util.List files = null;
+
+    try
+    {
+      DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
+      if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+      {
+        //Works on Windows and MacOSX
+        evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+        files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);
+      }
+      else if (t.isDataFlavorSupported(uriListFlavor))
+      {
+        // This is used by Unix drag system
+        evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+        String data = (String) t.getTransferData(uriListFlavor);
+        files = new java.util.ArrayList(1);
+        for (java.util.StringTokenizer st = new java.util.StringTokenizer(
+            data,
+            "\r\n");
+             st.hasMoreTokens(); )
+        {
+          String s = st.nextToken();
+          if (s.startsWith("#"))
+          {
+            // the line is a comment (as per the RFC 2483)
+            continue;
+          }
+
+          java.net.URI uri = new java.net.URI(s);
+          java.io.File file = new java.io.File(uri);
+          files.add(file);
+        }
+      }
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    if (files != null)
+    {
+      try
+      {
+
+        for (int i = 0; i < files.size(); i++)
+        {
+          loadJalviewDataFile(files.get(i).toString());
+        }
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+}
+
+  // This method will attempt to load a "dropped" file first by testing
+  // whether its and Annotation file, then features file. If both are
+  // false then the user may have dropped an alignment file onto this
+  // AlignFrame
+   public void loadJalviewDataFile(String file)
+  {
+    try{
+      String protocol = "File";
+
+      if (file.indexOf("http:") > -1 || file.indexOf("file:") > -1)
+      {
+        protocol = "URL";
+      }
+
+      boolean isAnnotation = new AnnotationFile().readAnnotationFile(viewport.
+          alignment, file);
+
+      if (!isAnnotation)
+      {
+        boolean isGroupsFile = parseFeaturesFile(file,protocol);
+        if (!isGroupsFile)
+        {
+          String format = new IdentifyFile().Identify(file, protocol);
+
+          if(format.equalsIgnoreCase("JnetFile"))
+          {
+            jalview.io.JPredFile predictions = new jalview.io.JPredFile(
+                file, protocol);
+            new JnetAnnotationMaker().add_annotation(predictions,
+                viewport.getAlignment(),
+                0, false);
+            alignPanel.adjustAnnotationHeight();
+            alignPanel.repaint();
+          }
+          else
+            new FileLoader().LoadFile(viewport, file, protocol, format);
+        }
+      }
+      else
+      {
+        // (isAnnotation)
+        alignPanel.adjustAnnotationHeight();
+      }
+
+    }catch(Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+}
index a92517c..5edb65b 100755 (executable)
- /*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.bin.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AlignViewport\r
-{\r
-    int startRes;\r
-    int endRes;\r
-    int startSeq;\r
-    int endSeq;\r
-    boolean showJVSuffix = true;\r
-    boolean showText = true;\r
-    boolean showColourText = false;\r
-    boolean showBoxes = true;\r
-    boolean wrapAlignment = false;\r
-    boolean renderGaps = true;\r
-    boolean showSequenceFeatures = false;\r
-    boolean showAnnotation = true;\r
-    boolean showConservation = true;\r
-    boolean showQuality = true;\r
-    boolean showIdentity = true;\r
-    boolean colourAppliesToAllGroups = true;\r
-    ColourSchemeI globalColourScheme = null;\r
-    boolean conservationColourSelected = false;\r
-    boolean abovePIDThreshold = false;\r
-    SequenceGroup selectionGroup;\r
-    int charHeight;\r
-    int charWidth;\r
-    int wrappedWidth;\r
-    Font font = new Font("SansSerif", Font.PLAIN, 10);\r
-    AlignmentI alignment;\r
-    ColumnSelection colSel = new ColumnSelection();\r
-    int threshold;\r
-    int increment;\r
-    NJTree currentTree = null;\r
-    boolean scaleAboveWrapped = false;\r
-    boolean scaleLeftWrapped = true;\r
-    boolean scaleRightWrapped = true;\r
-    boolean hasHiddenColumns = false;\r
-    boolean hasHiddenRows = false;\r
-\r
-    boolean cursorMode = false;\r
-\r
-    // The following vector holds the features which are\r
-    // currently visible, in the correct order or rendering\r
-    Hashtable featuresDisplayed = null;\r
-\r
-\r
-    /** DOCUMENT ME!! */\r
-    public Vector vconsensus;\r
-    AlignmentAnnotation consensus;\r
-    AlignmentAnnotation conservation;\r
-    AlignmentAnnotation quality;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
-\r
-    // JBPNote Prolly only need this in the applet version.\r
-    private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);\r
-\r
-    boolean ignoreGapsInConsensusCalculation = false;\r
-\r
-    boolean isDataset = false;\r
-\r
-    boolean antiAlias = false;\r
-\r
-\r
-    public AlignViewport(AlignmentI al, boolean dataset)\r
-    {\r
-      isDataset = dataset;\r
-      setAlignment(al);\r
-      init();\r
-    }\r
-    /**\r
-     * Creates a new AlignViewport object.\r
-     *\r
-     * @param al DOCUMENT ME!\r
-     */\r
-    public AlignViewport(AlignmentI al)\r
-    {\r
-        setAlignment(al);\r
-        init();\r
-    }\r
-\r
-    void init()\r
-    {\r
-        this.startRes = 0;\r
-        this.endRes = alignment.getWidth() - 1;\r
-        this.startSeq = 0;\r
-        this.endSeq = alignment.getHeight() - 1;\r
-\r
-      antiAlias = Cache.getDefault("ANTI_ALIAS", false);\r
-\r
-      showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);\r
-      showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);\r
-      showConservation = Cache.getDefault("SHOW_CONSERVATION", true);\r
-\r
-      showQuality = Cache.getDefault("SHOW_QUALITY", true);\r
-      showIdentity = Cache.getDefault("SHOW_IDENTITY", true);\r
-\r
-       String fontName = Cache.getDefault("FONT_NAME", "SansSerif");\r
-       String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "") ;\r
-       String fontSize = Cache.getDefault("FONT_SIZE", "10");\r
-\r
-       int style = 0;\r
-\r
-       if (fontStyle.equals("bold"))\r
-       {\r
-         style = 1;\r
-       }\r
-       else if (fontStyle.equals("italic"))\r
-       {\r
-         style = 2;\r
-       }\r
-\r
-       setFont(new Font(fontName, style, Integer.parseInt(fontSize)));\r
-\r
-\r
-       alignment.setGapCharacter( Cache.getDefault("GAP_SYMBOL", "-").charAt(0) );\r
-\r
-\r
-        // We must set conservation and consensus before setting colour,\r
-        // as Blosum and Clustal require this to be done\r
-        if(vconsensus==null && !isDataset)\r
-        {\r
-          updateConservation();\r
-          updateConsensus();\r
-        }\r
-\r
-        if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)\r
-        {\r
-          globalColourScheme = ColourSchemeProperty.getColour(alignment,\r
-              jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));\r
-\r
-            if (globalColourScheme instanceof UserColourScheme)\r
-            {\r
-                globalColourScheme = UserDefinedColours.loadDefaultColours();\r
-                ((UserColourScheme)globalColourScheme).setThreshold(0, getIgnoreGapsConsensus());\r
-            }\r
-\r
-            if (globalColourScheme != null)\r
-            {\r
-                globalColourScheme.setConsensus(vconsensus);\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setShowSequenceFeatures(boolean b)\r
-    {\r
-        showSequenceFeatures = b;\r
-    }\r
-\r
-    public boolean getShowSequenceFeatures()\r
-    {\r
-      return showSequenceFeatures;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void updateConservation()\r
-    {\r
-      if(alignment.isNucleotide())\r
-          return;\r
-\r
-      try{\r
-        Conservation cons = new jalview.analysis.Conservation("All",\r
-            jalview.schemes.ResidueProperties.propHash, 3,\r
-            alignment.getSequences(), 0, alignment.getWidth() - 1);\r
-        cons.calculate();\r
-        cons.verdict(false, ConsPercGaps);\r
-        cons.findQuality();\r
-\r
-        int alWidth = alignment.getWidth();\r
-        Annotation[] annotations = new Annotation[alWidth];\r
-        Annotation[] qannotations = new Annotation[alWidth];\r
-        String sequence = cons.getConsSequence().getSequence();\r
-        float minR;\r
-        float minG;\r
-        float minB;\r
-        float maxR;\r
-        float maxG;\r
-        float maxB;\r
-        minR = 0.3f;\r
-        minG = 0.0f;\r
-        minB = 0f;\r
-        maxR = 1.0f - minR;\r
-        maxG = 0.9f - minG;\r
-        maxB = 0f - minB; // scalable range for colouring both Conservation and Quality\r
-\r
-        float min = 0f;\r
-        float max = 11f;\r
-        float qmin = cons.qualityRange[0].floatValue();\r
-        float qmax = cons.qualityRange[1].floatValue();\r
-\r
-        for (int i = 0; i < alWidth; i++)\r
-        {\r
-          float value = 0;\r
-\r
-          try\r
-          {\r
-            value = Integer.parseInt(sequence.charAt(i) + "");\r
-          }\r
-          catch (Exception ex)\r
-          {\r
-            if (sequence.charAt(i) == '*')\r
-            {\r
-              value = 11;\r
-            }\r
-\r
-            if (sequence.charAt(i) == '+')\r
-            {\r
-              value = 10;\r
-            }\r
-          }\r
-\r
-          float vprop = value - min;\r
-          vprop /= max;\r
-          annotations[i] = new Annotation(sequence.charAt(i) + "",\r
-                                          String.valueOf(value), ' ', value,\r
-                                          new Color(minR + (maxR * vprop),\r
-              minG + (maxG * vprop),\r
-              minB + (maxB * vprop)));\r
-\r
-          // Quality calc\r
-          value = ( (Double) cons.quality.get(i)).floatValue();\r
-          vprop = value - qmin;\r
-          vprop /= qmax;\r
-          qannotations[i] = new Annotation(" ", String.valueOf(value), ' ',\r
-                                           value,\r
-                                           new Color(minR + (maxR * vprop),\r
-              minG + (maxG * vprop),\r
-              minB + (maxB * vprop)));\r
-        }\r
-\r
-        if (conservation == null)\r
-        {\r
-          conservation = new AlignmentAnnotation("Conservation",\r
-                                                 "Conservation of total alignment less than " +\r
-                                                 ConsPercGaps + "% gaps",\r
-                                                 annotations, 0f, // cons.qualityRange[0].floatValue(),\r
-                                                 11f, // cons.qualityRange[1].floatValue()\r
-                                                 AlignmentAnnotation.BAR_GRAPH);\r
-\r
-          if (showConservation)\r
-          {\r
-            alignment.addAnnotation(conservation);\r
-          }\r
-\r
-          quality = new AlignmentAnnotation("Quality",\r
-                                            "Alignment Quality based on Blosum62 scores",\r
-                                            qannotations,\r
-                                            cons.qualityRange[0].floatValue(),\r
-                                            cons.qualityRange[1].floatValue(),\r
-                                            AlignmentAnnotation.BAR_GRAPH);\r
-\r
-          if (showQuality)\r
-          {\r
-            alignment.addAnnotation(quality);\r
-          }\r
-        }\r
-        else\r
-        {\r
-          conservation.annotations = annotations;\r
-          quality.annotations = qannotations;\r
-          quality.graphMax = cons.qualityRange[1].floatValue();\r
-        }\r
-      }\r
-      catch (OutOfMemoryError error)\r
-      {\r
-        javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-            "Out of memory calculating conservation!!"\r
-            +\r
-            "\nSee help files for increasing Java Virtual Machine memory."\r
-            , "Out of memory",\r
-            javax.swing.JOptionPane.WARNING_MESSAGE);\r
-        System.out.println("Conservation calculation: " + error);\r
-        System.gc();\r
-\r
-      }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void updateConsensus()\r
-    {\r
-      try{\r
-        Annotation[] annotations = new Annotation[alignment.getWidth()];\r
-\r
-        // this routine prevents vconsensus becoming a new object each time\r
-        // consenus is calculated. Important for speed of Blosum62\r
-        // and PID colouring of alignment\r
-        if (vconsensus == null)\r
-        {\r
-          vconsensus = alignment.getAAFrequency();\r
-        }\r
-        else\r
-        {\r
-          Vector temp = alignment.getAAFrequency();\r
-          vconsensus.clear();\r
-\r
-          Enumeration e = temp.elements();\r
-\r
-          while (e.hasMoreElements())\r
-          {\r
-            vconsensus.add(e.nextElement());\r
-          }\r
-        }\r
-\r
-        Hashtable hash = null;\r
-\r
-        for (int i = 0; i < alignment.getWidth(); i++)\r
-        {\r
-          hash = (Hashtable) vconsensus.elementAt(i);\r
-\r
-          float value = 0;\r
-          if (ignoreGapsInConsensusCalculation)\r
-            value = ( (Float) hash.get("pid_nogaps")).floatValue();\r
-          else\r
-            value = ( (Float) hash.get("pid_gaps")).floatValue();\r
-\r
-          String maxRes = hash.get("maxResidue").toString();\r
-          String mouseOver = hash.get("maxResidue") + " ";\r
-\r
-          if (maxRes.length() > 1)\r
-          {\r
-            mouseOver = "[" + maxRes + "] ";\r
-            maxRes = "+";\r
-          }\r
-\r
-          mouseOver += ( (int) value + "%");\r
-          annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);\r
-        }\r
-\r
-        if (consensus == null)\r
-        {\r
-          consensus = new AlignmentAnnotation("Consensus", "PID",\r
-                                              annotations, 0f, 100f,AlignmentAnnotation.BAR_GRAPH);\r
-\r
-          if (showIdentity)\r
-          {\r
-            alignment.addAnnotation(consensus);\r
-          }\r
-        }\r
-        else\r
-        {\r
-          consensus.annotations = annotations;\r
-        }\r
-\r
-        if (globalColourScheme != null)\r
-          globalColourScheme.setConsensus(vconsensus);\r
-\r
-      }catch(OutOfMemoryError error)\r
-      {\r
-        javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-            "Out of memory calculating consensus!!"\r
-            +\r
-            "\nSee help files for increasing Java Virtual Machine memory."\r
-            , "Out of memory",\r
-            javax.swing.JOptionPane.WARNING_MESSAGE);\r
-        System.out.println("Consensus calculation: " + error);\r
-        System.gc();\r
-      }\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceGroup getSelectionGroup()\r
-    {\r
-        return selectionGroup;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param sg DOCUMENT ME!\r
-     */\r
-    public void setSelectionGroup(SequenceGroup sg)\r
-    {\r
-        selectionGroup = sg;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getConservationSelected()\r
-    {\r
-        return conservationColourSelected;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setConservationSelected(boolean b)\r
-    {\r
-        conservationColourSelected = b;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getAbovePIDThreshold()\r
-    {\r
-        return abovePIDThreshold;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setAbovePIDThreshold(boolean b)\r
-    {\r
-        abovePIDThreshold = b;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getStartRes()\r
-    {\r
-        return startRes;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getEndRes()\r
-    {\r
-        return endRes;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getStartSeq()\r
-    {\r
-        return startSeq;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param cs DOCUMENT ME!\r
-     */\r
-    public void setGlobalColourScheme(ColourSchemeI cs)\r
-    {\r
-        globalColourScheme = cs;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public ColourSchemeI getGlobalColourScheme()\r
-    {\r
-        return globalColourScheme;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param res DOCUMENT ME!\r
-     */\r
-    public void setStartRes(int res)\r
-    {\r
-        this.startRes = res;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    public void setStartSeq(int seq)\r
-    {\r
-        this.startSeq = seq;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param res DOCUMENT ME!\r
-     */\r
-    public void setEndRes(int res)\r
-    {\r
-        if (res > (alignment.getWidth() - 1))\r
-        {\r
-            // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));\r
-            res = alignment.getWidth() - 1;\r
-        }\r
-\r
-        if (res < 0)\r
-        {\r
-            res = 0;\r
-        }\r
-\r
-        this.endRes = res;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    public void setEndSeq(int seq)\r
-    {\r
-        if (seq > alignment.getHeight())\r
-        {\r
-            seq = alignment.getHeight();\r
-        }\r
-\r
-        if (seq < 0)\r
-        {\r
-            seq = 0;\r
-        }\r
-\r
-        this.endSeq = seq;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getEndSeq()\r
-    {\r
-        return endSeq;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param f DOCUMENT ME!\r
-     */\r
-    public void setFont(Font f)\r
-    {\r
-        font = f;\r
-\r
-        Container c = new Container();\r
-\r
-        java.awt.FontMetrics fm = c.getFontMetrics(font);\r
-        setCharHeight(fm.getHeight());\r
-        setCharWidth(fm.charWidth('M'));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Font getFont()\r
-    {\r
-        return font;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param w DOCUMENT ME!\r
-     */\r
-    public void setCharWidth(int w)\r
-    {\r
-        this.charWidth = w;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getCharWidth()\r
-    {\r
-        return charWidth;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param h DOCUMENT ME!\r
-     */\r
-    public void setCharHeight(int h)\r
-    {\r
-        this.charHeight = h;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getCharHeight()\r
-    {\r
-        return charHeight;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param w DOCUMENT ME!\r
-     */\r
-    public void setWrappedWidth(int w)\r
-    {\r
-        this.wrappedWidth = w;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getWrappedWidth()\r
-    {\r
-        return wrappedWidth;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public AlignmentI getAlignment()\r
-    {\r
-        return alignment;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param align DOCUMENT ME!\r
-     */\r
-    public void setAlignment(AlignmentI align)\r
-    {\r
-        this.alignment = align;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setWrapAlignment(boolean state)\r
-    {\r
-        wrapAlignment = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setShowText(boolean state)\r
-    {\r
-        showText = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setRenderGaps(boolean state)\r
-    {\r
-        renderGaps = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getColourText()\r
-    {\r
-        return showColourText;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setColourText(boolean state)\r
-    {\r
-        showColourText = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setShowBoxes(boolean state)\r
-    {\r
-        showBoxes = state;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getWrapAlignment()\r
-    {\r
-        return wrapAlignment;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getShowText()\r
-    {\r
-        return showText;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getShowBoxes()\r
-    {\r
-        return showBoxes;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public char getGapCharacter()\r
-    {\r
-        return getAlignment().getGapCharacter();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param gap DOCUMENT ME!\r
-     */\r
-    public void setGapCharacter(char gap)\r
-    {\r
-        if (getAlignment() != null)\r
-        {\r
-            getAlignment().setGapCharacter(gap);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param thresh DOCUMENT ME!\r
-     */\r
-    public void setThreshold(int thresh)\r
-    {\r
-        threshold = thresh;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getThreshold()\r
-    {\r
-        return threshold;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param inc DOCUMENT ME!\r
-     */\r
-    public void setIncrement(int inc)\r
-    {\r
-        increment = inc;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getIncrement()\r
-    {\r
-        return increment;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param y DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getIndex(int y)\r
-    {\r
-        int y1 = 0;\r
-        int starty = getStartSeq();\r
-        int endy = getEndSeq();\r
-\r
-        for (int i = starty; i <= endy; i++)\r
-        {\r
-            if ((i < alignment.getHeight()) &&\r
-                    (alignment.getSequenceAt(i) != null))\r
-            {\r
-                int y2 = y1 + getCharHeight();\r
-\r
-                if ((y >= y1) && (y <= y2))\r
-                {\r
-                    return i;\r
-                }\r
-\r
-                y1 = y2;\r
-            }\r
-            else\r
-            {\r
-                return -1;\r
-            }\r
-        }\r
-\r
-        return -1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public ColumnSelection getColumnSelection()\r
-    {\r
-        return colSel;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param tree DOCUMENT ME!\r
-     */\r
-    public void setCurrentTree(NJTree tree)\r
-    {\r
-        currentTree = tree;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public NJTree getCurrentTree()\r
-    {\r
-        return currentTree;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setColourAppliesToAllGroups(boolean b)\r
-    {\r
-        colourAppliesToAllGroups = b;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getColourAppliesToAllGroups()\r
-    {\r
-        return colourAppliesToAllGroups;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getShowJVSuffix()\r
-    {\r
-        return showJVSuffix;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setShowJVSuffix(boolean b)\r
-    {\r
-        showJVSuffix = b;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getShowAnnotation()\r
-    {\r
-        return showAnnotation;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setShowAnnotation(boolean b)\r
-    {\r
-        showAnnotation = b;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getScaleAboveWrapped()\r
-    {\r
-        return scaleAboveWrapped;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getScaleLeftWrapped()\r
-    {\r
-        return scaleLeftWrapped;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean getScaleRightWrapped()\r
-    {\r
-        return scaleRightWrapped;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setScaleAboveWrapped(boolean b)\r
-    {\r
-        scaleAboveWrapped = b;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setScaleLeftWrapped(boolean b)\r
-    {\r
-        scaleLeftWrapped = b;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setScaleRightWrapped(boolean b)\r
-    {\r
-        scaleRightWrapped = b;\r
-    }\r
-\r
-    /**\r
-     * Property change listener for changes in alignment\r
-     *\r
-     * @param listener DOCUMENT ME!\r
-     */\r
-    public void addPropertyChangeListener(\r
-        java.beans.PropertyChangeListener listener)\r
-    {\r
-        changeSupport.addPropertyChangeListener(listener);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param listener DOCUMENT ME!\r
-     */\r
-    public void removePropertyChangeListener(\r
-        java.beans.PropertyChangeListener listener)\r
-    {\r
-        changeSupport.removePropertyChangeListener(listener);\r
-    }\r
-\r
-    /**\r
-     * Property change listener for changes in alignment\r
-     *\r
-     * @param prop DOCUMENT ME!\r
-     * @param oldvalue DOCUMENT ME!\r
-     * @param newvalue DOCUMENT ME!\r
-     */\r
-    public void firePropertyChange(String prop, Object oldvalue, Object newvalue)\r
-    {\r
-        changeSupport.firePropertyChange(prop, oldvalue, newvalue);\r
-    }\r
-\r
-    public void setIgnoreGapsConsensus(boolean b)\r
-    {\r
-      ignoreGapsInConsensusCalculation = b;\r
-      updateConsensus();\r
-      if(globalColourScheme!=null)\r
-      {\r
-        globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation);\r
-      }\r
-    }\r
-\r
-    public boolean getIgnoreGapsConsensus()\r
-    {\r
-     return ignoreGapsInConsensusCalculation;\r
-    }\r
-\r
-    public void setDataset(boolean b)\r
-    {\r
-      isDataset = b;\r
-    }\r
-\r
-    public boolean isDataset()\r
-    {\r
-      return isDataset;\r
-    }\r
-\r
-    public void hideSequence(SequenceI seq)\r
-    {\r
-      alignment.getHiddenSequences().hideSequence(seq);\r
-      hasHiddenRows = true;\r
-    }\r
-\r
-    public void showSequence(int index)\r
-    {\r
-      alignment.getHiddenSequences().showSequence(index);\r
-\r
-      if(alignment.getHiddenSequences().getSize()<1)\r
-        hasHiddenRows = false;\r
-    }\r
-\r
-    public int adjustForHiddenSeqs(int alignmentIndex)\r
-    {\r
-      return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);\r
-    }\r
-}\r
+ /*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.analysis.*;
+
+import jalview.bin.*;
+
+import jalview.datamodel.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AlignViewport
+{
+    int startRes;
+    int endRes;
+    int startSeq;
+    int endSeq;
+    boolean showJVSuffix = true;
+    boolean showText = true;
+    boolean showColourText = false;
+    boolean showBoxes = true;
+    boolean wrapAlignment = false;
+    boolean renderGaps = true;
+    boolean showSequenceFeatures = false;
+    boolean showAnnotation = true;
+    boolean showConservation = true;
+    boolean showQuality = true;
+    boolean showIdentity = true;
+    boolean colourAppliesToAllGroups = true;
+    ColourSchemeI globalColourScheme = null;
+    boolean conservationColourSelected = false;
+    boolean abovePIDThreshold = false;
+    SequenceGroup selectionGroup;
+    int charHeight;
+    int charWidth;
+    boolean validCharWidth;
+    int wrappedWidth;
+    Font font;
+    AlignmentI alignment;
+    ColumnSelection colSel = new ColumnSelection();
+    int threshold;
+    int increment;
+    NJTree currentTree = null;
+    boolean scaleAboveWrapped = false;
+    boolean scaleLeftWrapped = true;
+    boolean scaleRightWrapped = true;
+    boolean hasHiddenColumns = false;
+    boolean hasHiddenRows = false;
+    boolean showHiddenMarkers = true;
+
+    boolean cursorMode = false;
+
+    // The following vector holds the features which are
+    // currently visible, in the correct order or rendering
+    Hashtable featuresDisplayed = null;
+
+
+    /** DOCUMENT ME!! */
+    public Vector vconsensus;
+    AlignmentAnnotation consensus;
+    AlignmentAnnotation conservation;
+    AlignmentAnnotation quality;
+    boolean autoCalculateConsensus = true;
+
+    /** DOCUMENT ME!! */
+    public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
+
+    // JBPNote Prolly only need this in the applet version.
+    private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);
+
+    boolean ignoreGapsInConsensusCalculation = false;
+
+    boolean isDataset = false;
+
+    boolean antiAlias = false;
+
+    boolean padGaps = false;
+
+
+    public AlignViewport(AlignmentI al, boolean dataset)
+    {
+      isDataset = dataset;
+      setAlignment(al);
+      init();
+    }
+    /**
+     * Creates a new AlignViewport object.
+     *
+     * @param al DOCUMENT ME!
+     */
+    public AlignViewport(AlignmentI al)
+    {
+        setAlignment(al);
+        init();
+    }
+    /**
+     * Create a new AlignViewport with hidden regions
+     * @param al AlignmentI
+     * @param hiddenColumns ColumnSelection
+     */
+    public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) {
+      setAlignment(al);
+      if (hiddenColumns!=null) {
+        this.colSel = hiddenColumns;
+        if (hiddenColumns.getHiddenColumns() != null)
+          hasHiddenColumns = true;
+      }
+      init();
+    }
+
+    void init()
+    {
+        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);
+      showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);
+      showConservation = Cache.getDefault("SHOW_CONSERVATION", true);
+
+      showQuality = Cache.getDefault("SHOW_QUALITY", true);
+      showIdentity = Cache.getDefault("SHOW_IDENTITY", true);
+
+      autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
+
+      padGaps = Cache.getDefault("PAD_GAPS", false);
+
+       String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
+       String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "") ;
+       String fontSize = Cache.getDefault("FONT_SIZE", "10");
+
+       int style = 0;
+
+       if (fontStyle.equals("bold"))
+       {
+         style = 1;
+       }
+       else if (fontStyle.equals("italic"))
+       {
+         style = 2;
+       }
+
+       setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
+
+
+       alignment.setGapCharacter( Cache.getDefault("GAP_SYMBOL", "-").charAt(0) );
+
+
+        // We must set conservation and consensus before setting colour,
+        // as Blosum and Clustal require this to be done
+        if(vconsensus==null && !isDataset)
+        {
+          updateConservation();
+          updateConsensus();
+        }
+
+        if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
+        {
+          globalColourScheme = ColourSchemeProperty.getColour(alignment,
+              jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
+
+            if (globalColourScheme instanceof UserColourScheme)
+            {
+                globalColourScheme = UserDefinedColours.loadDefaultColours();
+                ((UserColourScheme)globalColourScheme).setThreshold(0, getIgnoreGapsConsensus());
+            }
+
+            if (globalColourScheme != null)
+            {
+                globalColourScheme.setConsensus(vconsensus);
+            }
+        }
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void setShowSequenceFeatures(boolean b)
+    {
+        showSequenceFeatures = b;
+    }
+
+    public boolean getShowSequenceFeatures()
+    {
+      return showSequenceFeatures;
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void updateConservation()
+    {
+      if(alignment.isNucleotide())
+          return;
+
+      try{
+        Conservation cons = new jalview.analysis.Conservation("All",
+            jalview.schemes.ResidueProperties.propHash, 3,
+            alignment.getSequences(), 0, alignment.getWidth() - 1);
+        cons.calculate();
+        cons.verdict(false, ConsPercGaps);
+        cons.findQuality();
+
+        int alWidth = alignment.getWidth();
+        Annotation[] annotations = new Annotation[alWidth];
+        Annotation[] qannotations = new Annotation[alWidth];
+        String sequence = cons.getConsSequence().getSequence();
+        float minR;
+        float minG;
+        float minB;
+        float maxR;
+        float maxG;
+        float maxB;
+        minR = 0.3f;
+        minG = 0.0f;
+        minB = 0f;
+        maxR = 1.0f - minR;
+        maxG = 0.9f - minG;
+        maxB = 0f - minB; // scalable range for colouring both Conservation and Quality
+
+        float min = 0f;
+        float max = 11f;
+        float qmin = cons.qualityRange[0].floatValue();
+        float qmax = cons.qualityRange[1].floatValue();
+
+        for (int i = 0; i < alWidth; i++)
+        {
+          float value = 0;
+
+          try
+          {
+            value = Integer.parseInt(sequence.charAt(i) + "");
+          }
+          catch (Exception ex)
+          {
+            if (sequence.charAt(i) == '*')
+            {
+              value = 11;
+            }
+
+            if (sequence.charAt(i) == '+')
+            {
+              value = 10;
+            }
+          }
+
+          float vprop = value - min;
+          vprop /= max;
+          annotations[i] = new Annotation(sequence.charAt(i) + "",
+                                          String.valueOf(value), ' ', value,
+                                          new Color(minR + (maxR * vprop),
+              minG + (maxG * vprop),
+              minB + (maxB * vprop)));
+
+          // Quality calc
+          value = ( (Double) cons.quality.get(i)).floatValue();
+          vprop = value - qmin;
+          vprop /= qmax;
+          qannotations[i] = new Annotation(" ", String.valueOf(value), ' ',
+                                           value,
+                                           new Color(minR + (maxR * vprop),
+              minG + (maxG * vprop),
+              minB + (maxB * vprop)));
+        }
+
+        if (conservation == null)
+        {
+          conservation = new AlignmentAnnotation("Conservation",
+                                                 "Conservation of total alignment less than " +
+                                                 ConsPercGaps + "% gaps",
+                                                 annotations, 0f, // cons.qualityRange[0].floatValue(),
+                                                 11f, // cons.qualityRange[1].floatValue()
+                                                 AlignmentAnnotation.BAR_GRAPH);
+
+          if (showConservation)
+          {
+            alignment.addAnnotation(conservation);
+          }
+
+          quality = new AlignmentAnnotation("Quality",
+                                            "Alignment Quality based on Blosum62 scores",
+                                            qannotations,
+                                            cons.qualityRange[0].floatValue(),
+                                            cons.qualityRange[1].floatValue(),
+                                            AlignmentAnnotation.BAR_GRAPH);
+
+          if (showQuality)
+          {
+            alignment.addAnnotation(quality);
+          }
+        }
+        else
+        {
+          conservation.annotations = annotations;
+          quality.annotations = qannotations;
+          quality.graphMax = cons.qualityRange[1].floatValue();
+        }
+      }
+      catch (OutOfMemoryError error)
+      {
+        javax.swing.SwingUtilities.invokeLater(new Runnable()
+        {
+          public void run()
+          {
+            javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                "Out of memory calculating conservation!!"
+                +
+                "\nSee help files for increasing Java Virtual Machine memory."
+                , "Out of memory",
+                javax.swing.JOptionPane.WARNING_MESSAGE);
+          }
+        });
+
+        System.out.println("Conservation calculation: " + error);
+        System.gc();
+
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void updateConsensus()
+    {
+      try{
+        Annotation[] annotations = new Annotation[alignment.getWidth()];
+
+        // this routine prevents vconsensus becoming a new object each time
+        // consenus is calculated. Important for speed of Blosum62
+        // and PID colouring of alignment
+        if (vconsensus == null)
+        {
+          vconsensus = alignment.getAAFrequency();
+        }
+        else
+        {
+          Vector temp = alignment.getAAFrequency();
+          vconsensus.clear();
+
+          Enumeration e = temp.elements();
+
+          while (e.hasMoreElements())
+          {
+            vconsensus.add(e.nextElement());
+          }
+        }
+
+        Hashtable hash = null;
+
+        for (int i = 0; i < alignment.getWidth(); i++)
+        {
+          hash = (Hashtable) vconsensus.elementAt(i);
+
+          float value = 0;
+          if (ignoreGapsInConsensusCalculation)
+            value = ( (Float) hash.get("pid_nogaps")).floatValue();
+          else
+            value = ( (Float) hash.get("pid_gaps")).floatValue();
+
+          String maxRes = hash.get("maxResidue").toString();
+          String mouseOver = hash.get("maxResidue") + " ";
+
+          if (maxRes.length() > 1)
+          {
+            mouseOver = "[" + maxRes + "] ";
+            maxRes = "+";
+          }
+
+          mouseOver += ( (int) value + "%");
+          annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);
+        }
+
+        if (consensus == null)
+        {
+          consensus = new AlignmentAnnotation("Consensus", "PID",
+                                              annotations, 0f, 100f,AlignmentAnnotation.BAR_GRAPH);
+
+          if (showIdentity)
+          {
+            alignment.addAnnotation(consensus);
+          }
+        }
+        else
+        {
+          consensus.annotations = annotations;
+        }
+
+        if (globalColourScheme != null)
+          globalColourScheme.setConsensus(vconsensus);
+
+      }catch(OutOfMemoryError error)
+      {
+        javax.swing.SwingUtilities.invokeLater(new Runnable()
+        {
+          public void run()
+          {
+            javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                "Out of memory calculating consensus!!"
+                +
+                "\nSee help files for increasing Java Virtual Machine memory."
+                , "Out of memory",
+                javax.swing.JOptionPane.WARNING_MESSAGE);
+          }
+        });
+
+
+        System.out.println("Consensus calculation: " + error);
+        System.gc();
+      }
+
+    }
+    /**
+     * get the consensus sequence as displayed under the PID consensus annotation row.
+     * @return consensus sequence as a new sequence object
+     */
+    public SequenceI getConsensusSeq() {
+      if (consensus==null)
+        updateConsensus();
+      if (consensus==null)
+        return null;
+      StringBuffer seqs=new StringBuffer();
+      for (int i=0; i<consensus.annotations.length; i++) {
+        if (consensus.annotations[i]!=null) {
+          if (consensus.annotations[i].description.charAt(0) == '[')
+            seqs.append(consensus.annotations[i].description.charAt(1));          
+          else
+            seqs.append(consensus.annotations[i].displayCharacter);          
+        }
+      }
+      SequenceI sq = new Sequence("Consensus", seqs.toString());
+      sq.setDescription("Percentage Identity Consensus "+((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
+      return sq;
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceGroup getSelectionGroup()
+    {
+        return selectionGroup;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param sg DOCUMENT ME!
+     */
+    public void setSelectionGroup(SequenceGroup sg)
+    {
+        selectionGroup = sg;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean getConservationSelected()
+    {
+        return conservationColourSelected;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void setConservationSelected(boolean b)
+    {
+        conservationColourSelected = b;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean getAbovePIDThreshold()
+    {
+        return abovePIDThreshold;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void setAbovePIDThreshold(boolean b)
+    {
+        abovePIDThreshold = b;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getStartRes()
+    {
+        return startRes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getEndRes()
+    {
+        return endRes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getStartSeq()
+    {
+        return startSeq;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param cs DOCUMENT ME!
+     */
+    public void setGlobalColourScheme(ColourSchemeI cs)
+    {
+        globalColourScheme = cs;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public ColourSchemeI getGlobalColourScheme()
+    {
+        return globalColourScheme;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param res DOCUMENT ME!
+     */
+    public void setStartRes(int res)
+    {
+        this.startRes = res;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     */
+    public void setStartSeq(int seq)
+    {
+        this.startSeq = seq;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param res DOCUMENT ME!
+     */
+    public void setEndRes(int res)
+    {
+        if (res > (alignment.getWidth() - 1))
+        {
+            // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));
+            res = alignment.getWidth() - 1;
+        }
+
+        if (res < 0)
+        {
+            res = 0;
+        }
+
+        this.endRes = res;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     */
+    public void setEndSeq(int seq)
+    {
+        if (seq > alignment.getHeight())
+        {
+            seq = alignment.getHeight();
+        }
+
+        if (seq < 0)
+        {
+            seq = 0;
+        }
+
+        this.endSeq = seq;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getEndSeq()
+    {
+        return endSeq;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param f DOCUMENT ME!
+     */
+    public void setFont(Font f)
+    {
+        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;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getCharHeight()
+    {
+        return charHeight;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param w DOCUMENT ME!
+     */
+    public void setWrappedWidth(int w)
+    {
+        this.wrappedWidth = w;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getWrappedWidth()
+    {
+        return wrappedWidth;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AlignmentI getAlignment()
+    {
+        return alignment;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param align DOCUMENT ME!
+     */
+    public void setAlignment(AlignmentI align)
+    {
+        this.alignment = align;
+    }
+
+    /**
+     * 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()
+    {
+        return getAlignment().getGapCharacter();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param gap DOCUMENT ME!
+     */
+    public void setGapCharacter(char gap)
+    {
+        if (getAlignment() != null)
+        {
+            getAlignment().setGapCharacter(gap);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param thresh DOCUMENT ME!
+     */
+    public void setThreshold(int thresh)
+    {
+        threshold = thresh;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getThreshold()
+    {
+        return threshold;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param inc DOCUMENT ME!
+     */
+    public void setIncrement(int inc)
+    {
+        increment = inc;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getIncrement()
+    {
+        return increment;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public ColumnSelection getColumnSelection()
+    {
+        return colSel;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param tree DOCUMENT ME!
+     */
+    public void setCurrentTree(NJTree tree)
+    {
+        currentTree = tree;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public NJTree getCurrentTree()
+    {
+        return currentTree;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void setColourAppliesToAllGroups(boolean b)
+    {
+        colourAppliesToAllGroups = b;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean getColourAppliesToAllGroups()
+    {
+        return colourAppliesToAllGroups;
+    }
+
+    /**
+     * 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 getShowAnnotation()
+    {
+        return showAnnotation;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void setShowAnnotation(boolean b)
+    {
+        showAnnotation = 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;
+    }
+
+    /**
+     * Property change listener for changes in alignment
+     *
+     * @param listener DOCUMENT ME!
+     */
+    public void addPropertyChangeListener(
+        java.beans.PropertyChangeListener listener)
+    {
+        changeSupport.addPropertyChangeListener(listener);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param listener DOCUMENT ME!
+     */
+    public void removePropertyChangeListener(
+        java.beans.PropertyChangeListener listener)
+    {
+        changeSupport.removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Property change listener for changes in alignment
+     *
+     * @param prop DOCUMENT ME!
+     * @param oldvalue DOCUMENT ME!
+     * @param newvalue DOCUMENT ME!
+     */
+    public void firePropertyChange(String prop, Object oldvalue, Object newvalue)
+    {
+        changeSupport.firePropertyChange(prop, oldvalue, newvalue);
+    }
+
+    public void setIgnoreGapsConsensus(boolean b)
+    {
+      ignoreGapsInConsensusCalculation = b;
+      updateConsensus();
+      if(globalColourScheme!=null)
+      {
+        globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation);
+      }
+    }
+
+    public boolean getIgnoreGapsConsensus()
+    {
+     return ignoreGapsInConsensusCalculation;
+    }
+
+    public void setDataset(boolean b)
+    {
+      isDataset = b;
+    }
+
+    public boolean isDataset()
+    {
+      return isDataset;
+    }
+
+
+    public void hideSelectedColumns()
+    {
+      if (colSel.size() < 1)
+        return;
+
+      colSel.hideSelectedColumns();
+      setSelectionGroup(null);
+
+      hasHiddenColumns = true;
+    }
+
+
+    public void hideColumns(int start, int end)
+    {
+      if(start==end)
+        colSel.hideColumns(start);
+      else
+        colSel.hideColumns(start, end);
+
+      hasHiddenColumns = true;
+    }
+
+    public void hideAllSelectedSeqs()
+    {
+      if (selectionGroup == null)
+        return;
+
+      SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
+
+      for (int i = 0; i < seqs.length; i++)
+      {
+        alignment.getHiddenSequences().hideSequence(seqs[i]);
+      }
+      firePropertyChange("alignment", null, alignment.getSequences());
+      hasHiddenRows = true;
+      setSelectionGroup(null);
+    }
+
+    public void hideSequence(SequenceI seq)
+    {
+      if(seq!=null)
+      {
+        alignment.getHiddenSequences().hideSequence(seq);
+        hasHiddenRows = true;
+        firePropertyChange("alignment", null, alignment.getSequences());
+      }
+    }
+
+    public void showSequence(int index)
+    {
+      Vector tmp = alignment.getHiddenSequences().showSequence(index);
+      if(tmp.size()>0)
+      {
+        if(selectionGroup==null)
+        {
+          selectionGroup = new SequenceGroup();
+          selectionGroup.setEndRes(alignment.getWidth()-1);
+        }
+
+        for (int t = 0; t < tmp.size(); t++)
+        {
+          selectionGroup.addSequence(
+              (SequenceI) tmp.elementAt(t), false
+              );
+        }
+        firePropertyChange("alignment", null, alignment.getSequences());
+      }
+
+      if(alignment.getHiddenSequences().getSize()<1)
+        hasHiddenRows = false;
+    }
+
+    public void showColumn(int col)
+    {
+      colSel.revealHiddenColumns(col);
+      if(colSel.getHiddenColumns()==null)
+        hasHiddenColumns = false;
+    }
+
+    public void showAllHiddenColumns()
+    {
+      colSel.revealAllHiddenColumns();
+      hasHiddenColumns = false;
+    }
+
+    public void showAllHiddenSeqs()
+    {
+      if(alignment.getHiddenSequences().getSize()>0)
+      {
+        if(selectionGroup==null)
+        {
+          selectionGroup = new SequenceGroup();
+          selectionGroup.setEndRes(alignment.getWidth()-1);
+        }
+        Vector tmp = alignment.getHiddenSequences().showAll();
+        for(int t=0; t<tmp.size(); t++)
+        {
+          selectionGroup.addSequence(
+              (SequenceI)tmp.elementAt(t), false
+              );
+        }
+        firePropertyChange("alignment", null, alignment.getSequences());
+        hasHiddenRows = false;
+      }
+    }
+
+    public void invertColumnSelection()
+    {
+      int column;
+      for(int i=0; i<alignment.getWidth(); i++)
+      {
+        column = i;
+
+        if(colSel.contains(column))
+          colSel.removeElement(column);
+        else
+          colSel.addElement(column);
+
+      }
+
+    }
+
+    public int adjustForHiddenSeqs(int alignmentIndex)
+    {
+      return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);
+    }
+
+    /**
+     * This method returns the a new SequenceI [] with
+     * the selection sequence and start and end points adjusted
+     * @return String[]
+     */
+    public SequenceI[] getSelectionAsNewSequence()
+    {
+      SequenceI[] sequences;
+
+      if (selectionGroup == null)
+        sequences = alignment.getSequencesArray();
+      else
+        sequences = selectionGroup.getSelectionAsNewSequences(alignment);
+
+      return sequences;
+    }
+
+    /**
+     * This method returns the visible alignment as text, as
+     * seen on the GUI, ie if columns are hidden they will not
+     * be returned in the result.
+     * Use this for calculating trees, PCA, redundancy etc on views
+     * which contain hidden columns.
+     * @return String[]
+     */
+    public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)
+    {
+      CigarArray selection=null;
+      SequenceI [] seqs= null;
+      int i, iSize;
+      int start = 0, end = 0;
+      if(selectedRegionOnly && selectionGroup!=null)
+      {
+        iSize = selectionGroup.getSize(false);
+        seqs = selectionGroup.getSequencesInOrder(alignment);
+        start = selectionGroup.getStartRes();
+        end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor
+      }
+      else
+      {
+        iSize = alignment.getHeight();
+        seqs = alignment.getSequencesArray();
+        end = alignment.getWidth()-1;
+      }
+      SeqCigar[] selseqs = new SeqCigar[iSize];
+      for(i=0; i<iSize; i++)
+      {
+        selseqs[i] = new SeqCigar(seqs[i], start, end);
+      }
+      selection=new CigarArray(selseqs);
+      // now construct the CigarArray operations
+      if (hasHiddenColumns) {
+        Vector regions = colSel.getHiddenColumns();
+        int [] region;
+        int hideStart, hideEnd;
+        int last=start;
+        for (int j = 0; last<end & j < regions.size(); j++)
+        {
+          region = (int[]) regions.elementAt(j);
+          hideStart = region[0];
+          hideEnd = region[1];
+          // edit hidden regions to selection range
+          if(hideStart<last) {
+            if (hideEnd > last)
+            {
+              hideStart = last;
+            } else
+              continue;
+          }
+
+          if (hideStart>end)
+            break;
+
+          if (hideEnd>end)
+            hideEnd=end;
+
+          if (hideStart>hideEnd)
+            break;
+          /**
+           * form operations...
+           */
+          if (last<hideStart)
+            selection.addOperation(CigarArray.M, hideStart-last);
+          selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);
+          last = hideEnd+1;
+        }
+        // Final match if necessary.
+        if (last<end)
+          selection.addOperation(CigarArray.M, end-last);
+      } else {
+        selection.addOperation(CigarArray.M, end-start);
+      }
+      return selection;
+    }
+    /**
+     * return a compact representation of the current alignment selection to
+     * pass to an analysis function
+     * @param selectedOnly boolean true to just return the selected view
+     * @return AlignmentView
+     */
+    jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {
+      // JBPNote:
+      // this is here because the AlignmentView constructor modifies the CigarArray
+      // object. Refactoring of Cigar and alignment view representation should
+      // be done to remove redundancy.
+      CigarArray aligview = getViewAsCigars(selectedOnly);
+      if (aligview!=null)
+        return new AlignmentView(aligview);
+      return null;
+    }
+    /**
+     * This method returns the visible alignment as text, as
+     * seen on the GUI, ie if columns are hidden they will not
+     * be returned in the result.
+     * Use this for calculating trees, PCA, redundancy etc on views
+     * which contain hidden columns.
+     * @return String[]
+     */
+    public String [] getViewAsString(boolean selectedRegionOnly)
+    {
+      String [] selection = null;
+      SequenceI [] seqs= null;
+      int i, iSize;
+      int start = 0, end = 0;
+      if(selectedRegionOnly && selectionGroup!=null)
+      {
+        iSize = selectionGroup.getSize(false);
+        seqs = selectionGroup.getSequencesInOrder(alignment);
+        start = selectionGroup.getStartRes();
+        end = selectionGroup.getEndRes()+1;
+      }
+      else
+      {
+        iSize = alignment.getHeight();
+        seqs = alignment.getSequencesArray();
+        end = alignment.getWidth();
+      }
+
+      selection = new String[iSize];
+      if (hasHiddenColumns) {
+        selection = colSel.getVisibleSequenceStrings(start, end, seqs);
+      } else {
+        for(i=0; i<iSize; i++)
+        {
+          selection[i] = seqs[i].getSequence(start, end);
+        }
+        
+      }
+      return selection;
+    }
+
+    public boolean getShowHiddenMarkers()
+    {
+      return showHiddenMarkers;
+    }
+
+    public void setShowHiddenMarkers(boolean show)
+    {
+      showHiddenMarkers = show;
+    }
+}
index a04c5bf..c2df433 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.awt.print.*;\r
-\r
-import java.io.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AlignmentPanel extends GAlignmentPanel\r
-    implements AdjustmentListener, Printable\r
-{\r
-  public AlignViewport av;\r
-  OverviewPanel overviewPanel;\r
-  SeqPanel seqPanel;\r
-  IdPanel idPanel;\r
-  IdwidthAdjuster idwidthAdjuster;\r
-\r
-  /** DOCUMENT ME!! */\r
-  public AlignFrame alignFrame;\r
-  ScalePanel scalePanel;\r
-  AnnotationPanel annotationPanel;\r
-  AnnotationLabels alabels;\r
-\r
-  // this value is set false when selection area being dragged\r
-  boolean fastPaint = true;\r
-  int hextent = 0;\r
-  int vextent = 0;\r
-\r
-  /**\r
-   * Creates a new AlignmentPanel object.\r
-   *\r
-   * @param af DOCUMENT ME!\r
-   * @param av DOCUMENT ME!\r
-   */\r
-  public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
-  {\r
-    alignFrame = af;\r
-    this.av = av;\r
-    seqPanel = new SeqPanel(av, this);\r
-    idPanel = new IdPanel(av, this);\r
-\r
-    scalePanel = new ScalePanel(av, this);\r
-\r
-    idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
-    idwidthAdjuster = new IdwidthAdjuster(this);\r
-    idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
-\r
-    annotationPanel = new AnnotationPanel(this);\r
-    alabels = new AnnotationLabels(this);\r
-\r
-\r
-    annotationScroller.setViewportView(annotationPanel);\r
-    annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
-\r
-    fontChanged();\r
-\r
-    scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
-    seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
-\r
-    setScrollValues(0, 0);\r
-\r
-    annotationPanel.adjustPanelHeight();\r
-    annotationSpaceFillerHolder.setPreferredSize(annotationPanel.\r
-                                                 getPreferredSize());\r
-    annotationScroller.setPreferredSize(annotationPanel.\r
-                                        getPreferredSize());\r
-    setAnnotationVisible(av.getShowAnnotation());\r
-\r
-    hscroll.addAdjustmentListener(this);\r
-    vscroll.addAdjustmentListener(this);\r
-\r
-    af.addKeyListener(new KeyAdapter()\r
-    {\r
-      public void keyPressed(KeyEvent evt)\r
-      {\r
-        if(av.cursorMode\r
-           && evt.getKeyCode()>=KeyEvent.VK_0\r
-           && evt.getKeyCode()<=KeyEvent.VK_9)\r
-        {\r
-          seqPanel.numberPressed(evt.getKeyChar());\r
-        }\r
-\r
-        switch (evt.getKeyCode())\r
-        {\r
-          case 27: // escape key\r
-            av.setSelectionGroup(null);\r
-            repaint();\r
-\r
-            break;\r
-\r
-          case KeyEvent.VK_DOWN:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(0,1);\r
-            }\r
-            else\r
-              alignFrame.moveSelectedSequences(false);\r
-            break;\r
-\r
-          case KeyEvent.VK_UP:\r
-            if (av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(0,-1);\r
-            }\r
-            else\r
-              alignFrame.moveSelectedSequences(true);\r
-            break;\r
-\r
-          case KeyEvent.VK_LEFT:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(-1,0);\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_RIGHT:\r
-            if (av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(1,0);\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_SPACE:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.insertGapAtCursor(evt.isControlDown());\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_DELETE:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.deleteGapAtCursor(evt.isControlDown());\r
-              break;\r
-            }\r
-\r
-          case KeyEvent.VK_BACK_SPACE:\r
-            if(!av.cursorMode)\r
-            {\r
-              alignFrame.cut_actionPerformed(null);\r
-              seqPanel.seqCanvas.repaint();\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_Q:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setSelectionAreaAtCursor(true);\r
-            }\r
-            break;\r
-          case KeyEvent.VK_M:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setSelectionAreaAtCursor(false);\r
-            }\r
-            break;\r
-\r
-         case KeyEvent.VK_F2:\r
-           av.cursorMode = ! av.cursorMode;\r
-           alignFrame.statusBar.setText("Keyboard editing mode is "+\r
-               (av.cursorMode ? "on" : "off"));\r
-           if(av.cursorMode)\r
-           {\r
-             seqPanel.seqCanvas.cursorX = av.startRes;\r
-             seqPanel.seqCanvas.cursorY = av.startSeq;\r
-           }\r
-           seqPanel.seqCanvas.repaint();\r
-           break;\r
-\r
-          case KeyEvent.VK_F1:\r
-            try\r
-            {\r
-              ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();\r
-              java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");\r
-              javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);\r
-\r
-              javax.help.HelpBroker hb = hs.createHelpBroker();\r
-              hb.setCurrentID("home");\r
-              hb.setDisplayed(true);\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-              ex.printStackTrace();\r
-            }\r
-            break;\r
-\r
-        }\r
-      }\r
-    });\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void fontChanged()\r
-  {\r
-    // set idCanvas bufferedImage to null\r
-    // to prevent drawing old image\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-\r
-    scalePanelHolder.setPreferredSize(new Dimension(10,\r
-        av.charHeight + fm.getDescent()));\r
-    idSpaceFillerPanel1.setPreferredSize(new Dimension(10,\r
-        av.charHeight + fm.getDescent()));\r
-\r
-    idPanel.idCanvas.gg = null;\r
-    seqPanel.seqCanvas.img = null;\r
-    annotationPanel.adjustPanelHeight();\r
-\r
-    Dimension d = calculateIdWidth();\r
-    d.setSize(d.width + 4, d.height);\r
-    idPanel.idCanvas.setPreferredSize(d);\r
-    hscrollFillerPanel.setPreferredSize(d);\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      int max = av.alignment.getWidth() /\r
-          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
-      vscroll.setMaximum(max);\r
-      vscroll.setUnitIncrement(1);\r
-      vscroll.setVisibleAmount(1);\r
-    }\r
-    else\r
-    {\r
-      setScrollValues(av.getStartRes(), av.getStartSeq());\r
-    }\r
-\r
-    if (overviewPanel != null)\r
-      overviewPanel.setBoxPosition();\r
-\r
-    repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public Dimension calculateIdWidth()\r
-  {\r
-    Container c = new Container();\r
-\r
-    FontMetrics fm = c.getFontMetrics(av.font);\r
-    AlignmentI al = av.getAlignment();\r
-\r
-    int i = 0;\r
-    int idWidth = 0;\r
-    String id;\r
-\r
-    while ( (i < al.getHeight()) && (al.getSequenceAt(i) != null))\r
-    {\r
-      SequenceI s = al.getSequenceAt(i);\r
-\r
-      id = s.getDisplayId(av.getShowJVSuffix());\r
-\r
-      if (fm.stringWidth(id) > idWidth)\r
-      {\r
-        idWidth = fm.stringWidth(id);\r
-      }\r
-\r
-      i++;\r
-    }\r
-\r
-    // Also check annotation label widths\r
-    i = 0;\r
-\r
-    if (al.getAlignmentAnnotation() != null)\r
-    {\r
-      fm = c.getFontMetrics(alabels.getFont());\r
-\r
-      while (i < al.getAlignmentAnnotation().length)\r
-      {\r
-        String label = al.getAlignmentAnnotation()[i].label;\r
-\r
-        if (fm.stringWidth(label) > idWidth)\r
-        {\r
-          idWidth = fm.stringWidth(label);\r
-        }\r
-\r
-        i++;\r
-      }\r
-    }\r
-\r
-    return new Dimension(idWidth, 12);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param results DOCUMENT ME!\r
-   */\r
-  public void highlightSearchResults(SearchResults results)\r
-  {\r
-    seqPanel.seqCanvas.highlightSearchResults(results);\r
-\r
-    // do we need to scroll the panel?\r
-    if (results != null)\r
-    {\r
-      SequenceI seq = results.getResultSequence(0);\r
-      int seqIndex = av.alignment.findIndex(seq);\r
-      int start = seq.findIndex(results.getResultStart(0)) - 1;\r
-      int end = seq.findIndex(results.getResultEnd(0)) - 1;\r
-\r
-      if(!av.wrapAlignment)\r
-      {\r
-        if ( (av.getStartRes() > end)  || (av.getEndRes() < start) ||\r
-           ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))\r
-        {\r
-          setScrollValues(start, seqIndex);\r
-        }\r
-      }\r
-      else\r
-      {\r
-        int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
-        if( start<av.getStartRes() || start>(av.getStartRes()+cwidth) )\r
-        {\r
-          vscroll.setValue(start / cwidth);\r
-          av.startRes = vscroll.getValue() * cwidth;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public OverviewPanel getOverviewPanel()\r
-  {\r
-    return overviewPanel;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param op DOCUMENT ME!\r
-   */\r
-  public void setOverviewPanel(OverviewPanel op)\r
-  {\r
-    overviewPanel = op;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param b DOCUMENT ME!\r
-   */\r
-  public void setAnnotationVisible(boolean b)\r
-  {\r
-    if (!av.wrapAlignment)\r
-    {\r
-      annotationSpaceFillerHolder.setVisible(b);\r
-      annotationScroller.setVisible(b);\r
-    }\r
-    repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param wrap DOCUMENT ME!\r
-   */\r
-  public void setWrapAlignment(boolean wrap)\r
-  {\r
-    av.startSeq = 0;\r
-    scalePanelHolder.setVisible(!wrap);\r
-    hscroll.setVisible(!wrap);\r
-    idwidthAdjuster.setVisible(!wrap);\r
-\r
-    if (wrap)\r
-    {\r
-      annotationScroller.setVisible(false);\r
-      annotationSpaceFillerHolder.setVisible(false);\r
-    }\r
-    else if (av.showAnnotation)\r
-    {\r
-      annotationScroller.setVisible(true);\r
-      annotationSpaceFillerHolder.setVisible(true);\r
-    }\r
-\r
-    idSpaceFillerPanel1.setVisible(!wrap);\r
-\r
-    repaint();\r
-  }\r
-\r
-  // return value is true if the scroll is valid\r
-  public boolean scrollUp(boolean up)\r
-  {\r
-    if (up)\r
-    {\r
-      if (vscroll.getValue() < 1)\r
-      {\r
-        return false;\r
-      }\r
-\r
-      fastPaint = false;\r
-      vscroll.setValue(vscroll.getValue() - 1);\r
-    }\r
-    else\r
-    {\r
-      if ( (vextent + vscroll.getValue()) >= av.getAlignment().getHeight())\r
-      {\r
-        return false;\r
-      }\r
-\r
-      fastPaint = false;\r
-      vscroll.setValue(vscroll.getValue() + 1);\r
-    }\r
-\r
-    fastPaint = true;\r
-\r
-    return true;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param right DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public boolean scrollRight(boolean right)\r
-  {\r
-    if (!right)\r
-    {\r
-      if (hscroll.getValue() < 1)\r
-      {\r
-        return false;\r
-      }\r
-\r
-      fastPaint = false;\r
-      hscroll.setValue(hscroll.getValue() - 1);\r
-    }\r
-    else\r
-    {\r
-      if ( (hextent + hscroll.getValue()) >= av.getAlignment().getWidth())\r
-      {\r
-        return false;\r
-      }\r
-\r
-      fastPaint = false;\r
-      hscroll.setValue(hscroll.getValue() + 1);\r
-    }\r
-\r
-    fastPaint = true;\r
-\r
-    return true;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param x DOCUMENT ME!\r
-   * @param y DOCUMENT ME!\r
-   */\r
-  public void setScrollValues(int x, int y)\r
-  {\r
-\r
-    int width = av.alignment.getWidth();\r
-    int height = av.alignment.getHeight();\r
-\r
-    if(av.hasHiddenColumns)\r
-     width = av.getColumnSelection().findColumnPosition(width);\r
-\r
-    av.setEndRes( (x + (seqPanel.seqCanvas.getWidth() / av.charWidth)) -1);\r
-\r
-    hextent = seqPanel.seqCanvas.getWidth() / av.charWidth;\r
-    vextent = seqPanel.seqCanvas.getHeight() / av.charHeight;\r
-\r
-    if (hextent > width)\r
-    {\r
-      hextent = width;\r
-    }\r
-\r
-    if (vextent > height)\r
-    {\r
-      vextent = height;\r
-    }\r
-\r
-    if ( (hextent + x) > width)\r
-    {\r
-      x = width - hextent;\r
-    }\r
-\r
-    if ( (vextent + y) > height)\r
-    {\r
-      y = height - vextent;\r
-    }\r
-\r
-    if (y < 0)\r
-    {\r
-      y = 0;\r
-    }\r
-\r
-    if (x < 0)\r
-    {\r
-      x = 0;\r
-    }\r
-\r
-    hscroll.setValues(x, hextent, 0, width);\r
-    vscroll.setValues(y, vextent, 0, height);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param evt DOCUMENT ME!\r
-   */\r
-  public void adjustmentValueChanged(AdjustmentEvent evt)\r
-  {\r
-    int oldX = av.getStartRes();\r
-    int oldY = av.getStartSeq();\r
-\r
-    if (evt.getSource() == hscroll)\r
-    {\r
-      int x = hscroll.getValue();\r
-      av.setStartRes(x);\r
-      av.setEndRes( (x +\r
-                     (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) - 1);\r
-    }\r
-\r
-    if (evt.getSource() == vscroll)\r
-    {\r
-      int offy = vscroll.getValue();\r
-\r
-      if (av.getWrapAlignment())\r
-      {\r
-        int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.\r
-            seqCanvas.getWidth());\r
-        av.setStartRes(vscroll.getValue() * rowSize);\r
-        av.setEndRes( (vscroll.getValue() + 1) * rowSize);\r
-      }\r
-      else\r
-      {\r
-        av.setStartSeq(offy);\r
-        av.setEndSeq(offy +\r
-                     (seqPanel.seqCanvas.getHeight() / av.getCharHeight()));\r
-      }\r
-    }\r
-\r
-    if (overviewPanel != null)\r
-    {\r
-      overviewPanel.setBoxPosition();\r
-    }\r
-\r
-    int scrollX = av.startRes - oldX;\r
-    int scrollY = av.startSeq - oldY;\r
-\r
-    if (av.getWrapAlignment() || !fastPaint)\r
-    {\r
-      repaint();\r
-    }\r
-    else\r
-    {\r
-      // Make sure we're not trying to draw a panel\r
-      // larger than the visible window\r
-      if(scrollX>av.endRes-av.startRes)\r
-        scrollX = av.endRes-av.startRes;\r
-      else if(scrollX<av.startRes-av.endRes)\r
-        scrollX = av.startRes - av.endRes;\r
-\r
-      if(scrollX!=0 || scrollY!=0)\r
-      {\r
-        idPanel.idCanvas.fastPaint(scrollY);\r
-        seqPanel.seqCanvas.fastPaint(scrollX,\r
-                                     scrollY);\r
-        scalePanel.repaint();\r
-\r
-        if (av.getShowAnnotation())\r
-        {\r
-          annotationPanel.fastPaint(scrollX);\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param g DOCUMENT ME!\r
-   */\r
-  public void paintComponent(Graphics g)\r
-  {\r
-    invalidate();\r
-\r
-    Dimension d = idPanel.idCanvas.getPreferredSize();\r
-    idPanelHolder.setPreferredSize(d);\r
-    hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));\r
-    validate();\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      int max = av.alignment.getWidth() /\r
-          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth()) +1;\r
-\r
-\r
-      vscroll.setMaximum(max);\r
-      vscroll.setUnitIncrement(1);\r
-      vscroll.setVisibleAmount(1);\r
-    }\r
-    else\r
-    {\r
-      setScrollValues(av.getStartRes(), av.getStartSeq());\r
-    }\r
-\r
-    if( this.getVisibleRect().getBounds() == g.getClipBounds()\r
-        && overviewPanel != null)\r
-        overviewPanel.updateOverviewImage();\r
-\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param pg DOCUMENT ME!\r
-   * @param pf DOCUMENT ME!\r
-   * @param pi DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   *\r
-   * @throws PrinterException DOCUMENT ME!\r
-   */\r
-  public int print(Graphics pg, PageFormat pf, int pi)\r
-      throws PrinterException\r
-  {\r
-    pg.translate( (int) pf.getImageableX(), (int) pf.getImageableY());\r
-\r
-    int pwidth = (int) pf.getImageableWidth();\r
-    int pheight = (int) pf.getImageableHeight();\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      return printWrappedAlignment(pg, pwidth, pheight, pi);\r
-    }\r
-    else\r
-    {\r
-      return printUnwrapped(pg, pwidth, pheight, pi);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param pg DOCUMENT ME!\r
-   * @param pwidth DOCUMENT ME!\r
-   * @param pheight DOCUMENT ME!\r
-   * @param pi DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   *\r
-   * @throws PrinterException DOCUMENT ME!\r
-   */\r
-  public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)\r
-      throws PrinterException\r
-  {\r
-    int idWidth = calculateIdWidth().width + 4;\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-    int scaleHeight = av.charHeight + fm.getDescent();\r
-\r
-    pg.setColor(Color.white);\r
-    pg.fillRect(0, 0, pwidth, pheight);\r
-    pg.setFont(av.getFont());\r
-\r
-    ////////////////////////////////////\r
-    /// How many sequences and residues can we fit on a printable page?\r
-    int totalRes = (pwidth - idWidth) / av.getCharWidth();\r
-\r
-    int totalSeq = (int) ( (pheight - scaleHeight) / av.getCharHeight()) -\r
-        1;\r
-\r
-    int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;\r
-\r
-    /////////////////////////////\r
-    /// Only print these sequences and residues on this page\r
-    int startRes;\r
-\r
-    /////////////////////////////\r
-    /// Only print these sequences and residues on this page\r
-    int endRes;\r
-\r
-    /////////////////////////////\r
-    /// Only print these sequences and residues on this page\r
-    int startSeq;\r
-\r
-    /////////////////////////////\r
-    /// Only print these sequences and residues on this page\r
-    int endSeq;\r
-    startRes = (pi % pagesWide) * totalRes;\r
-    endRes = (startRes + totalRes) - 1;\r
-\r
-    if (endRes > (av.getAlignment().getWidth() - 1))\r
-    {\r
-      endRes = av.getAlignment().getWidth() - 1;\r
-    }\r
-\r
-    startSeq = (pi / pagesWide) * totalSeq;\r
-    endSeq = startSeq + totalSeq;\r
-\r
-    if (endSeq > av.getAlignment().getHeight())\r
-    {\r
-      endSeq = av.getAlignment().getHeight();\r
-    }\r
-\r
-    int pagesHigh = ( (av.alignment.getHeight() / totalSeq) + 1) * pheight;\r
-\r
-    if (av.showAnnotation)\r
-    {\r
-      pagesHigh += annotationPanel.adjustPanelHeight() + 3;\r
-    }\r
-\r
-    pagesHigh /= pheight;\r
-\r
-    if (pi >= (pagesWide * pagesHigh))\r
-    {\r
-      return Printable.NO_SUCH_PAGE;\r
-    }\r
-\r
-    //draw Scale\r
-    pg.translate(idWidth, 0);\r
-    scalePanel.drawScale(pg, startRes, endRes, pwidth - idWidth, scaleHeight);\r
-    pg.translate( -idWidth, scaleHeight);\r
-\r
-    ////////////////\r
-    // Draw the ids\r
-    Color currentColor = null;\r
-    Color currentTextColor = null;\r
-\r
-    pg.setFont(new Font(av.getFont().getName(),\r
-                        Font.ITALIC,\r
-                        av.getFont().getSize()));\r
-    for (int i = startSeq; i < endSeq; i++)\r
-    {\r
-      if ( (av.getSelectionGroup() != null) &&\r
-          av.getSelectionGroup().sequences.contains(\r
-              av.getAlignment().getSequenceAt(i)))\r
-      {\r
-        currentColor = Color.gray;\r
-        currentTextColor = Color.black;\r
-      }\r
-      else\r
-      {\r
-        currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
-        currentTextColor = Color.black;\r
-      }\r
-\r
-      pg.setColor(currentColor);\r
-      pg.fillRect(0, (i - startSeq) * av.charHeight, idWidth,\r
-                  av.getCharHeight());\r
-\r
-      pg.setColor(currentTextColor);\r
-\r
-      String string = av.getAlignment().getSequenceAt(i).getDisplayId\r
-          ( av.getShowJVSuffix());\r
-\r
-      pg.drawString(string, 0,\r
-                    ( ( (i - startSeq) * av.charHeight) + av.getCharHeight()) -\r
-                    (av.getCharHeight() / 5));\r
-    }\r
-\r
-    pg.setFont(av.getFont());\r
-\r
-    // draw main sequence panel\r
-    pg.translate(idWidth, 0);\r
-    seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq, 0);\r
-\r
-    if (av.showAnnotation && (endSeq == av.alignment.getHeight()))\r
-    {\r
-      pg.translate( -idWidth-3, (endSeq - startSeq) * av.charHeight + 3);\r
-      alabels.drawComponent( (Graphics2D) pg, idWidth);\r
-      pg.translate(idWidth+3, 0);\r
-      annotationPanel.drawComponent( (Graphics2D) pg, startRes, endRes +\r
-                                    1);\r
-    }\r
-\r
-    return Printable.PAGE_EXISTS;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param pg DOCUMENT ME!\r
-   * @param pwidth DOCUMENT ME!\r
-   * @param pheight DOCUMENT ME!\r
-   * @param pi DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   *\r
-   * @throws PrinterException DOCUMENT ME!\r
-   */\r
-  public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,\r
-                                   int pi)\r
-      throws PrinterException\r
-  {\r
-\r
-    int annotationHeight = 0;\r
-    AnnotationLabels labels = null;\r
-    if (av.showAnnotation)\r
-    {\r
-      annotationHeight = annotationPanel.adjustPanelHeight();\r
-      labels = new AnnotationLabels(av);\r
-    }\r
-\r
-    int hgap = av.charHeight;\r
-    if (av.scaleAboveWrapped)\r
-      hgap += av.charHeight;\r
-\r
-    int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-        + hgap\r
-        + annotationHeight;\r
-\r
-    int idWidth = calculateIdWidth().width + 4;\r
-\r
-    int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth -\r
-        idWidth);\r
-\r
-    int totalHeight = cHeight * (av.alignment.getWidth() / resWidth + 1);\r
-\r
-    pg.setColor(Color.white);\r
-    pg.fillRect(0, 0, pwidth, pheight);\r
-    pg.setFont(av.getFont());\r
-\r
-    ////////////////\r
-    // Draw the ids\r
-    pg.setColor(Color.black);\r
-\r
-    pg.translate(0, -pi * pheight);\r
-\r
-    pg.setClip(0, pi * pheight, pwidth, pheight);\r
-\r
-    int ypos = hgap;\r
-    Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
-                           av.getFont().getSize());\r
-    pg.setFont(italic);\r
-\r
-    do\r
-    {\r
-      for (int i = 0; i < av.alignment.getHeight(); i++)\r
-      {\r
-        SequenceI s = av.alignment.getSequenceAt(i);\r
-        String string = s.getDisplayId( av.getShowJVSuffix());\r
-\r
-        pg.drawString(string, 0,\r
-                      ( (i * av.charHeight) + ypos + av.charHeight) -\r
-                      (av.charHeight / 5));\r
-      }\r
-      if (labels != null)\r
-      {\r
-        pg.translate(-3,\r
-                     ypos +\r
-                     (av.getAlignment().getHeight() * av.charHeight));\r
-\r
-        pg.setFont(av.getFont());\r
-        labels.drawComponent(pg, idWidth);\r
-        pg.setFont(italic);\r
-        pg.translate(+3,\r
-                     -ypos -\r
-                     (av.getAlignment().getHeight() * av.charHeight));\r
-      }\r
-\r
-      ypos += cHeight;\r
-    }\r
-    while (ypos < totalHeight);\r
-\r
-    pg.translate(idWidth, 0);\r
-\r
-    seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth - idWidth, totalHeight, 0);\r
-\r
-    if ( (pi * pheight) < totalHeight)\r
-    {\r
-      return Printable.PAGE_EXISTS;\r
-\r
-    }\r
-    else\r
-    {\r
-      return Printable.NO_SUCH_PAGE;\r
-    }\r
-  }\r
-\r
-  void makeAlignmentImage(int type, File file)\r
-  {\r
-    int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
-    int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
-\r
-    if (idPanel.getWidth() == 0)\r
-    {\r
-      width += calculateIdWidth().getWidth() + 4;\r
-    }\r
-\r
-    if (av.getWrapAlignment())\r
-    {\r
-      height = getWrappedHeight();\r
-      width = seqPanel.getWidth() + idPanel.getWidth();\r
-    }\r
-    else if (av.getShowAnnotation())\r
-    {\r
-      height += annotationPanel.adjustPanelHeight() + 3;\r
-    }\r
-\r
-    jalview.util.ImageMaker im;\r
-    if(type==jalview.util.ImageMaker.PNG)\r
-      im  = new jalview.util.ImageMaker(this,\r
-                                        jalview.util.ImageMaker.PNG,\r
-                                        "Create PNG image from alignment",\r
-                                        width, height, file, null);\r
-    else\r
-      im = new jalview.util.ImageMaker(this,\r
-                                        jalview.util.ImageMaker.EPS,\r
-                                       "Create EPS file from alignment",\r
-                                        width, height, file, alignFrame.getTitle() );\r
-\r
-    try\r
-    {\r
-      if (av.getWrapAlignment())\r
-      {\r
-        if(im.getGraphics()!=null)\r
-        {\r
-          printWrappedAlignment(im.getGraphics(), width, height, 0);\r
-          im.writeImage();\r
-        }\r
-      }\r
-      else\r
-      {\r
-        if(im.getGraphics()!=null)\r
-        {\r
-          printUnwrapped(im.getGraphics(), width, height, 0);\r
-          im.writeImage();\r
-        }\r
-      }\r
-    }\r
-    catch (OutOfMemoryError err)\r
-    {\r
-      System.out.println("########################\n"\r
-                         + "OUT OF MEMORY " + file + "\n"\r
-                         + "########################");\r
-\r
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                            "Out of Memory Creating Image!!"\r
-                                            +\r
-                                            "\nSee help files for increasing Java Virtual Machine memory."\r
-                                            , "Out of memory",\r
-                                            JOptionPane.WARNING_MESSAGE);\r
-      System.out.println("Create IMAGE: " + err);\r
-      System.gc();\r
-\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-  }\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void makeEPS(File epsFile)\r
-  {\r
-    makeAlignmentImage(jalview.util.ImageMaker.EPS, epsFile);\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void makePNG(File pngFile)\r
-  {\r
-    makeAlignmentImage(jalview.util.ImageMaker.PNG, pngFile);\r
-  }\r
-\r
-  public void makePNGImageMap(File imgMapFile, String imageName)\r
-  {\r
-    ///////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS\r
-    //////////////////////////////////////////////\r
-    int idWidth = calculateIdWidth().width + 4;\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-    int scaleHeight = av.charHeight + fm.getDescent();\r
-\r
-    // Gen image map\r
-    //////////////////////////////////\r
-    if (imgMapFile != null)\r
-    {\r
-      try\r
-      {\r
-        int s, sSize = av.alignment.getHeight(),\r
-            res, alwidth = av.alignment.getWidth(), g, gSize, f, fSize, sy;\r
-        StringBuffer text = new StringBuffer();\r
-        PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));\r
-        out.println(jalview.io.HTMLOutput.getImageMapHTML());\r
-        out.println("<img src=\"" + imageName +\r
-                    "\" border=\"0\" usemap=\"#Map\" >"\r
-                    + "<map name=\"Map\">");\r
-\r
-        for (s = 0; s < sSize; s++)\r
-        {\r
-          sy = s * av.charHeight + scaleHeight;\r
-\r
-          SequenceI seq = av.alignment.getSequenceAt(s);\r
-          SequenceFeature [] features = seq.getDatasetSequence().getSequenceFeatures();\r
-          SequenceGroup[] groups = av.alignment.findAllGroups(seq);\r
-          for(res =0; res<alwidth; res++)\r
-          {\r
-            text = new StringBuffer();\r
-            Object obj = null;\r
-            if(av.alignment.isNucleotide())\r
-              obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res)+"" );\r
-            else\r
-              obj = ResidueProperties.aa2Triplet.get(\r
-                    seq.getCharAt(res) + "");\r
-\r
-              if (obj == null)\r
-                  continue;\r
-\r
-            String triplet = obj.toString();\r
-            int alIndex = seq.findPosition(res);\r
-            gSize = groups.length;\r
-            for (g = 0; g < gSize; g++)\r
-            {\r
-              if(text.length()<1)\r
-              {\r
-                text.append("<area shape=\"rect\" coords=\""\r
-                  + (idWidth + res * av.charWidth) + ","\r
-                  + sy + ","\r
-                  + (idWidth + (res + 1) * av.charWidth) + ","\r
-                  + (av.charHeight + sy) + "\""\r
-                  + " onMouseOver=\"toolTip('"\r
-                  + alIndex + " " + triplet );\r
-              }\r
-\r
-              if(groups[g].getStartRes()<res && groups[g].getEndRes()>res)\r
-                text.append("<br><em>" + groups[g].getName() + "</em>");\r
-            }\r
-\r
-            if (features != null)\r
-            {\r
-              if(text.length()<1)\r
-              {\r
-                text.append("<area shape=\"rect\" coords=\""\r
-                  + (idWidth + res * av.charWidth) + ","\r
-                  + sy + ","\r
-                  + (idWidth + (res + 1) * av.charWidth) + ","\r
-                  + (av.charHeight + sy) + "\""\r
-                  + " onMouseOver=\"toolTip('"\r
-                  + alIndex + " " + triplet );\r
-              }\r
-                fSize = features.length;\r
-                for (f = 0; f < fSize; f++)\r
-                {\r
-\r
-                  if ( (features[f].getBegin() <= seq.findPosition(res)) &&\r
-                      (features[f].getEnd() >= seq.findPosition(res)))\r
-                  {\r
-                    if (features[f].getType().equals("disulfide bond"))\r
-                    {\r
-                      if (features[f].getBegin() == seq.findPosition(res)\r
-                          || features[f].getEnd() == seq.findPosition(res))\r
-                      {\r
-                        text.append("<br>disulfide bond " + features[f].getBegin() + ":" +\r
-                                       features[f].getEnd());\r
-                      }\r
-                    }\r
-                    else\r
-                    {\r
-                      text.append("<br>");\r
-                      text.append(features[f].getType());\r
-                      if (features[f].getDescription() != null && !features[f].getType().equals(features[f].getDescription()))\r
-                        text.append(" " + features[f].getDescription());\r
-\r
-                      if (features[f].getStatus() != null && features[f].getStatus().length()>0)\r
-                      {\r
-                        text.append(" (" + features[f].getStatus() + ")");\r
-                      }\r
-                    }\r
-                  }\r
-\r
-                }\r
-              }\r
-              if(text.length()>1)\r
-              {\r
-                text.append("')\"; onMouseOut=\"toolTip()\";  href=\"#\">");\r
-                out.println(text.toString());\r
-              }\r
-            }\r
-          }\r
-        out.println("</map></body></html>");\r
-        out.close();\r
-\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    } ///////////END OF IMAGE MAP\r
-\r
-  }\r
-\r
-  int getWrappedHeight()\r
-  {\r
-\r
-    int chunkWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(\r
-        seqPanel.seqCanvas.getWidth());\r
-\r
-    int hgap = av.charHeight;\r
-    if (av.scaleAboveWrapped)\r
-      hgap += av.charHeight;\r
-\r
-    int annotationHeight = 0;\r
-    if (av.showAnnotation)\r
-    {\r
-      annotationHeight = annotationPanel.adjustPanelHeight();\r
-    }\r
-\r
-    int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-        + hgap\r
-        + annotationHeight;\r
-\r
-    int height = ( (av.alignment.getWidth() / chunkWidth) + 1) * cHeight;\r
-\r
-    return height;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @author $author$\r
-   * @version $Revision$\r
-   */\r
-  class Preview\r
-      extends JFrame\r
-  {\r
-    /**\r
-     * Creates a new Preview object.\r
-     *\r
-     * @param image DOCUMENT ME!\r
-     */\r
-    public Preview(Image image)\r
-    {\r
-      setResizable(true);\r
-      setSize(image.getWidth(this), image.getHeight(this));\r
-      setVisible(true);\r
-      getContentPane().setLayout(new BorderLayout());\r
-      getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);\r
-      validate();\r
-      repaint();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @author $author$\r
-   * @version $Revision$\r
-   */\r
-  class PreviewPanel\r
-      extends JPanel\r
-  {\r
-    Image image;\r
-\r
-    /**\r
-     * Creates a new PreviewPanel object.\r
-     *\r
-     * @param image DOCUMENT ME!\r
-     */\r
-    public PreviewPanel(Image image)\r
-    {\r
-      this.image = image;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-      if (image != null)\r
-      {\r
-        g.drawImage(image, 0, 0, this);\r
-      }\r
-      else\r
-      {\r
-        System.out.println("DEBUG:image is null");\r
-      }\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.jbgui.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.print.*;
+
+import java.io.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AlignmentPanel extends GAlignmentPanel
+    implements AdjustmentListener, Printable
+{
+  public AlignViewport av;
+  OverviewPanel overviewPanel;
+  SeqPanel seqPanel;
+  IdPanel idPanel;
+  IdwidthAdjuster idwidthAdjuster;
+
+  /** DOCUMENT ME!! */
+  public AlignFrame alignFrame;
+  ScalePanel scalePanel;
+  AnnotationPanel annotationPanel;
+  AnnotationLabels alabels;
+
+  // this value is set false when selection area being dragged
+  boolean fastPaint = true;
+  int hextent = 0;
+  int vextent = 0;
+
+  /**
+   * Creates a new AlignmentPanel object.
+   *
+   * @param af DOCUMENT ME!
+   * @param av DOCUMENT ME!
+   */
+  public AlignmentPanel(AlignFrame af, final AlignViewport av)
+  {
+    alignFrame = af;
+    this.av = av;
+    seqPanel = new SeqPanel(av, this);
+    idPanel = new IdPanel(av, this);
+
+    scalePanel = new ScalePanel(av, this);
+
+    idPanelHolder.add(idPanel, BorderLayout.CENTER);
+    idwidthAdjuster = new IdwidthAdjuster(this);
+    idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);
+
+    annotationPanel = new AnnotationPanel(this);
+    alabels = new AnnotationLabels(this);
+
+
+    annotationScroller.setViewportView(annotationPanel);
+    annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);
+
+    fontChanged();
+
+    scalePanelHolder.add(scalePanel, BorderLayout.CENTER);
+    seqPanelHolder.add(seqPanel, BorderLayout.CENTER);
+
+    setScrollValues(0, 0);
+
+    adjustAnnotationHeight();
+
+    setAnnotationVisible(av.getShowAnnotation());
+
+    hscroll.addAdjustmentListener(this);
+    vscroll.addAdjustmentListener(this);
+
+    af.addKeyListener(new KeyAdapter()
+    {
+      public void keyPressed(KeyEvent evt)
+      {
+        if(av.cursorMode
+           && evt.getKeyCode()>=KeyEvent.VK_0
+           && evt.getKeyCode()<=KeyEvent.VK_9)
+        {
+          seqPanel.numberPressed(evt.getKeyChar());
+        }
+
+        switch (evt.getKeyCode())
+        {
+          case 27: // escape key
+            alignFrame.deselectAllSequenceMenuItem_actionPerformed(null);
+
+            break;
+
+          case KeyEvent.VK_DOWN:
+            if(av.cursorMode)
+            {
+              seqPanel.moveCursor(0,1);
+            }
+            else
+              alignFrame.moveSelectedSequences(false);
+            break;
+
+          case KeyEvent.VK_UP:
+            if (av.cursorMode)
+            {
+              seqPanel.moveCursor(0,-1);
+            }
+            else
+              alignFrame.moveSelectedSequences(true);
+            break;
+
+          case KeyEvent.VK_LEFT:
+            if(av.cursorMode)
+            {
+              seqPanel.moveCursor(-1,0);
+            }
+            break;
+
+          case KeyEvent.VK_RIGHT:
+            if (av.cursorMode)
+            {
+              seqPanel.moveCursor(1,0);
+            }
+            break;
+
+          case KeyEvent.VK_SPACE:
+            if(av.cursorMode)
+            {
+              seqPanel.insertGapAtCursor(evt.isControlDown() || evt.isShiftDown());
+            }
+            break;
+
+          case KeyEvent.VK_DELETE:
+          case KeyEvent.VK_BACK_SPACE:
+            if(!av.cursorMode)
+            {
+              alignFrame.cut_actionPerformed(null);
+            }
+            else
+              seqPanel.deleteGapAtCursor(evt.isControlDown() || evt.isShiftDown());
+
+            break;
+
+          case KeyEvent.VK_S:
+            if(av.cursorMode)
+            {
+              seqPanel.setCursorRow();
+            }
+            break;
+          case KeyEvent.VK_C:
+            if(av.cursorMode && !evt.isControlDown())
+            {
+              seqPanel.setCursorColumn();
+            }
+            break;
+          case KeyEvent.VK_P:
+            if(av.cursorMode)
+            {
+              seqPanel.setCursorPosition();
+            }
+            break;
+
+          case KeyEvent.VK_ENTER:
+          case KeyEvent.VK_COMMA:
+            if(av.cursorMode)
+            {
+              seqPanel.setCursorRowAndColumn();
+            }
+            break;
+
+          case KeyEvent.VK_Q:
+            if(av.cursorMode)
+            {
+              seqPanel.setSelectionAreaAtCursor(true);
+            }
+            break;
+          case KeyEvent.VK_M:
+            if(av.cursorMode)
+            {
+              seqPanel.setSelectionAreaAtCursor(false);
+            }
+            break;
+
+         case KeyEvent.VK_F2:
+           av.cursorMode = ! av.cursorMode;
+           alignFrame.statusBar.setText("Keyboard editing mode is "+
+               (av.cursorMode ? "on" : "off"));
+           if(av.cursorMode)
+           {
+             seqPanel.seqCanvas.cursorX = av.startRes;
+             seqPanel.seqCanvas.cursorY = av.startSeq;
+           }
+           seqPanel.seqCanvas.repaint();
+           break;
+
+          case KeyEvent.VK_F1:
+            try
+            {
+              ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
+              java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
+              javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
+
+              javax.help.HelpBroker hb = hs.createHelpBroker();
+              hb.setCurrentID("home");
+              hb.setDisplayed(true);
+            }
+            catch (Exception ex)
+            {
+              ex.printStackTrace();
+            }
+            break;
+          case KeyEvent.VK_H:
+          {
+            boolean toggleSeqs = !evt.isControlDown();
+            boolean toggleCols = !evt.isShiftDown();
+
+            boolean hide = false;
+
+            SequenceGroup sg = av.getSelectionGroup();
+            if(toggleSeqs)
+             {
+               if(sg != null && sg.getSize(false) != av.alignment.getHeight())
+               {
+                 alignFrame.hideSelSequences_actionPerformed(null);
+                 hide = true;
+               }
+               else if (!(toggleCols && av.colSel.getSelected().size() > 0))
+                 alignFrame.showAllSeqs_actionPerformed(null);
+             }
+
+             if (toggleCols)
+             {
+               if(av.colSel.getSelected().size() > 0)
+               {
+                 alignFrame.hideSelColumns_actionPerformed(null);
+                 if(!toggleSeqs)
+                   av.selectionGroup = sg;
+               }
+               else if(!hide)
+                 alignFrame.showAllColumns_actionPerformed(null);
+             }
+            break;
+          }
+
+        }
+      }
+    });
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void fontChanged()
+  {
+    // set idCanvas bufferedImage to null
+    // to prevent drawing old image
+    FontMetrics fm = getFontMetrics(av.getFont());
+
+    scalePanelHolder.setPreferredSize(new Dimension(10,
+        av.charHeight + fm.getDescent()));
+    idSpaceFillerPanel1.setPreferredSize(new Dimension(10,
+        av.charHeight + fm.getDescent()));
+
+    idPanel.idCanvas.gg = null;
+    seqPanel.seqCanvas.img = null;
+    annotationPanel.adjustPanelHeight();
+
+    Dimension d = calculateIdWidth();
+    d.setSize(d.width + 4, d.height);
+    idPanel.idCanvas.setPreferredSize(d);
+    hscrollFillerPanel.setPreferredSize(d);
+
+    if (av.getWrapAlignment())
+    {
+      int max = av.alignment.getWidth() /
+          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
+      vscroll.setMaximum(max);
+      vscroll.setUnitIncrement(1);
+      vscroll.setVisibleAmount(1);
+    }
+    else
+    {
+      setScrollValues(av.getStartRes(), av.getStartSeq());
+    }
+
+    if (overviewPanel != null)
+      overviewPanel.setBoxPosition();
+
+    repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public Dimension calculateIdWidth()
+  {
+    Container c = new Container();
+
+    FontMetrics fm = c.getFontMetrics(av.font);
+    AlignmentI al = av.getAlignment();
+
+    int i = 0;
+    int idWidth = 0;
+    String id;
+
+    while ( (i < al.getHeight()) && (al.getSequenceAt(i) != null))
+    {
+      SequenceI s = al.getSequenceAt(i);
+
+      id = s.getDisplayId(av.getShowJVSuffix());
+
+      if (fm.stringWidth(id) > idWidth)
+      {
+        idWidth = fm.stringWidth(id);
+      }
+
+      i++;
+    }
+
+    // Also check annotation label widths
+    i = 0;
+
+    if (al.getAlignmentAnnotation() != null)
+    {
+      fm = c.getFontMetrics(alabels.getFont());
+
+      while (i < al.getAlignmentAnnotation().length)
+      {
+        String label = al.getAlignmentAnnotation()[i].label;
+
+        if (fm.stringWidth(label) > idWidth)
+        {
+          idWidth = fm.stringWidth(label);
+        }
+
+        i++;
+      }
+    }
+
+    return new Dimension(idWidth, 12);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param results DOCUMENT ME!
+   */
+  public void highlightSearchResults(SearchResults results)
+  {
+    seqPanel.seqCanvas.highlightSearchResults(results);
+
+    // do we need to scroll the panel?
+    if (results != null)
+    {
+      SequenceI seq = results.getResultSequence(0);
+      int seqIndex = av.alignment.findIndex(seq);
+      int start = seq.findIndex(results.getResultStart(0)) - 1;
+      int end = seq.findIndex(results.getResultEnd(0)) - 1;
+
+      if(!av.wrapAlignment)
+      {
+        if ( (av.getStartRes() > end)  || (av.getEndRes() < start) ||
+           ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
+        {
+          setScrollValues(start, seqIndex);
+        }
+      }
+      else
+      {
+        scrollToWrappedVisible(start);
+      }
+    }
+  }
+
+  void scrollToWrappedVisible(int res)
+  {
+    int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
+    if( res<=av.getStartRes() || res>=(av.getStartRes()+cwidth) )
+    {
+      vscroll.setValue(res / cwidth);
+      av.startRes = vscroll.getValue() * cwidth;
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public OverviewPanel getOverviewPanel()
+  {
+    return overviewPanel;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param op DOCUMENT ME!
+   */
+  public void setOverviewPanel(OverviewPanel op)
+  {
+    overviewPanel = op;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  public void setAnnotationVisible(boolean b)
+  {
+    if (!av.wrapAlignment)
+    {
+      annotationSpaceFillerHolder.setVisible(b);
+      annotationScroller.setVisible(b);
+    }
+    repaint();
+  }
+
+  public void adjustAnnotationHeight()
+  {
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      public void run()
+      {
+          while(alignFrame.getHeight()==0)
+          {
+            Thread.yield();
+          }
+
+        int height = annotationPanel.adjustPanelHeight();
+
+        if (height > alignFrame.getHeight() / 2)
+        {
+          height = alignFrame.getHeight() / 2;
+        }
+
+        annotationScroller.setPreferredSize(
+            new Dimension(annotationScroller.getWidth(),
+                          height));
+
+        annotationSpaceFillerHolder.setPreferredSize(new Dimension(
+            annotationSpaceFillerHolder.getWidth(),
+            height));
+
+        annotationPanel.repaint();
+        repaint();
+      }
+    });
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param wrap DOCUMENT ME!
+   */
+  public void setWrapAlignment(boolean wrap)
+  {
+    av.startSeq = 0;
+    scalePanelHolder.setVisible(!wrap);
+    hscroll.setVisible(!wrap);
+    idwidthAdjuster.setVisible(!wrap);
+
+    if (wrap)
+    {
+      annotationScroller.setVisible(false);
+      annotationSpaceFillerHolder.setVisible(false);
+    }
+    else if (av.showAnnotation)
+    {
+      annotationScroller.setVisible(true);
+      annotationSpaceFillerHolder.setVisible(true);
+    }
+
+    idSpaceFillerPanel1.setVisible(!wrap);
+
+    repaint();
+  }
+
+  // return value is true if the scroll is valid
+  public boolean scrollUp(boolean up)
+  {
+    if (up)
+    {
+      if (vscroll.getValue() < 1)
+      {
+        return false;
+      }
+
+      fastPaint = false;
+      vscroll.setValue(vscroll.getValue() - 1);
+    }
+    else
+    {
+      if ( (vextent + vscroll.getValue()) >= av.getAlignment().getHeight())
+      {
+        return false;
+      }
+
+      fastPaint = false;
+      vscroll.setValue(vscroll.getValue() + 1);
+    }
+
+    fastPaint = true;
+
+    return true;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param right DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean scrollRight(boolean right)
+  {
+    if (!right)
+    {
+      if (hscroll.getValue() < 1)
+      {
+        return false;
+      }
+
+      fastPaint = false;
+      hscroll.setValue(hscroll.getValue() - 1);
+    }
+    else
+    {
+      if ( (hextent + hscroll.getValue()) >= av.getAlignment().getWidth())
+      {
+        return false;
+      }
+
+      fastPaint = false;
+      hscroll.setValue(hscroll.getValue() + 1);
+    }
+
+    fastPaint = true;
+
+    return true;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param x DOCUMENT ME!
+   * @param y DOCUMENT ME!
+   */
+  public void setScrollValues(int x, int y)
+  {
+
+    int width = av.alignment.getWidth();
+    int height = av.alignment.getHeight();
+
+    if(av.hasHiddenColumns)
+     width = av.getColumnSelection().findColumnPosition(width);
+
+    av.setEndRes( (x + (seqPanel.seqCanvas.getWidth() / av.charWidth)) -1);
+
+    hextent = seqPanel.seqCanvas.getWidth() / av.charWidth;
+    vextent = seqPanel.seqCanvas.getHeight() / av.charHeight;
+
+    if (hextent > width)
+    {
+      hextent = width;
+    }
+
+    if (vextent > height)
+    {
+      vextent = height;
+    }
+
+    if ( (hextent + x) > width)
+    {
+      x = width - hextent;
+    }
+
+    if ( (vextent + y) > height)
+    {
+      y = height - vextent;
+    }
+
+    if (y < 0)
+    {
+      y = 0;
+    }
+
+    if (x < 0)
+    {
+      x = 0;
+    }
+
+    hscroll.setValues(x, hextent, 0, width);
+    vscroll.setValues(y, vextent, 0, height);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param evt DOCUMENT ME!
+   */
+  public void adjustmentValueChanged(AdjustmentEvent evt)
+  {
+
+    int oldX = av.getStartRes();
+    int oldY = av.getStartSeq();
+
+    if (evt.getSource() == hscroll)
+    {
+      int x = hscroll.getValue();
+      av.setStartRes(x);
+      av.setEndRes( (x +
+                     (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) - 1);
+    }
+
+    if (evt.getSource() == vscroll)
+    {
+      int offy = vscroll.getValue();
+
+      if (av.getWrapAlignment())
+      {
+        if(offy>-1)
+        {
+          int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.
+              seqCanvas.getWidth());
+          av.setStartRes(offy * rowSize);
+          av.setEndRes( (offy + 1) * rowSize);
+        }
+        else
+        {
+          //This is only called if file loaded is a jar file that
+          //was wrapped when saved and user has wrap alignment true
+          //as preference setting
+          SwingUtilities.invokeLater(new Runnable()
+              {
+                public void run()
+                {
+                  setScrollValues(av.getStartRes(), av.getStartSeq());
+                }
+              });
+        }
+      }
+      else
+      {
+        av.setStartSeq(offy);
+        av.setEndSeq(offy +
+                     (seqPanel.seqCanvas.getHeight() / av.getCharHeight()));
+      }
+    }
+
+    if (overviewPanel != null)
+    {
+      overviewPanel.setBoxPosition();
+    }
+
+    int scrollX = av.startRes - oldX;
+    int scrollY = av.startSeq - oldY;
+
+    if (av.getWrapAlignment() || !fastPaint)
+    {
+      repaint();
+    }
+    else
+    {
+      // Make sure we're not trying to draw a panel
+      // larger than the visible window
+      if(scrollX>av.endRes-av.startRes)
+        scrollX = av.endRes-av.startRes;
+      else if(scrollX<av.startRes-av.endRes)
+        scrollX = av.startRes - av.endRes;
+
+      if(scrollX!=0 || scrollY!=0)
+      {
+        idPanel.idCanvas.fastPaint(scrollY);
+        seqPanel.seqCanvas.fastPaint(scrollX,
+                                     scrollY);
+        scalePanel.repaint();
+
+        if (av.getShowAnnotation())
+        {
+          annotationPanel.fastPaint(scrollX);
+        }
+      }
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param g DOCUMENT ME!
+   */
+  public void paintComponent(Graphics g)
+  {
+    invalidate();
+
+    Dimension d = idPanel.idCanvas.getPreferredSize();
+    idPanelHolder.setPreferredSize(d);
+    hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));
+    validate();
+
+    if (av.getWrapAlignment())
+    {
+      int maxwidth = av.alignment.getWidth();
+
+      if (av.hasHiddenColumns)
+        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+      int max = maxwidth /
+          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth()) +
+          1;
+
+
+      vscroll.setMaximum(max);
+      vscroll.setUnitIncrement(1);
+      vscroll.setVisibleAmount(1);
+    }
+    else
+    {
+      setScrollValues(av.getStartRes(), av.getStartSeq());
+    }
+
+    if( this.getVisibleRect().getBounds() == g.getClipBounds()
+        && overviewPanel != null)
+        overviewPanel.updateOverviewImage();
+
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param pg DOCUMENT ME!
+   * @param pf DOCUMENT ME!
+   * @param pi DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   *
+   * @throws PrinterException DOCUMENT ME!
+   */
+  public int print(Graphics pg, PageFormat pf, int pi)
+      throws PrinterException
+  {
+    pg.translate( (int) pf.getImageableX(), (int) pf.getImageableY());
+
+    int pwidth = (int) pf.getImageableWidth();
+    int pheight = (int) pf.getImageableHeight();
+
+    if (av.getWrapAlignment())
+    {
+      return printWrappedAlignment(pg, pwidth, pheight, pi);
+    }
+    else
+    {
+      return printUnwrapped(pg, pwidth, pheight, pi);
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param pg DOCUMENT ME!
+   * @param pwidth DOCUMENT ME!
+   * @param pheight DOCUMENT ME!
+   * @param pi DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   *
+   * @throws PrinterException DOCUMENT ME!
+   */
+  public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)
+      throws PrinterException
+  {
+    int idWidth = calculateIdWidth().width + 4;
+    FontMetrics fm = getFontMetrics(av.getFont());
+    int scaleHeight = av.charHeight + fm.getDescent();
+
+    pg.setColor(Color.white);
+    pg.fillRect(0, 0, pwidth, pheight);
+    pg.setFont(av.getFont());
+
+    ////////////////////////////////////
+    /// How many sequences and residues can we fit on a printable page?
+    int totalRes = (pwidth - idWidth) / av.getCharWidth();
+
+    int totalSeq = (int) ( (pheight - scaleHeight) / av.getCharHeight()) -
+        1;
+
+    int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
+
+    /////////////////////////////
+    /// Only print these sequences and residues on this page
+    int startRes;
+
+    /////////////////////////////
+    /// Only print these sequences and residues on this page
+    int endRes;
+
+    /////////////////////////////
+    /// Only print these sequences and residues on this page
+    int startSeq;
+
+    /////////////////////////////
+    /// Only print these sequences and residues on this page
+    int endSeq;
+    startRes = (pi % pagesWide) * totalRes;
+    endRes = (startRes + totalRes) - 1;
+
+    if (endRes > (av.getAlignment().getWidth() - 1))
+    {
+      endRes = av.getAlignment().getWidth() - 1;
+    }
+
+    startSeq = (pi / pagesWide) * totalSeq;
+    endSeq = startSeq + totalSeq;
+
+    if (endSeq > av.getAlignment().getHeight())
+    {
+      endSeq = av.getAlignment().getHeight();
+    }
+
+    int pagesHigh = ( (av.alignment.getHeight() / totalSeq) + 1) * pheight;
+
+    if (av.showAnnotation)
+    {
+      pagesHigh += annotationPanel.adjustPanelHeight() + 3;
+    }
+
+    pagesHigh /= pheight;
+
+    if (pi >= (pagesWide * pagesHigh))
+    {
+      return Printable.NO_SUCH_PAGE;
+    }
+
+    //draw Scale
+    pg.translate(idWidth, 0);
+    scalePanel.drawScale(pg, startRes, endRes, pwidth - idWidth, scaleHeight);
+    pg.translate( -idWidth, scaleHeight);
+
+    ////////////////
+    // Draw the ids
+    Color currentColor = null;
+    Color currentTextColor = null;
+
+    pg.setFont(new Font(av.getFont().getName(),
+                        Font.ITALIC,
+                        av.getFont().getSize()));
+    for (int i = startSeq; i < endSeq; i++)
+    {
+      if ( (av.getSelectionGroup() != null) &&
+          av.getSelectionGroup().getSequences(false).contains(
+              av.getAlignment().getSequenceAt(i)))
+      {
+        currentColor = Color.gray;
+        currentTextColor = Color.black;
+      }
+      else
+      {
+        currentColor = av.getAlignment().getSequenceAt(i).getColor();
+        currentTextColor = Color.black;
+      }
+
+      pg.setColor(currentColor);
+      pg.fillRect(0, (i - startSeq) * av.charHeight, idWidth,
+                  av.getCharHeight());
+
+      pg.setColor(currentTextColor);
+
+      String string = av.getAlignment().getSequenceAt(i).getDisplayId
+          ( av.getShowJVSuffix());
+
+      pg.drawString(string, 0,
+                    ( ( (i - startSeq) * av.charHeight) + av.getCharHeight()) -
+                    (av.getCharHeight() / 5));
+    }
+
+    pg.setFont(av.getFont());
+
+    // draw main sequence panel
+    pg.translate(idWidth, 0);
+    seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq, 0);
+
+    if (av.showAnnotation && (endSeq == av.alignment.getHeight()))
+    {
+      pg.translate( -idWidth-3, (endSeq - startSeq) * av.charHeight + 3);
+      alabels.drawComponent( (Graphics2D) pg, idWidth);
+      pg.translate(idWidth+3, 0);
+      annotationPanel.drawComponent( (Graphics2D) pg, startRes, endRes +
+                                    1);
+    }
+
+    return Printable.PAGE_EXISTS;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param pg DOCUMENT ME!
+   * @param pwidth DOCUMENT ME!
+   * @param pheight DOCUMENT ME!
+   * @param pi DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   *
+   * @throws PrinterException DOCUMENT ME!
+   */
+  public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,
+                                   int pi)
+      throws PrinterException
+  {
+
+    int annotationHeight = 0;
+    AnnotationLabels labels = null;
+    if (av.showAnnotation)
+    {
+      annotationHeight = annotationPanel.adjustPanelHeight();
+      labels = new AnnotationLabels(av);
+    }
+
+    int hgap = av.charHeight;
+    if (av.scaleAboveWrapped)
+      hgap += av.charHeight;
+
+    int cHeight = av.getAlignment().getHeight() * av.charHeight
+        + hgap
+        + annotationHeight;
+
+    int idWidth = calculateIdWidth().width + 4;
+
+    int maxwidth = av.alignment.getWidth();
+    if (av.hasHiddenColumns)
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+
+    int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth -
+        idWidth);
+
+    int totalHeight = cHeight * (maxwidth / resWidth + 1);
+
+    pg.setColor(Color.white);
+    pg.fillRect(0, 0, pwidth, pheight);
+    pg.setFont(av.getFont());
+
+    ////////////////
+    // Draw the ids
+    pg.setColor(Color.black);
+
+    pg.translate(0, -pi * pheight);
+
+    pg.setClip(0, pi * pheight, pwidth, pheight);
+
+    int ypos = hgap;
+    Font italic = new Font(av.getFont().getName(), Font.ITALIC,
+                           av.getFont().getSize());
+    pg.setFont(italic);
+
+    do
+    {
+      for (int i = 0; i < av.alignment.getHeight(); i++)
+      {
+        SequenceI s = av.alignment.getSequenceAt(i);
+        String string = s.getDisplayId( av.getShowJVSuffix());
+
+        pg.drawString(string, 0,
+                      ( (i * av.charHeight) + ypos + av.charHeight) -
+                      (av.charHeight / 5));
+      }
+      if (labels != null)
+      {
+        pg.translate(-3,
+                     ypos +
+                     (av.getAlignment().getHeight() * av.charHeight));
+
+        pg.setFont(av.getFont());
+        labels.drawComponent(pg, idWidth);
+        pg.setFont(italic);
+        pg.translate(+3,
+                     -ypos -
+                     (av.getAlignment().getHeight() * av.charHeight));
+      }
+
+      ypos += cHeight;
+    }
+    while (ypos < totalHeight);
+
+    pg.translate(idWidth, 0);
+
+    seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth - idWidth, totalHeight, 0);
+
+    if ( (pi * pheight) < totalHeight)
+    {
+      return Printable.PAGE_EXISTS;
+
+    }
+    else
+    {
+      return Printable.NO_SUCH_PAGE;
+    }
+  }
+
+  void makeAlignmentImage(int type, File file)
+  {
+    int maxwidth = av.alignment.getWidth();
+    if (av.hasHiddenColumns)
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);
+
+    int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;
+    int width = idPanel.getWidth() + (maxwidth * av.charWidth);
+    if (idPanel.getWidth() == 0)
+    {
+      width += calculateIdWidth().getWidth() + 4;
+    }
+
+    if (av.getWrapAlignment())
+    {
+      height = getWrappedHeight();
+      if (System.getProperty("java.awt.headless") != null
+          && System.getProperty("java.awt.headless").equals("true"))
+      {
+        width = alignFrame.getWidth() - 22;
+      }
+      else
+        width = seqPanel.getWidth() + idPanel.getWidth();
+
+    }
+    else if (av.getShowAnnotation())
+    {
+      height += annotationPanel.adjustPanelHeight() + 3;
+    }
+
+    jalview.util.ImageMaker im;
+    if(type==jalview.util.ImageMaker.PNG)
+      im  = new jalview.util.ImageMaker(this,
+                                        jalview.util.ImageMaker.PNG,
+                                        "Create PNG image from alignment",
+                                        width, height, file, null);
+    else
+      im = new jalview.util.ImageMaker(this,
+                                        jalview.util.ImageMaker.EPS,
+                                       "Create EPS file from alignment",
+                                        width, height, file, alignFrame.getTitle() );
+
+    try
+    {
+      if (av.getWrapAlignment())
+      {
+        if(im.getGraphics()!=null)
+        {
+          printWrappedAlignment(im.getGraphics(), width, height, 0);
+          im.writeImage();
+        }
+      }
+      else
+      {
+        if(im.getGraphics()!=null)
+        {
+          printUnwrapped(im.getGraphics(), width, height, 0);
+          im.writeImage();
+        }
+      }
+    }
+    catch (OutOfMemoryError err)
+    {
+      System.out.println("########################\n"
+                         + "OUT OF MEMORY " + file + "\n"
+                         + "########################");
+
+      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                            "Out of Memory Creating Image!!"
+                                            +
+                                            "\nSee help files for increasing Java Virtual Machine memory."
+                                            , "Out of memory",
+                                            JOptionPane.WARNING_MESSAGE);
+      System.out.println("Create IMAGE: " + err);
+      System.gc();
+
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+  /**
+   * DOCUMENT ME!
+   */
+  public void makeEPS(File epsFile)
+  {
+    makeAlignmentImage(jalview.util.ImageMaker.EPS, epsFile);
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void makePNG(File pngFile)
+  {
+    makeAlignmentImage(jalview.util.ImageMaker.PNG, pngFile);
+  }
+
+  public void makePNGImageMap(File imgMapFile, String imageName)
+  {
+    ///////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS
+    //////////////////////////////////////////////
+    int idWidth = calculateIdWidth().width + 4;
+    FontMetrics fm = getFontMetrics(av.getFont());
+    int scaleHeight = av.charHeight + fm.getDescent();
+
+    // Gen image map
+    //////////////////////////////////
+    if (imgMapFile != null)
+    {
+      try
+      {
+        int s, sSize = av.alignment.getHeight(),
+            res, alwidth = av.alignment.getWidth(), g, gSize, f, fSize, sy;
+        StringBuffer text = new StringBuffer();
+        PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
+        out.println(jalview.io.HTMLOutput.getImageMapHTML());
+        out.println("<img src=\"" + imageName +
+                    "\" border=\"0\" usemap=\"#Map\" >"
+                    + "<map name=\"Map\">");
+
+        for (s = 0; s < sSize; s++)
+        {
+          sy = s * av.charHeight + scaleHeight;
+
+          SequenceI seq = av.alignment.getSequenceAt(s);
+          SequenceFeature [] features = seq.getDatasetSequence().getSequenceFeatures();
+          SequenceGroup[] groups = av.alignment.findAllGroups(seq);
+          for(res =0; res<alwidth; res++)
+          {
+            text = new StringBuffer();
+            Object obj = null;
+            if(av.alignment.isNucleotide())
+              obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res)+"" );
+            else
+              obj = ResidueProperties.aa2Triplet.get(
+                    seq.getCharAt(res) + "");
+
+              if (obj == null)
+                  continue;
+
+            String triplet = obj.toString();
+            int alIndex = seq.findPosition(res);
+            gSize = groups.length;
+            for (g = 0; g < gSize; g++)
+            {
+              if(text.length()<1)
+              {
+                text.append("<area shape=\"rect\" coords=\""
+                  + (idWidth + res * av.charWidth) + ","
+                  + sy + ","
+                  + (idWidth + (res + 1) * av.charWidth) + ","
+                  + (av.charHeight + sy) + "\""
+                  + " onMouseOver=\"toolTip('"
+                  + alIndex + " " + triplet );
+              }
+
+              if(groups[g].getStartRes()<res && groups[g].getEndRes()>res)
+                text.append("<br><em>" + groups[g].getName() + "</em>");
+            }
+
+            if (features != null)
+            {
+              if(text.length()<1)
+              {
+                text.append("<area shape=\"rect\" coords=\""
+                  + (idWidth + res * av.charWidth) + ","
+                  + sy + ","
+                  + (idWidth + (res + 1) * av.charWidth) + ","
+                  + (av.charHeight + sy) + "\""
+                  + " onMouseOver=\"toolTip('"
+                  + alIndex + " " + triplet );
+              }
+                fSize = features.length;
+                for (f = 0; f < fSize; f++)
+                {
+
+                  if ( (features[f].getBegin() <= seq.findPosition(res)) &&
+                      (features[f].getEnd() >= seq.findPosition(res)))
+                  {
+                    if (features[f].getType().equals("disulfide bond"))
+                    {
+                      if (features[f].getBegin() == seq.findPosition(res)
+                          || features[f].getEnd() == seq.findPosition(res))
+                      {
+                        text.append("<br>disulfide bond " + features[f].getBegin() + ":" +
+                                       features[f].getEnd());
+                      }
+                    }
+                    else
+                    {
+                      text.append("<br>");
+                      text.append(features[f].getType());
+                      if (features[f].getDescription() != null && !features[f].getType().equals(features[f].getDescription()))
+                        text.append(" " + features[f].getDescription());
+
+                      if (features[f].getValue("status") != null )
+                      {
+                        text.append(" (" + features[f].getValue("status") + ")");
+                      }
+                    }
+                  }
+
+                }
+              }
+              if(text.length()>1)
+              {
+                text.append("')\"; onMouseOut=\"toolTip()\";  href=\"#\">");
+                out.println(text.toString());
+              }
+            }
+          }
+        out.println("</map></body></html>");
+        out.close();
+
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    } ///////////END OF IMAGE MAP
+
+  }
+
+  int getWrappedHeight()
+  {
+    int seqPanelWidth = seqPanel.seqCanvas.getWidth();
+
+    //If headless, seqPanel will have 0 width
+    if (System.getProperty("java.awt.headless") != null
+              && System.getProperty("java.awt.headless").equals("true"))
+    {
+      int idWidth = calculateIdWidth().width + 4;
+      seqPanelWidth = alignFrame.getWidth() - idWidth;
+    }
+
+    int chunkWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(
+        seqPanelWidth
+          );
+
+    int hgap = av.charHeight;
+    if (av.scaleAboveWrapped)
+      hgap += av.charHeight;
+
+    int annotationHeight = 0;
+    if (av.showAnnotation)
+    {
+      annotationHeight = annotationPanel.adjustPanelHeight();
+    }
+
+    int cHeight = av.getAlignment().getHeight() * av.charHeight
+        + hgap
+        + annotationHeight;
+
+    int maxwidth = av.alignment.getWidth();
+    if (av.hasHiddenColumns)
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+
+    int height = ( (maxwidth / chunkWidth) + 1) * cHeight;
+
+    return height;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @author $author$
+   * @version $Revision$
+   */
+  class Preview
+      extends JFrame
+  {
+    /**
+     * Creates a new Preview object.
+     *
+     * @param image DOCUMENT ME!
+     */
+    public Preview(Image image)
+    {
+      setResizable(true);
+      setSize(image.getWidth(this), image.getHeight(this));
+      setVisible(true);
+      getContentPane().setLayout(new BorderLayout());
+      getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);
+      validate();
+      repaint();
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @author $author$
+   * @version $Revision$
+   */
+  class PreviewPanel
+      extends JPanel
+  {
+    Image image;
+
+    /**
+     * Creates a new PreviewPanel object.
+     *
+     * @param image DOCUMENT ME!
+     */
+    public PreviewPanel(Image image)
+    {
+      this.image = image;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+      if (image != null)
+      {
+        g.drawImage(image, 0, 0, this);
+      }
+      else
+      {
+        System.out.println("DEBUG:image is null");
+      }
+    }
+  }
+}
index d49a4b6..3881fa9 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.gui;\r
-\r
-import javax.swing.*;\r
-import java.awt.event.*;\r
-import java.awt.*;\r
-\r
-import jalview.schemes.*;\r
-import javax.swing.event.*;\r
-import java.util.*;\r
-import jalview.datamodel.SequenceGroup;\r
-\r
-public class AnnotationColourChooser\r
-    extends JPanel\r
-{\r
-  JInternalFrame frame;\r
-  AlignViewport av;\r
-  AlignmentPanel ap;\r
-  ColourSchemeI oldcs;\r
-  Hashtable oldgroupColours;\r
-  jalview.datamodel.AlignmentAnnotation currentAnnotation;\r
-  boolean adjusting = false;\r
-\r
-  public AnnotationColourChooser(AlignViewport av, AlignmentPanel ap)\r
-  {\r
-    oldcs = av.getGlobalColourScheme();\r
-    if (av.alignment.getGroups() != null)\r
-    {\r
-      oldgroupColours = new Hashtable();\r
-      Vector allGroups = ap.av.alignment.getGroups();\r
-      SequenceGroup sg;\r
-      for (int g = 0; g < allGroups.size(); g++)\r
-      {\r
-        sg = (SequenceGroup) allGroups.get(g);\r
-        oldgroupColours.put(sg, sg.cs);\r
-      }\r
-    }\r
-    this.av = av;\r
-    this.ap = ap;\r
-    frame = new JInternalFrame();\r
-    frame.setContentPane(this);\r
-    frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
-    Desktop.addInternalFrame(frame, "Colour by Annotation", 480, 145);\r
-\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-\r
-    slider.addChangeListener(new ChangeListener()\r
-    {\r
-      public void stateChanged(ChangeEvent evt)\r
-      {\r
-        if(!adjusting)\r
-        {\r
-          thresholdValue.setText( ( (float) slider.getValue() / 1000f) + "");\r
-          valueChanged();\r
-        }\r
-      }\r
-    });\r
-\r
-    if (av.alignment.getAlignmentAnnotation() == null)\r
-      return;\r
-\r
-    if (oldcs instanceof AnnotationColourGradient)\r
-    {\r
-      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;\r
-      minColour.setBackground(acg.getMinColour());\r
-      maxColour.setBackground(acg.getMaxColour());\r
-    }\r
-    else\r
-    {\r
-      minColour.setBackground(Color.orange);\r
-      maxColour.setBackground(Color.red);\r
-    }\r
-\r
-    adjusting = true;\r
-    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if (av.alignment.getAlignmentAnnotation()[i].graph > 0)\r
-        annotations.addItem(av.alignment.getAlignmentAnnotation()[i].label);\r
-    }\r
-\r
-    threshold.addItem("No Threshold");\r
-    threshold.addItem("Above Threshold");\r
-    threshold.addItem("Below Threshold");\r
-\r
-    adjusting = false;\r
-\r
-    changeColour();\r
-\r
-  }\r
-\r
-  public AnnotationColourChooser()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    minColour.setToolTipText("");\r
-    minColour.setMargin(new Insets(2, 2, 2, 2));\r
-    minColour.setText("Min Colour");\r
-    minColour.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        minColour_actionPerformed(e);\r
-      }\r
-    });\r
-    maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    maxColour.setMargin(new Insets(2, 2, 2, 2));\r
-    maxColour.setText("Max Colour");\r
-    maxColour.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        maxColour_actionPerformed(e);\r
-      }\r
-    });\r
-    ok.setOpaque(false);\r
-    ok.setText("OK");\r
-    ok.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        ok_actionPerformed(e);\r
-      }\r
-    });\r
-    cancel.setOpaque(false);\r
-    cancel.setText("Cancel");\r
-    cancel.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        cancel_actionPerformed(e);\r
-      }\r
-    });\r
-    this.setLayout(borderLayout1);\r
-    jPanel2.setLayout(flowLayout1);\r
-    annotations.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        annotations_actionPerformed(e);\r
-      }\r
-    });\r
-    jPanel1.setBackground(Color.white);\r
-    jPanel2.setBackground(Color.white);\r
-    threshold.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        threshold_actionPerformed(e);\r
-      }\r
-    });\r
-    jPanel3.setLayout(flowLayout2);\r
-    thresholdValue.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        thresholdValue_actionPerformed(e);\r
-      }\r
-    });\r
-    slider.setPaintLabels(false);\r
-    slider.setPaintTicks(true);\r
-    slider.setBackground(Color.white);\r
-    slider.setEnabled(false);\r
-    slider.setOpaque(false);\r
-    slider.setPreferredSize(new Dimension(150, 32));\r
-    thresholdValue.setEnabled(false);\r
-    thresholdValue.setColumns(10);\r
-    jPanel3.setBackground(Color.white);\r
-    currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    currentColours.setOpaque(false);\r
-    currentColours.setText("Use Original Colours");\r
-    currentColours.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        currentColours_actionPerformed(e);\r
-      }\r
-    });\r
-    jPanel1.add(ok);\r
-    jPanel1.add(cancel);\r
-    jPanel2.add(annotations);\r
-    jPanel2.add(currentColours);\r
-    jPanel2.add(minColour);\r
-    jPanel2.add(maxColour);\r
-    this.add(jPanel3, java.awt.BorderLayout.CENTER);\r
-    jPanel3.add(threshold);\r
-    jPanel3.add(slider);\r
-    jPanel3.add(thresholdValue);\r
-    this.add(jPanel1, java.awt.BorderLayout.SOUTH);\r
-    this.add(jPanel2, java.awt.BorderLayout.NORTH);\r
-  }\r
-\r
-  JComboBox annotations = new JComboBox();\r
-  JButton minColour = new JButton();\r
-  JButton maxColour = new JButton();\r
-  JButton ok = new JButton();\r
-  JButton cancel = new JButton();\r
-  JPanel jPanel1 = new JPanel();\r
-  JPanel jPanel2 = new JPanel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  JComboBox threshold = new JComboBox();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  JPanel jPanel3 = new JPanel();\r
-  FlowLayout flowLayout2 = new FlowLayout();\r
-  JSlider slider = new JSlider();\r
-  JTextField thresholdValue = new JTextField(20);\r
-  JCheckBox currentColours = new JCheckBox();\r
-\r
-  public void minColour_actionPerformed(ActionEvent e)\r
-  {\r
-    Color col = JColorChooser.showDialog(this,\r
-                                         "Select Colour for Minimum Value",\r
-                                         minColour.getBackground());\r
-    if (col != null)\r
-      minColour.setBackground(col);\r
-    minColour.repaint();\r
-    changeColour();\r
-  }\r
-\r
-  public void maxColour_actionPerformed(ActionEvent e)\r
-  {\r
-    Color col = JColorChooser.showDialog(this,\r
-                                         "Select Colour for Maximum Value",\r
-                                         maxColour.getBackground());\r
-    if (col != null)\r
-      maxColour.setBackground(col);\r
-    maxColour.repaint();\r
-    changeColour();\r
-  }\r
-\r
-  void changeColour()\r
-  {\r
-    // Check if combobox is still adjusting\r
-    if (adjusting)\r
-      return;\r
-\r
-    // We removed the non-graph annotations when filling the combobox\r
-    // so allow for them again here\r
-    int nograph = 0, graph = -1;\r
-    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if (av.alignment.getAlignmentAnnotation()[i].graph == 0)\r
-        nograph++;\r
-      else\r
-        graph++;\r
-\r
-      if (graph == annotations.getSelectedIndex())\r
-        break;\r
-    }\r
-\r
-    currentAnnotation = av.alignment.getAlignmentAnnotation()[graph + nograph];\r
-\r
-    int aboveThreshold = -1;\r
-    if (threshold.getSelectedItem().equals("Above Threshold"))\r
-      aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;\r
-    else if (threshold.getSelectedItem().equals("Below Threshold"))\r
-      aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;\r
-\r
-    slider.setEnabled(true);\r
-    thresholdValue.setEnabled(true);\r
-\r
-    if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)\r
-    {\r
-      slider.setEnabled(false);\r
-      thresholdValue.setEnabled(false);\r
-      thresholdValue.setText("");\r
-    }\r
-    else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD &&\r
-             currentAnnotation.threshold == null)\r
-    {\r
-      currentAnnotation.setThreshold(new jalview.datamodel.GraphLine\r
-                                     ( (currentAnnotation.graphMax -\r
-                                        currentAnnotation.graphMin) / 2f,\r
-                                      "Threshold",\r
-                                      Color.black));\r
-    }\r
-\r
-    if(aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)\r
-    {\r
-      adjusting = true;\r
-      float range = currentAnnotation.graphMax * 1000 -\r
-          currentAnnotation.graphMin * 1000;\r
-\r
-      slider.setMinimum( (int) (currentAnnotation.graphMin * 1000));\r
-      slider.setMaximum( (int) (currentAnnotation.graphMax * 1000));\r
-      slider.setValue( (int) (currentAnnotation.threshold.value * 1000));\r
-      thresholdValue.setText(currentAnnotation.threshold.value + "");\r
-      slider.setMajorTickSpacing( (int) (range / 10f));\r
-      slider.setMinorTickSpacing( (int) (range / 100f));\r
-      slider.setEnabled(true);\r
-      thresholdValue.setEnabled(true);\r
-      adjusting = false;\r
-    }\r
-\r
-    AnnotationColourGradient acg = null;\r
-    if (currentColours.isSelected())\r
-      acg = new AnnotationColourGradient(\r
-          currentAnnotation,\r
-          av.getGlobalColourScheme(), aboveThreshold);\r
-    else\r
-      acg =\r
-          new AnnotationColourGradient(\r
-              currentAnnotation,\r
-              minColour.getBackground(),\r
-              maxColour.getBackground(),\r
-              aboveThreshold);\r
-\r
-    av.setGlobalColourScheme(acg);\r
-\r
-    if (av.alignment.getGroups() != null)\r
-    {\r
-      Vector allGroups = ap.av.alignment.getGroups();\r
-      SequenceGroup sg;\r
-      for (int g = 0; g < allGroups.size(); g++)\r
-      {\r
-        sg = (SequenceGroup) allGroups.get(g);\r
-\r
-        if (sg.cs == null)\r
-        {\r
-          continue;\r
-        }\r
-\r
-        if (currentColours.isSelected())\r
-          sg.cs = new AnnotationColourGradient(\r
-              currentAnnotation,\r
-              sg.cs, aboveThreshold);\r
-        else\r
-          sg.cs = new AnnotationColourGradient(\r
-              currentAnnotation,\r
-              minColour.getBackground(),\r
-              maxColour.getBackground(),\r
-              aboveThreshold);\r
-\r
-      }\r
-    }\r
-\r
-    ap.repaint();\r
-  }\r
-\r
-  public void ok_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour();\r
-    try\r
-    {\r
-      frame.setClosed(true);\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-  }\r
-\r
-  public void cancel_actionPerformed(ActionEvent e)\r
-  {\r
-    reset();\r
-    try\r
-    {\r
-      frame.setClosed(true);\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-  }\r
-\r
-\r
-  void reset()\r
-  {\r
-    av.setGlobalColourScheme(oldcs);\r
-    if (av.alignment.getGroups() != null)\r
-    {\r
-      Vector allGroups = ap.av.alignment.getGroups();\r
-      SequenceGroup sg;\r
-      for (int g = 0; g < allGroups.size(); g++)\r
-      {\r
-        sg = (SequenceGroup) allGroups.get(g);\r
-        sg.cs = (ColourSchemeI)oldgroupColours.get(sg);\r
-      }\r
-    }\r
-  }\r
-\r
-  public void thresholdCheck_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour();\r
-  }\r
-\r
-  public void annotations_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour();\r
-  }\r
-\r
-  public void threshold_actionPerformed(ActionEvent e)\r
-  {\r
-    changeColour();\r
-  }\r
-\r
-  public void thresholdValue_actionPerformed(ActionEvent e)\r
-  {\r
-    try\r
-    {\r
-      float f = Float.parseFloat(thresholdValue.getText());\r
-      slider.setValue( (int) (f * 1000));\r
-    }\r
-    catch (NumberFormatException ex)\r
-    {}\r
-  }\r
-\r
-  public void valueChanged()\r
-  {\r
-    if (currentColours.isSelected()\r
-        && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient))\r
-    {\r
-      changeColour();\r
-    }\r
-\r
-    currentAnnotation.threshold.value = (float)slider.getValue()/1000f;\r
-    ap.repaint();\r
-  }\r
-\r
-  public void currentColours_actionPerformed(ActionEvent e)\r
-  {\r
-    if(currentColours.isSelected())\r
-    {\r
-      reset();\r
-    }\r
-\r
-    maxColour.setEnabled(!currentColours.isSelected());\r
-    minColour.setEnabled(!currentColours.isSelected());\r
-\r
-    changeColour();\r
-  }\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.gui;
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+
+import jalview.schemes.*;
+import javax.swing.event.*;
+import java.util.*;
+import jalview.datamodel.SequenceGroup;
+
+public class AnnotationColourChooser
+    extends JPanel
+{
+  JInternalFrame frame;
+  AlignViewport av;
+  AlignmentPanel ap;
+  ColourSchemeI oldcs;
+  Hashtable oldgroupColours;
+  jalview.datamodel.AlignmentAnnotation currentAnnotation;
+  boolean adjusting = false;
+
+  public AnnotationColourChooser(AlignViewport av, AlignmentPanel ap)
+  {
+    oldcs = av.getGlobalColourScheme();
+    if (av.alignment.getGroups() != null)
+    {
+      oldgroupColours = new Hashtable();
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.get(g);
+        if(sg.cs!=null)
+          oldgroupColours.put(sg, sg.cs);
+      }
+    }
+    this.av = av;
+    this.ap = ap;
+    frame = new JInternalFrame();
+    frame.setContentPane(this);
+    frame.setLayer(JLayeredPane.PALETTE_LAYER);
+    Desktop.addInternalFrame(frame, "Colour by Annotation", 480, 145);
+
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {}
+
+    slider.addChangeListener(new ChangeListener()
+    {
+      public void stateChanged(ChangeEvent evt)
+      {
+        if(!adjusting)
+        {
+          thresholdValue.setText( ( (float) slider.getValue() / 1000f) + "");
+          valueChanged();
+        }
+      }
+    });
+
+    if (av.alignment.getAlignmentAnnotation() == null)
+      return;
+
+    if (oldcs instanceof AnnotationColourGradient)
+    {
+      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
+      minColour.setBackground(acg.getMinColour());
+      maxColour.setBackground(acg.getMaxColour());
+    }
+    else
+    {
+      minColour.setBackground(Color.orange);
+      maxColour.setBackground(Color.red);
+    }
+
+    adjusting = true;
+    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
+    {
+      if (av.alignment.getAlignmentAnnotation()[i].graph > 0)
+        annotations.addItem(av.alignment.getAlignmentAnnotation()[i].label);
+    }
+
+    threshold.addItem("No Threshold");
+    threshold.addItem("Above Threshold");
+    threshold.addItem("Below Threshold");
+
+    adjusting = false;
+
+    changeColour();
+
+  }
+
+  public AnnotationColourChooser()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    minColour.setToolTipText("");
+    minColour.setMargin(new Insets(2, 2, 2, 2));
+    minColour.setText("Min Colour");
+    minColour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        minColour_actionPerformed(e);
+      }
+    });
+    maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    maxColour.setMargin(new Insets(2, 2, 2, 2));
+    maxColour.setText("Max Colour");
+    maxColour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        maxColour_actionPerformed(e);
+      }
+    });
+    ok.setOpaque(false);
+    ok.setText("OK");
+    ok.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+    cancel.setOpaque(false);
+    cancel.setText("Cancel");
+    cancel.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        cancel_actionPerformed(e);
+      }
+    });
+    this.setLayout(borderLayout1);
+    jPanel2.setLayout(flowLayout1);
+    annotations.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        annotations_actionPerformed(e);
+      }
+    });
+    jPanel1.setBackground(Color.white);
+    jPanel2.setBackground(Color.white);
+    threshold.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        threshold_actionPerformed(e);
+      }
+    });
+    jPanel3.setLayout(flowLayout2);
+    thresholdValue.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        thresholdValue_actionPerformed(e);
+      }
+    });
+    slider.setPaintLabels(false);
+    slider.setPaintTicks(true);
+    slider.setBackground(Color.white);
+    slider.setEnabled(false);
+    slider.setOpaque(false);
+    slider.setPreferredSize(new Dimension(150, 32));
+    thresholdValue.setEnabled(false);
+    thresholdValue.setColumns(10);
+    jPanel3.setBackground(Color.white);
+    currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    currentColours.setOpaque(false);
+    currentColours.setText("Use Original Colours");
+    currentColours.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        currentColours_actionPerformed(e);
+      }
+    });
+    jPanel1.add(ok);
+    jPanel1.add(cancel);
+    jPanel2.add(annotations);
+    jPanel2.add(currentColours);
+    jPanel2.add(minColour);
+    jPanel2.add(maxColour);
+    this.add(jPanel3, java.awt.BorderLayout.CENTER);
+    jPanel3.add(threshold);
+    jPanel3.add(slider);
+    jPanel3.add(thresholdValue);
+    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+    this.add(jPanel2, java.awt.BorderLayout.NORTH);
+  }
+
+  JComboBox annotations = new JComboBox();
+  JButton minColour = new JButton();
+  JButton maxColour = new JButton();
+  JButton ok = new JButton();
+  JButton cancel = new JButton();
+  JPanel jPanel1 = new JPanel();
+  JPanel jPanel2 = new JPanel();
+  BorderLayout borderLayout1 = new BorderLayout();
+  JComboBox threshold = new JComboBox();
+  FlowLayout flowLayout1 = new FlowLayout();
+  JPanel jPanel3 = new JPanel();
+  FlowLayout flowLayout2 = new FlowLayout();
+  JSlider slider = new JSlider();
+  JTextField thresholdValue = new JTextField(20);
+  JCheckBox currentColours = new JCheckBox();
+
+  public void minColour_actionPerformed(ActionEvent e)
+  {
+    Color col = JColorChooser.showDialog(this,
+                                         "Select Colour for Minimum Value",
+                                         minColour.getBackground());
+    if (col != null)
+      minColour.setBackground(col);
+    minColour.repaint();
+    changeColour();
+  }
+
+  public void maxColour_actionPerformed(ActionEvent e)
+  {
+    Color col = JColorChooser.showDialog(this,
+                                         "Select Colour for Maximum Value",
+                                         maxColour.getBackground());
+    if (col != null)
+      maxColour.setBackground(col);
+    maxColour.repaint();
+    changeColour();
+  }
+
+  void changeColour()
+  {
+    // Check if combobox is still adjusting
+    if (adjusting)
+      return;
+
+    // We removed the non-graph annotations when filling the combobox
+    // so allow for them again here
+    int nograph = 0, graph = -1;
+    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
+    {
+      if (av.alignment.getAlignmentAnnotation()[i].graph == 0)
+        nograph++;
+      else
+        graph++;
+
+      if (graph == annotations.getSelectedIndex())
+        break;
+    }
+
+    currentAnnotation = av.alignment.getAlignmentAnnotation()[graph + nograph];
+
+    int aboveThreshold = -1;
+    if (threshold.getSelectedItem().equals("Above Threshold"))
+      aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+    else if (threshold.getSelectedItem().equals("Below Threshold"))
+      aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+
+    slider.setEnabled(true);
+    thresholdValue.setEnabled(true);
+
+    if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+    {
+      slider.setEnabled(false);
+      thresholdValue.setEnabled(false);
+      thresholdValue.setText("");
+    }
+    else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD &&
+             currentAnnotation.threshold == null)
+    {
+      currentAnnotation.setThreshold(new jalview.datamodel.GraphLine
+                                     ( (currentAnnotation.graphMax -
+                                        currentAnnotation.graphMin) / 2f,
+                                      "Threshold",
+                                      Color.black));
+    }
+
+    if(aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+    {
+      adjusting = true;
+      float range = currentAnnotation.graphMax * 1000 -
+          currentAnnotation.graphMin * 1000;
+
+      slider.setMinimum( (int) (currentAnnotation.graphMin * 1000));
+      slider.setMaximum( (int) (currentAnnotation.graphMax * 1000));
+      slider.setValue( (int) (currentAnnotation.threshold.value * 1000));
+      thresholdValue.setText(currentAnnotation.threshold.value + "");
+      slider.setMajorTickSpacing( (int) (range / 10f));
+      slider.setEnabled(true);
+      thresholdValue.setEnabled(true);
+      adjusting = false;
+    }
+
+    AnnotationColourGradient acg = null;
+    if (currentColours.isSelected())
+      acg = new AnnotationColourGradient(
+          currentAnnotation,
+          av.getGlobalColourScheme(), aboveThreshold);
+    else
+      acg =
+          new AnnotationColourGradient(
+              currentAnnotation,
+              minColour.getBackground(),
+              maxColour.getBackground(),
+              aboveThreshold);
+
+    av.setGlobalColourScheme(acg);
+
+    if (av.alignment.getGroups() != null)
+    {
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.get(g);
+
+        if (sg.cs == null)
+        {
+          continue;
+        }
+
+        if (currentColours.isSelected())
+          sg.cs = new AnnotationColourGradient(
+              currentAnnotation,
+              sg.cs, aboveThreshold);
+        else
+          sg.cs = new AnnotationColourGradient(
+              currentAnnotation,
+              minColour.getBackground(),
+              maxColour.getBackground(),
+              aboveThreshold);
+
+      }
+    }
+
+    ap.repaint();
+  }
+
+  public void ok_actionPerformed(ActionEvent e)
+  {
+    changeColour();
+    try
+    {
+      frame.setClosed(true);
+    }
+    catch (Exception ex)
+    {}
+  }
+
+  public void cancel_actionPerformed(ActionEvent e)
+  {
+    reset();
+    try
+    {
+      frame.setClosed(true);
+    }
+    catch (Exception ex)
+    {}
+  }
+
+
+  void reset()
+  {
+    av.setGlobalColourScheme(oldcs);
+    if (av.alignment.getGroups() != null)
+    {
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.get(g);
+        sg.cs = (ColourSchemeI)oldgroupColours.get(sg);
+      }
+    }
+  }
+
+  public void thresholdCheck_actionPerformed(ActionEvent e)
+  {
+    changeColour();
+  }
+
+  public void annotations_actionPerformed(ActionEvent e)
+  {
+    changeColour();
+  }
+
+  public void threshold_actionPerformed(ActionEvent e)
+  {
+    changeColour();
+  }
+
+  public void thresholdValue_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      float f = Float.parseFloat(thresholdValue.getText());
+      slider.setValue( (int) (f * 1000));
+    }
+    catch (NumberFormatException ex)
+    {}
+  }
+
+  public void valueChanged()
+  {
+    if (currentColours.isSelected()
+        && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient))
+    {
+      changeColour();
+    }
+
+    currentAnnotation.threshold.value = (float)slider.getValue()/1000f;
+    ap.repaint();
+  }
+
+  public void currentColours_actionPerformed(ActionEvent e)
+  {
+    if(currentColours.isSelected())
+    {
+      reset();
+    }
+
+    maxColour.setEnabled(!currentColours.isSelected());
+    minColour.setEnabled(!currentColours.isSelected());
+
+    changeColour();
+  }
+
+}
index bffa89a..63d7c53 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.awt.image.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AnnotationLabels extends JPanel implements MouseListener,\r
-    MouseMotionListener, ActionListener\r
-{\r
-    static String ADDNEW = "Add New Row";\r
-    static String HIDE = "Hide This Row";\r
-    static String DELETE = "Delete This Row";\r
-    static String SHOWALL = "Show All Hidden Rows";\r
-    static String OUTPUT_TEXT = "Show Values In Textbox";\r
-    boolean active = false;\r
-    Image image;\r
-    AlignmentPanel ap;\r
-    AlignViewport av;\r
-    boolean resizing = false;\r
-    int oldY;\r
-    int mouseX;\r
-    int selectedRow = 0;\r
-    int scrollOffset = 0;\r
-    Font font = new Font("Arial", Font.PLAIN, 11);\r
-\r
-\r
-    /**\r
-     * Creates a new AnnotationLabels object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     */\r
-    public AnnotationLabels(AlignmentPanel ap)\r
-    {\r
-        this.ap = ap;\r
-        av = ap.av;\r
-\r
-        java.net.URL url = getClass().getResource("/images/idwidth.gif");\r
-        Image temp = null;\r
-\r
-        if (url != null)\r
-        {\r
-            temp = java.awt.Toolkit.getDefaultToolkit().createImage(url);\r
-        }\r
-\r
-        try\r
-        {\r
-            MediaTracker mt = new MediaTracker(this);\r
-            mt.addImage(temp, 0);\r
-            mt.waitForID(0);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-\r
-        BufferedImage bi = new BufferedImage(temp.getHeight(this),\r
-                temp.getWidth(this), BufferedImage.TYPE_INT_RGB);\r
-        Graphics2D g = (Graphics2D) bi.getGraphics();\r
-        g.rotate(Math.toRadians(90));\r
-        g.drawImage(temp, 0, -bi.getWidth(this), this);\r
-        image = (Image) bi;\r
-\r
-        addMouseListener(this);\r
-        addMouseMotionListener(this);\r
-    }\r
-\r
-    public AnnotationLabels(AlignViewport av)\r
-    {\r
-      this.av = av;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param y DOCUMENT ME!\r
-     */\r
-    public void setScrollOffset(int y)\r
-    {\r
-        scrollOffset = y;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void actionPerformed(ActionEvent evt)\r
-    {\r
-        int dif = 0;\r
-        AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
-\r
-        if (evt.getActionCommand().equals(ADDNEW))\r
-        {\r
-            String label = JOptionPane.showInputDialog(this,\r
-                    "Label for annotation");\r
-\r
-            if (label == null)\r
-            {\r
-                label = "";\r
-            }\r
-\r
-            AlignmentAnnotation newAnnotation = new AlignmentAnnotation(label,\r
-                    "New description",\r
-                    new Annotation[ap.av.alignment.getWidth()]);\r
-\r
-            ap.av.alignment.addAnnotation(newAnnotation);\r
-            ap.av.alignment.setAnnotationIndex(newAnnotation, 0);\r
-            dif = aa[aa.length - 1].height;\r
-        }\r
-        else if (evt.getActionCommand().equals(HIDE))\r
-        {\r
-            aa[selectedRow].visible = false;\r
-\r
-            if (aa[selectedRow].label.equals("Conservation"))\r
-            {\r
-                ap.av.showConservation = false;\r
-            }\r
-\r
-            if (aa[selectedRow].label.equals("Quality"))\r
-            {\r
-                ap.av.showQuality = false;\r
-            }\r
-\r
-            if (aa[selectedRow].label.equals("Consensus"))\r
-            {\r
-                ap.av.showIdentity = false;\r
-            }\r
-\r
-            dif = aa[selectedRow].height * -1;\r
-        }\r
-        else if (evt.getActionCommand().equals(DELETE))\r
-        {\r
-            ap.av.alignment.deleteAnnotation(aa[selectedRow]);\r
-            dif = aa[selectedRow].height * -1;\r
-        }\r
-        else if (evt.getActionCommand().equals(SHOWALL))\r
-        {\r
-            for (int i = 0; i < aa.length; i++)\r
-            {\r
-                if (!aa[i].visible)\r
-                {\r
-                    dif += aa[i].height;\r
-                    aa[i].visible = true;\r
-                }\r
-            }\r
-        }\r
-        else if (evt.getActionCommand().equals(OUTPUT_TEXT))\r
-        {\r
-            CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
-            Desktop.addInternalFrame(cap,\r
-                ap.alignFrame.getTitle() + " - " + aa[selectedRow].label, 500,\r
-                100);\r
-            cap.setText(aa[selectedRow].toString());\r
-        }\r
-\r
-\r
-        ap.annotationPanel.adjustPanelHeight();\r
-        ap.annotationScroller.validate();\r
-        ap.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent evt)\r
-    {\r
-        oldY = evt.getY();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-        active = false;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent evt)\r
-    {\r
-        active = true;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent evt)\r
-    {\r
-        active = false;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-        active = true;\r
-\r
-        Dimension d = ap.annotationScroller.getPreferredSize();\r
-        int dif = evt.getY() - oldY;\r
-\r
-        dif /= ap.av.charHeight;\r
-        dif *= ap.av.charHeight;\r
-\r
-        if ((d.height - dif) > 20)\r
-        {\r
-            ap.annotationScroller.setPreferredSize(new Dimension(d.width,\r
-                    d.height - dif));\r
-            d = ap.annotationSpaceFillerHolder.getPreferredSize();\r
-            ap.annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
-                    d.width, d.height - dif));\r
-            ap.repaint();\r
-        }\r
-\r
-        ap.addNotify();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseMoved(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseClicked(MouseEvent evt)\r
-    {\r
-        int y = evt.getY() - scrollOffset;\r
-        AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
-\r
-        if ((aa == null) || (aa.length == 0))\r
-        {\r
-            JPopupMenu pop = new JPopupMenu("Annotations");\r
-            JMenuItem item = new JMenuItem(ADDNEW);\r
-            item.addActionListener(this);\r
-            pop.add(item);\r
-            pop.show(this, evt.getX(), evt.getY());\r
-\r
-            return;\r
-        }\r
-\r
-        int height = 0;\r
-\r
-        for (int i = 0; i < aa.length; i++)\r
-        {\r
-            if (!aa[i].visible)\r
-            {\r
-                continue;\r
-            }\r
-\r
-            height += aa[i].height;\r
-\r
-            if (y < height)\r
-            {\r
-                selectedRow = i;\r
-\r
-                break;\r
-            }\r
-        }\r
-\r
-        JPopupMenu pop = new JPopupMenu("Annotations");\r
-        JMenuItem item = new JMenuItem(ADDNEW);\r
-        item.addActionListener(this);\r
-        pop.add(item);\r
-        item = new JMenuItem(HIDE);\r
-        item.addActionListener(this);\r
-        pop.add(item);\r
-        item = new JMenuItem(DELETE);\r
-        item.addActionListener(this);\r
-        pop.add(item);\r
-        item = new JMenuItem(SHOWALL);\r
-        item.addActionListener(this);\r
-        pop.add(item);\r
-        item = new JMenuItem(OUTPUT_TEXT);\r
-        item.addActionListener(this);\r
-        pop.add(item);\r
-\r
-        if (aa[selectedRow].label.equals("Consensus"))\r
-        {\r
-          pop.addSeparator();\r
-          final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(\r
-              "Ignore Gaps In Consensus",\r
-              ap.av.getIgnoreGapsConsensus());\r
-          cbmi.addActionListener(new ActionListener()\r
-              {public void actionPerformed(ActionEvent e)\r
-               {\r
-                 ap.av.setIgnoreGapsConsensus(cbmi.getState());\r
-                 ap.repaint();\r
-               }\r
-              });\r
-          pop.add(cbmi);\r
-\r
-        }\r
-\r
-        pop.show(this, evt.getX(), evt.getY());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g1 DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-\r
-        int width = getWidth();\r
-        if(width==0)\r
-         width = ap.calculateIdWidth().width + 4;\r
-\r
-       Graphics2D g2 = (Graphics2D) g;\r
-       if(av.antiAlias)\r
-        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-            RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-       drawComponent(g2, width);\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void drawComponent(Graphics g, int width)\r
-    {\r
-        if(av.getFont().getSize()<10)\r
-          g.setFont(new Font("Arial", Font.PLAIN, av.getFont().getSize()-1));\r
-        else\r
-          g.setFont(font);\r
-\r
-        FontMetrics fm = g.getFontMetrics(g.getFont());\r
-        g.setColor(Color.white);\r
-        g.fillRect(0, 0, getWidth(), getHeight());\r
-\r
-        g.translate(0, scrollOffset);\r
-        g.setColor(Color.black);\r
-\r
-        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-        int fontHeight = g.getFont().getSize();\r
-        int y = fontHeight;\r
-        int x = 0;\r
-        int graphExtras = 0;\r
-\r
-\r
-\r
-        if (aa != null)\r
-        {\r
-            for (int i = 0; i < aa.length; i++)\r
-            {\r
-                if (!aa[i].visible)\r
-                {\r
-                    continue;\r
-                }\r
-\r
-                x = width - fm.stringWidth(aa[i].label) - 3;\r
-\r
-                if (aa[i].graph>0)\r
-                {\r
-                    graphExtras = y;\r
-\r
-                    y += (aa[i].height / 3);\r
-\r
-                    if(aa[i].graphGroup<0)\r
-                        graphExtras = y + fontHeight;\r
-                }\r
-\r
-                if(aa[i].graphGroup>-1)\r
-                {\r
-                  int groupSize = 0;\r
-                  for (int gg = 0; gg < aa.length; gg++)\r
-                  {\r
-                    if (aa[gg].graphGroup == aa[i].graphGroup)\r
-                      groupSize++;\r
-                  }\r
-\r
-                  if(groupSize * (fontHeight+8) < aa[i].height)\r
-                    graphExtras += (aa[i].height -( groupSize * (fontHeight+8)) )/2;\r
-\r
-                 for(int gg=0; gg<aa.length; gg++)\r
-                 {\r
-                   if(aa[gg].graphGroup==aa[i].graphGroup)\r
-                   {\r
-                     x = width - fm.stringWidth(aa[gg].label) - 3;\r
-                     g.drawString(aa[gg].label, x, graphExtras );\r
-                     if(aa[gg].annotations[0]!=null)\r
-                       g.setColor(aa[gg].annotations[0].colour);\r
-\r
-                     g.drawLine( x, graphExtras+3,\r
-                                 x+fm.stringWidth(aa[gg].label),\r
-                                 graphExtras+3);\r
-\r
-                     g.setColor(Color.black);\r
-                     graphExtras += fontHeight+8;\r
-                   }\r
-                 }\r
-                }\r
-                else\r
-                  g.drawString(aa[i].label, x, y);\r
-\r
-                if (aa[i].graph>0)\r
-                {\r
-                /*  if (aa[i].graphLines != null)\r
-                  {\r
-                    for (int gl = 0; gl < aa[i].graphLines.size(); gl++)\r
-                    {\r
-                       x = width - fm.stringWidth(aa[i].getGraphLine(gl).label) - 3;\r
-                      g.drawString(aa[i].getGraphLine(gl).label, x, graphExtras);\r
-                      g.setColor(aa[i].getGraphLine(gl).colour);\r
-                      Graphics2D g2 = (Graphics2D) g;\r
-                      g2.setStroke(new BasicStroke(1,\r
-                          BasicStroke.CAP_SQUARE,\r
-                          BasicStroke.JOIN_ROUND, 3f,\r
-                          new float[]\r
-                          {5f, 3f}, 0f));\r
-\r
-                      graphExtras += 3;\r
-\r
-                      g.drawLine(x, graphExtras,\r
-                                 x+fm.stringWidth(aa[i].label),\r
-                                 graphExtras);\r
-                      g2.setStroke(new BasicStroke());\r
-                    }\r
-                  }*/\r
-                    y += ((2 * aa[i].height) / 3);\r
-                }\r
-                else\r
-                {\r
-                    y += aa[i].height;\r
-                }\r
-            }\r
-        }\r
-\r
-        if (active)\r
-        {\r
-            if (image != null)\r
-            {\r
-                g.drawImage(image, 2, 0 - scrollOffset, this);\r
-            }\r
-        }\r
-\r
-        if ((aa == null) || (aa.length < 1))\r
-        {\r
-            g.drawString("Right click", 2, 8);\r
-            g.drawString("to add annotation", 2, 18);\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+import jalview.io.FormatAdapter;
+
+import java.awt.*;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.*;
+import java.awt.image.*;
+import java.util.Vector;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AnnotationLabels extends JPanel implements MouseListener,
+    MouseMotionListener, ActionListener
+{
+    static String ADDNEW = "Add New Row";
+    static String HIDE = "Hide This Row";
+    static String DELETE = "Delete This Row";
+    static String SHOWALL = "Show All Hidden Rows";
+    static String OUTPUT_TEXT = "Export Annotation";
+    static String COPYCONS_SEQ = "Copy Consensus Sequence";
+    boolean resizePanel = false;
+    Image image;
+    AlignmentPanel ap;
+    AlignViewport av;
+    boolean resizing = false;
+    MouseEvent dragEvent;
+    int oldY;
+    int selectedRow;
+    int scrollOffset = 0;
+    Font font = new Font("Arial", Font.PLAIN, 11);
+
+
+    /**
+     * Creates a new AnnotationLabels object.
+     *
+     * @param ap DOCUMENT ME!
+     */
+    public AnnotationLabels(AlignmentPanel ap)
+    {
+        this.ap = ap;
+        av = ap.av;
+
+        java.net.URL url = getClass().getResource("/images/idwidth.gif");
+        Image temp = null;
+
+        if (url != null)
+        {
+            temp = java.awt.Toolkit.getDefaultToolkit().createImage(url);
+        }
+
+        try
+        {
+            MediaTracker mt = new MediaTracker(this);
+            mt.addImage(temp, 0);
+            mt.waitForID(0);
+        }
+        catch (Exception ex)
+        {
+        }
+
+        BufferedImage bi = new BufferedImage(temp.getHeight(this),
+                temp.getWidth(this), BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = (Graphics2D) bi.getGraphics();
+        g.rotate(Math.toRadians(90));
+        g.drawImage(temp, 0, -bi.getWidth(this), this);
+        image = (Image) bi;
+
+        addMouseListener(this);
+        addMouseMotionListener(this);
+    }
+
+    public AnnotationLabels(AlignViewport av)
+    {
+      this.av = av;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param y DOCUMENT ME!
+     */
+    public void setScrollOffset(int y)
+    {
+        scrollOffset = y;
+        repaint();
+    }
+
+    void getSelectedRow(int y)
+    {
+      int height = 0;
+      AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();
+
+      if(aa!=null)
+      {
+        for (int i = 0; i < aa.length; i++)
+        {
+          if (!aa[i].visible)
+          {
+            continue;
+          }
+
+          height += aa[i].height;
+
+          if (y < height)
+          {
+            selectedRow = i;
+
+            break;
+          }
+        }
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void actionPerformed(ActionEvent evt)
+    {
+        int dif = 0;
+        AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();
+
+        if (evt.getActionCommand().equals(ADDNEW))
+        {
+            String label = JOptionPane.showInputDialog(this,
+                    "Label for annotation");
+
+            if (label == null)
+            {
+                label = "";
+            }
+
+            AlignmentAnnotation newAnnotation = new AlignmentAnnotation(label,
+                    "New description",
+                    new Annotation[ap.av.alignment.getWidth()]);
+
+            ap.av.alignment.addAnnotation(newAnnotation);
+            ap.av.alignment.setAnnotationIndex(newAnnotation, 0);
+            if (aa != null)
+              dif = aa[aa.length - 1].height;
+        }
+        else if (evt.getActionCommand().equals(HIDE))
+        {
+            aa[selectedRow].visible = false;
+
+            if (aa[selectedRow].label.equals("Conservation"))
+            {
+                ap.av.showConservation = false;
+            }
+
+            if (aa[selectedRow].label.equals("Quality"))
+            {
+                ap.av.showQuality = false;
+            }
+
+            if (aa[selectedRow].label.equals("Consensus"))
+            {
+                ap.av.showIdentity = false;
+            }
+
+            dif = aa[selectedRow].height * -1;
+        }
+        else if (evt.getActionCommand().equals(DELETE))
+        {
+            ap.av.alignment.deleteAnnotation(aa[selectedRow]);
+            dif = aa[selectedRow].height * -1;
+        }
+        else if (evt.getActionCommand().equals(SHOWALL))
+        {
+            for (int i = 0; i < aa.length; i++)
+            {
+                if (!aa[i].visible)
+                {
+                    dif += aa[i].height;
+                    aa[i].visible = true;
+                }
+            }
+        }
+        else if (evt.getActionCommand().equals(OUTPUT_TEXT))
+        {
+          new AnnotationExporter().exportAnnotations(
+              ap,
+              new AlignmentAnnotation[]
+              {aa[selectedRow]}
+              );
+        }
+        else if (evt.getActionCommand().equals(COPYCONS_SEQ))
+        {
+          SequenceI cons=av.getConsensusSeq();
+          if (cons!=null)
+            copy_annotseqtoclipboard(cons);
+          
+        }
+
+        ap.annotationPanel.adjustPanelHeight();
+        ap.annotationScroller.validate();
+        ap.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent evt)
+    {
+        getSelectedRow(evt.getY() - scrollOffset);
+        oldY = evt.getY();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent evt)
+    {
+        int start = selectedRow;
+        getSelectedRow(evt.getY() - scrollOffset);
+        int end = selectedRow;
+
+        if(start!=end)
+        {
+          //Swap these annotations
+          AlignmentAnnotation startAA = ap.av.alignment.getAlignmentAnnotation()[start];
+          AlignmentAnnotation endAA = ap.av.alignment.getAlignmentAnnotation()[end];
+
+
+          ap.av.alignment.getAlignmentAnnotation()[end] = startAA;
+          ap.av.alignment.getAlignmentAnnotation()[start] = endAA;
+        }
+
+        resizePanel = false;
+        dragEvent = null;
+        repaint();
+        ap.annotationPanel.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent evt)
+    {
+      if(evt.getY()<10)
+      {
+        resizePanel = true;
+        repaint();
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent evt)
+    {
+      if(dragEvent == null)
+      {
+        resizePanel = false;
+        repaint();
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent evt)
+    {
+      dragEvent = evt;
+
+      if (resizePanel)
+      {
+        Dimension d = ap.annotationScroller.getPreferredSize();
+        int dif = evt.getY() - oldY;
+
+        dif /= ap.av.charHeight;
+        dif *= ap.av.charHeight;
+
+        if ( (d.height - dif) > 20)
+        {
+          ap.annotationScroller.setPreferredSize(new Dimension(d.width,
+              d.height - dif));
+          d = ap.annotationSpaceFillerHolder.getPreferredSize();
+          ap.annotationSpaceFillerHolder.setPreferredSize(new Dimension(
+              d.width, d.height - dif));
+          ap.repaint();
+        }
+
+        ap.addNotify();
+      }
+      else
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseMoved(MouseEvent evt)
+    {
+      resizePanel = evt.getY()<10;
+
+      repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseClicked(MouseEvent evt)
+    {
+       if(!SwingUtilities.isRightMouseButton(evt))
+         return;
+
+        AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();
+
+        if ((aa == null) || (aa.length == 0))
+        {
+            JPopupMenu pop = new JPopupMenu("Annotations");
+            JMenuItem item = new JMenuItem(ADDNEW);
+            item.addActionListener(this);
+            pop.add(item);
+            pop.show(this, evt.getX(), evt.getY());
+
+            return;
+        }
+
+
+        JPopupMenu pop = new JPopupMenu("Annotations");
+        JMenuItem item = new JMenuItem(ADDNEW);
+        item.addActionListener(this);
+        pop.add(item);
+        item = new JMenuItem(HIDE);
+        item.addActionListener(this);
+        pop.add(item);
+        item = new JMenuItem(DELETE);
+        item.addActionListener(this);
+        pop.add(item);
+        item = new JMenuItem(SHOWALL);
+        item.addActionListener(this);
+        pop.add(item);
+        item = new JMenuItem(OUTPUT_TEXT);
+        item.addActionListener(this);
+        pop.add(item);
+        // annotation object should be typed
+        if (aa[selectedRow].label.equals("Consensus"))
+        {
+          pop.addSeparator();
+          final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
+              "Ignore Gaps In Consensus",
+              ap.av.getIgnoreGapsConsensus());
+          cbmi.addActionListener(new ActionListener()
+              {public void actionPerformed(ActionEvent e)
+               {
+                 ap.av.setIgnoreGapsConsensus(cbmi.getState());
+                 ap.repaint();
+               }
+              });
+          pop.add(cbmi);
+          final JMenuItem consclipbrd = new JMenuItem(COPYCONS_SEQ);
+          consclipbrd.addActionListener(this);
+          pop.add(consclipbrd);
+        }
+
+        pop.show(this, evt.getX(), evt.getY());
+    }
+    /**
+     * do a single sequence copy to jalview and the system clipboard
+     *
+     * @param sq sequence to be copied to clipboard
+     */
+    protected void copy_annotseqtoclipboard(SequenceI sq)
+    {
+      SequenceI [] seqs = new SequenceI[] { sq };
+      String[] omitHidden = null;
+      SequenceI [] dseqs=new SequenceI[] { sq.getDatasetSequence()};
+      if (dseqs[0]==null) {
+        dseqs[0] = new Sequence(sq);
+        dseqs[0].setSequence(jalview.analysis.AlignSeq.extractGaps(jalview.util.Comparison.GapChars, sq.getSequence()));
+        sq.setDatasetSequence(dseqs[0]);
+      }
+      Alignment ds=new Alignment(dseqs);
+      if (av.hasHiddenColumns)
+      {
+        omitHidden = av.getColumnSelection().getVisibleSequenceStrings(0, sq.getLength(), seqs);
+      }
+
+      String output = new FormatAdapter().formatSequences(
+          "Fasta",
+          seqs,
+          omitHidden);
+
+
+      Toolkit.getDefaultToolkit().getSystemClipboard()
+          .setContents(new StringSelection(output), Desktop.instance);
+
+      Vector hiddenColumns = null;
+      if(av.hasHiddenColumns)
+      {
+        hiddenColumns =new Vector();
+        for(int i=0; i<av.getColumnSelection().getHiddenColumns().size(); i++)
+        {
+          int[] region = (int[])
+              av.getColumnSelection().getHiddenColumns().elementAt(i);
+
+          hiddenColumns.addElement(new int[]{region[0],
+                            region[1]});
+        }
+      }
+      
+      Desktop.jalviewClipboard = new Object[]{ seqs,
+          ds, // what is the dataset of a consensus sequence ? need to flag sequence as special.
+          hiddenColumns};
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g1 DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+
+        int width = getWidth();
+        if(width==0)
+         width = ap.calculateIdWidth().width + 4;
+
+       Graphics2D g2 = (Graphics2D) g;
+       if(av.antiAlias)
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+            RenderingHints.VALUE_ANTIALIAS_ON);
+
+       drawComponent(g2, width);
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void drawComponent(Graphics g, int width)
+    {
+        if(av.getFont().getSize()<10)
+          g.setFont(font);
+        else
+          g.setFont(av.getFont());
+
+        FontMetrics fm = g.getFontMetrics(g.getFont());
+        g.setColor(Color.white);
+        g.fillRect(0, 0, getWidth(), getHeight());
+
+        g.translate(0, scrollOffset);
+        g.setColor(Color.black);
+
+        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+        int fontHeight = g.getFont().getSize();
+        int y = fontHeight;
+        int x = 0;
+        int graphExtras = 0;
+
+
+
+        if (aa != null)
+        {
+            for (int i = 0; i < aa.length; i++)
+            {
+                if (!aa[i].visible)
+                {
+                    continue;
+                }
+
+                x = width - fm.stringWidth(aa[i].label) - 3;
+
+                if (aa[i].graph>0 && aa[i].graphHeight>0)
+                {
+                    graphExtras = y;
+
+                    y += (aa[i].height / 3);
+
+                    if(aa[i].graphGroup<0)
+                        graphExtras = y + fontHeight;
+                }
+
+                if(aa[i].graphGroup>-1)
+                {
+                  int groupSize = 0;
+                  for (int gg = 0; gg < aa.length; gg++)
+                  {
+                    if (aa[gg].graphGroup == aa[i].graphGroup)
+                      groupSize++;
+                  }
+
+                  if(groupSize * (fontHeight+8) < aa[i].height)
+                    graphExtras += (aa[i].height -( groupSize * (fontHeight+8)) )/2;
+
+                 for(int gg=0; gg<aa.length; gg++)
+                 {
+                   if(aa[gg].graphGroup==aa[i].graphGroup)
+                   {
+                     x = width - fm.stringWidth(aa[gg].label) - 3;
+                     g.drawString(aa[gg].label, x, graphExtras );
+                     if(aa[gg].annotations[0]!=null)
+                       g.setColor(aa[gg].annotations[0].colour);
+
+                     g.drawLine( x, graphExtras+3,
+                                 x+fm.stringWidth(aa[gg].label),
+                                 graphExtras+3);
+
+                     g.setColor(Color.black);
+                     graphExtras += fontHeight+8;
+                   }
+                 }
+                }
+                else
+                  g.drawString(aa[i].label, x, y);
+
+                if (aa[i].graph>0)
+                {
+                /*  if (aa[i].graphLines != null)
+                  {
+                    for (int gl = 0; gl < aa[i].graphLines.size(); gl++)
+                    {
+                       x = width - fm.stringWidth(aa[i].getGraphLine(gl).label) - 3;
+                      g.drawString(aa[i].getGraphLine(gl).label, x, graphExtras);
+                      g.setColor(aa[i].getGraphLine(gl).colour);
+                      Graphics2D g2 = (Graphics2D) g;
+                      g2.setStroke(new BasicStroke(1,
+                          BasicStroke.CAP_SQUARE,
+                          BasicStroke.JOIN_ROUND, 3f,
+                          new float[]
+                          {5f, 3f}, 0f));
+
+                      graphExtras += 3;
+
+                      g.drawLine(x, graphExtras,
+                                 x+fm.stringWidth(aa[i].label),
+                                 graphExtras);
+                      g2.setStroke(new BasicStroke());
+                    }
+                  }*/
+                    y += ((2 * aa[i].height) / 3);
+                }
+                else
+                {
+                    y += aa[i].height;
+                }
+            }
+        }
+
+        if (resizePanel)
+        {
+          g.drawImage(image, 2, 0 - scrollOffset, this);
+        }
+        else if (dragEvent != null && aa!=null)
+        {
+          g.setColor(Color.lightGray);
+          g.drawString(aa[selectedRow].label, dragEvent.getX(), dragEvent.getY() - scrollOffset);
+        }
+
+
+        if ((aa == null) || (aa.length < 1))
+        {
+            g.drawString("Right click", 2, 8);
+            g.drawString("to add annotation", 2, 18);
+        }
+    }
+}
index a10d58b..ddfd6bb 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.awt.image.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class AnnotationPanel extends JPanel implements MouseListener,\r
-    MouseMotionListener, ActionListener, AdjustmentListener\r
-{\r
-    final String HELIX = "Helix";\r
-    final String SHEET = "Sheet";\r
-    final String LABEL = "Label";\r
-    final String REMOVE = "Remove Annotation";\r
-    final String COLOUR = "Colour";\r
-    final Color HELIX_COLOUR = Color.red.darker();\r
-    final Color SHEET_COLOUR = Color.green.darker().darker();\r
-\r
-    /** DOCUMENT ME!! */\r
-    AlignViewport av;\r
-    AlignmentPanel ap;\r
-    int activeRow = -1;\r
-    BufferedImage image;\r
-    Graphics2D gg;\r
-    FontMetrics fm;\r
-    int imgWidth = 0;\r
-    boolean fastPaint = false;\r
-\r
-    //Used For mouse Dragging and resizing graphs\r
-    int graphStretch = -1;\r
-    int graphStretchY = -1;\r
-\r
-    /**\r
-     * Creates a new AnnotationPanel object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     */\r
-    public AnnotationPanel(AlignmentPanel ap)\r
-    {\r
-        ToolTipManager.sharedInstance().registerComponent(this);\r
-        ToolTipManager.sharedInstance().setInitialDelay(0);\r
-        ToolTipManager.sharedInstance().setDismissDelay(10000);\r
-        this.ap = ap;\r
-        av = ap.av;\r
-        this.setLayout(null);\r
-        addMouseListener(this);\r
-        addMouseMotionListener(this);\r
-        ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener(this);\r
-    }\r
-\r
-    public AnnotationPanel(AlignViewport av)\r
-    {\r
-      this.av = av;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void adjustmentValueChanged(AdjustmentEvent evt)\r
-    {\r
-        ap.alabels.setScrollOffset(-evt.getValue());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public int adjustPanelHeight()\r
-    {\r
-        // setHeight of panels\r
-        image = null;\r
-        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-        int height = 0;\r
-\r
-        if (aa != null)\r
-        {\r
-            for (int i = 0; i < aa.length; i++)\r
-            {\r
-                if (!aa[i].visible)\r
-                {\r
-                    continue;\r
-                }\r
-\r
-                aa[i].height = 0;\r
-\r
-                if (aa[i].hasText)\r
-                {\r
-                    aa[i].height += av.charHeight;\r
-                }\r
-\r
-                if (aa[i].hasIcons)\r
-                {\r
-                    aa[i].height += 16;\r
-                }\r
-\r
-                if (aa[i].graph>0)\r
-                {\r
-                    aa[i].height += aa[i].graphHeight;\r
-                }\r
-\r
-                if (aa[i].height == 0)\r
-                {\r
-                    aa[i].height = 20;\r
-                }\r
-\r
-                height += aa[i].height;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            height = 20;\r
-        }\r
-\r
-        this.setPreferredSize(new Dimension(1, height));\r
-\r
-        return height;\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void actionPerformed(ActionEvent evt)\r
-    {\r
-        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-        Annotation[] anot = aa[activeRow].annotations;\r
-\r
-        if (evt.getActionCommand().equals(REMOVE))\r
-        {\r
-            for (int i = 0; i < av.getColumnSelection().size(); i++)\r
-            {\r
-                anot[av.getColumnSelection().columnAt(i)] = null;\r
-            }\r
-        }\r
-        else if (evt.getActionCommand().equals(LABEL))\r
-        {\r
-            String label = JOptionPane.showInputDialog(this, "Enter Label ",\r
-                    "Enter label", JOptionPane.QUESTION_MESSAGE);\r
-\r
-            if (label == null)\r
-            {\r
-                return;\r
-            }\r
-\r
-            if ((label.length() > 0) && !aa[activeRow].hasText)\r
-            {\r
-                aa[activeRow].hasText = true;\r
-            }\r
-\r
-            for (int i = 0; i < av.getColumnSelection().size(); i++)\r
-            {\r
-                int index = av.getColumnSelection().columnAt(i);\r
-\r
-                if (anot[index] == null)\r
-                {\r
-                    anot[index] = new Annotation(label, "", ' ', 0);\r
-                }\r
-\r
-                anot[index].displayCharacter = label;\r
-            }\r
-        }\r
-        else if (evt.getActionCommand().equals(COLOUR))\r
-        {\r
-            Color col = JColorChooser.showDialog(this,\r
-                    "Choose foreground colour", Color.black);\r
-\r
-            for (int i = 0; i < av.getColumnSelection().size(); i++)\r
-            {\r
-                int index = av.getColumnSelection().columnAt(i);\r
-\r
-                if (anot[index] == null)\r
-                {\r
-                    anot[index] = new Annotation("", "", ' ', 0);\r
-                }\r
-\r
-                anot[index].colour = col;\r
-            }\r
-        }\r
-        else // HELIX OR SHEET\r
-        {\r
-            char type = 0;\r
-            String symbol = "\u03B1";\r
-\r
-            if (evt.getActionCommand().equals(HELIX))\r
-            {\r
-                type = 'H';\r
-            }\r
-            else if (evt.getActionCommand().equals(SHEET))\r
-            {\r
-                type = 'E';\r
-                symbol = "\u03B2";\r
-            }\r
-\r
-            if (!aa[activeRow].hasIcons)\r
-            {\r
-                aa[activeRow].hasIcons = true;\r
-            }\r
-\r
-            String label = JOptionPane.showInputDialog("Enter a label for the structure?",\r
-                    symbol);\r
-\r
-            if (label == null)\r
-            {\r
-                return;\r
-            }\r
-\r
-            if ((label.length() > 0) && !aa[activeRow].hasText)\r
-            {\r
-                aa[activeRow].hasText = true;\r
-            }\r
-\r
-            for (int i = 0; i < av.getColumnSelection().size(); i++)\r
-            {\r
-                int index = av.getColumnSelection().columnAt(i);\r
-\r
-                if (anot[index] == null)\r
-                {\r
-                    anot[index] = new Annotation(label, "", type, 0);\r
-                }\r
-\r
-                anot[index].secondaryStructure = type;\r
-                anot[index].displayCharacter = label;\r
-            }\r
-        }\r
-\r
-        adjustPanelHeight();\r
-        repaint();\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent evt)\r
-    {\r
-        int height = 0;\r
-        activeRow = -1;\r
-\r
-        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-        if(aa==null)\r
-          return;\r
-\r
-        for (int i = 0; i < aa.length; i++)\r
-        {\r
-            if (aa[i].visible)\r
-            {\r
-              height += aa[i].height;\r
-            }\r
-\r
-            if (evt.getY() < height)\r
-            {\r
-                if (aa[i].editable)\r
-                {\r
-                    activeRow = i;\r
-                }\r
-                else if(aa[i].graph>0)\r
-                {\r
-                    //Stretch Graph\r
-                    graphStretch = i;\r
-                    graphStretchY = evt.getY();\r
-                }\r
-\r
-                break;\r
-            }\r
-        }\r
-\r
-        if (SwingUtilities.isRightMouseButton(evt))\r
-        {\r
-            if (av.getColumnSelection() == null)\r
-            {\r
-                return;\r
-            }\r
-\r
-            JPopupMenu pop = new JPopupMenu("Structure type");\r
-            JMenuItem item = new JMenuItem(HELIX);\r
-            item.addActionListener(this);\r
-            pop.add(item);\r
-            item = new JMenuItem(SHEET);\r
-            item.addActionListener(this);\r
-            pop.add(item);\r
-            item = new JMenuItem(LABEL);\r
-            item.addActionListener(this);\r
-            pop.add(item);\r
-            item = new JMenuItem(COLOUR);\r
-            item.addActionListener(this);\r
-            pop.add(item);\r
-            item = new JMenuItem(REMOVE);\r
-            item.addActionListener(this);\r
-            pop.add(item);\r
-            pop.show(this, evt.getX(), evt.getY());\r
-\r
-            return;\r
-        }\r
-\r
-        if (aa == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
-\r
-        if (evt.isShiftDown())\r
-        {\r
-                /*int start = Integer.parseInt(activeRes.get(activeRes.size() -\r
-                            1).toString());\r
-                int end = res;\r
-\r
-                if (end < start)\r
-                {\r
-                    int temp = end;\r
-                    end = start;\r
-                    start = temp;\r
-                }\r
-\r
-                for (int n = start; n <= end; n++)\r
-                {\r
-                   addEditableColumn(n);\r
-                } */\r
-        }\r
-        else\r
-        {\r
-          if (av.getColumnSelection().contains(res))\r
-            av.getColumnSelection().removeElement(res);\r
-          else\r
-            av.getColumnSelection().addElement(res);\r
-\r
-          ap.repaint();\r
-\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-      graphStretch = -1;\r
-      graphStretchY = -1;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-      if(graphStretch>-1)\r
-      {\r
-        av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight += graphStretchY - evt.getY();\r
-        if(av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight <10)\r
-          av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight = 10;\r
-        graphStretchY = evt.getY();\r
-        adjustPanelHeight();\r
-        ap.repaint();\r
-      }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseMoved(MouseEvent evt)\r
-    {\r
-        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-\r
-        if (aa == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        int row = -1;\r
-        int height = 0;\r
-\r
-        for (int i = 0; i < aa.length; i++)\r
-        {\r
-            if (aa[i].visible)\r
-            {\r
-                height += aa[i].height;\r
-            }\r
-\r
-            if (evt.getY() < height)\r
-            {\r
-                row = i;\r
-\r
-                break;\r
-            }\r
-        }\r
-\r
-        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
-\r
-        if(av.hasHiddenColumns)\r
-          res = av.getColumnSelection().adjustForHiddenColumns(res);\r
-\r
-        if (row > -1 && res<aa[row].annotations.length)\r
-        {\r
-            if(aa[row].graphGroup>-1)\r
-            {\r
-              StringBuffer tip = new StringBuffer("<html>");\r
-              for (int gg = 0; gg < aa.length; gg++)\r
-              {\r
-                if (aa[gg].graphGroup == aa[row].graphGroup && aa[gg].annotations[res]!=null)\r
-                  tip.append(aa[gg].label+" "+aa[gg].annotations[res].description+"<br>" );\r
-              }\r
-              if(tip.length()!=6)\r
-              {\r
-                tip.setLength(tip.length() - 4);\r
-                this.setToolTipText(tip.toString() + "</html>");\r
-              }\r
-            }\r
-            else if(aa[row].annotations[res] != null)\r
-              this.setToolTipText(aa[row].annotations[res].description);\r
-\r
-            if(aa[row].annotations[res]!=null)\r
-            {\r
-              StringBuffer text = new StringBuffer("Sequence position " +\r
-                                                   (res + 1) + "  " +\r
-                                                   aa[row].annotations[res].description);\r
-\r
-              ap.alignFrame.statusBar.setText(text.toString());\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseClicked(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-      g.setColor(Color.white);\r
-      g.fillRect(0, 0, getWidth(), getHeight());\r
-\r
-      if(image!=null)\r
-      {if (fastPaint\r
-            || (getVisibleRect().width != g.getClipBounds().width)\r
-            || (getVisibleRect().height != g.getClipBounds().height))\r
-        {\r
-          g.drawImage(image, 0, 0, this);\r
-          fastPaint = false;\r
-          return;\r
-        }\r
-      }\r
-      imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;\r
-\r
-      if (image == null || imgWidth != image.getWidth()\r
-          || image.getHeight(this) != getHeight())\r
-      {\r
-        image = new BufferedImage(imgWidth, ap.annotationPanel.getHeight(),\r
-                                  BufferedImage.TYPE_INT_RGB);\r
-        gg = (Graphics2D) image.getGraphics();\r
-\r
-        if(av.antiAlias)\r
-        gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                            RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-        gg.setFont(av.getFont());\r
-        fm = gg.getFontMetrics();\r
-      }\r
-\r
-\r
-      drawComponent(gg, av.startRes, av.endRes + 1);\r
-      g.drawImage(image, 0, 0, this);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param horizontal DOCUMENT ME!\r
-     */\r
-    public void fastPaint(int horizontal)\r
-    {\r
-        if ((horizontal == 0) || gg==null ||\r
-                (av.alignment.getAlignmentAnnotation() == null) ||\r
-                (av.alignment.getAlignmentAnnotation().length < 1))\r
-        {\r
-            repaint();\r
-            return;\r
-        }\r
-\r
-        gg.copyArea(0, 0, imgWidth, getHeight(), -horizontal * av.charWidth, 0);\r
-\r
-        int sr = av.startRes;\r
-        int er = av.endRes + 1;\r
-        int transX = 0;\r
-\r
-        if (horizontal > 0) // scrollbar pulled right, image to the left\r
-        {\r
-            transX = (er - sr - horizontal) * av.charWidth;\r
-            sr = er - horizontal;\r
-        }\r
-        else if (horizontal < 0)\r
-        {\r
-            er = sr - horizontal;\r
-        }\r
-\r
-        gg.translate(transX, 0);\r
-\r
-        drawComponent(gg, sr, er);\r
-\r
-        gg.translate(-transX, 0);\r
-\r
-        fastPaint = true;\r
-\r
-        repaint();\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param startRes DOCUMENT ME!\r
-     * @param endRes DOCUMENT ME!\r
-     */\r
-    public void drawComponent(Graphics g, int startRes, int endRes)\r
-    {\r
-      g.setFont(av.getFont());\r
-\r
-      if (fm == null)\r
-        fm = g.getFontMetrics();\r
-\r
-\r
-        g.setColor(Color.white);\r
-        g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getHeight());\r
-\r
-        if ((av.alignment.getAlignmentAnnotation() == null) ||\r
-                (av.alignment.getAlignmentAnnotation().length < 1))\r
-        {\r
-            g.setColor(Color.white);\r
-            g.fillRect(0, 0, getWidth(), getHeight());\r
-            g.setColor(Color.black);\r
-            g.drawString("Alignment has no annotations", 20, 15);\r
-\r
-            return;\r
-        }\r
-\r
-        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
-\r
-        int x = 0;\r
-        int y = 0;\r
-        char lastSS;\r
-        int lastSSX;\r
-        int iconOffset = av.charHeight / 2;\r
-        boolean validRes = false;\r
-\r
-        boolean [] graphGroupDrawn = new boolean[aa.length];\r
-\r
-\r
-        //\u03B2 \u03B1\r
-        for (int i = 0; i < aa.length; i++)\r
-        {\r
-            AlignmentAnnotation row = aa[i];\r
-\r
-            if (!row.visible)\r
-            {\r
-                continue;\r
-            }\r
-\r
-            lastSS = ' ';\r
-            lastSSX = 0;\r
-\r
-\r
-            if (row.graph>0)\r
-            {\r
-                if(row.graphGroup>-1 && graphGroupDrawn[ row.graphGroup ] )\r
-                  continue;\r
-\r
-                // this is so that we draw the characters below the graph\r
-                y += row.height;\r
-\r
-                if (row.hasText)\r
-                {\r
-                    y -= av.charHeight;\r
-                }\r
-            }\r
-\r
-            if (row.hasText)\r
-            {\r
-                iconOffset = av.charHeight / 2;\r
-            }\r
-            else\r
-            {\r
-                iconOffset = 0;\r
-            }\r
-\r
-            int column = startRes;\r
-            int yPos = startRes;\r
-\r
-            while (yPos < endRes)\r
-            {\r
-              if (av.hasHiddenColumns)\r
-              {\r
-                column = av.getColumnSelection().adjustForHiddenColumns(yPos);\r
-                if (column > row.annotations.length-1)\r
-                {\r
-                  break;\r
-                }\r
-              }\r
-              else\r
-                column = yPos;\r
-\r
-                if ((row.annotations.length <= column) ||\r
-                        (row.annotations[column] == null))\r
-                {\r
-                    validRes = false;\r
-                }\r
-                else\r
-                {\r
-                    validRes = true;\r
-                }\r
-\r
-                x = (yPos - startRes) * av.charWidth;\r
-\r
-                if (activeRow == i)\r
-                {\r
-                    g.setColor(Color.red);\r
-\r
-                    if (av.getColumnSelection() != null)\r
-                    {\r
-                        for (int n = 0; n < av.getColumnSelection().size(); n++)\r
-                        {\r
-                            int v = av.getColumnSelection().columnAt(n);\r
-\r
-                            if (v == column)\r
-                            {\r
-                                g.fillRect((column - startRes) * av.charWidth, y,\r
-                                    av.charWidth, row.height);\r
-                            }\r
-                        }\r
-                    }\r
-                }\r
-\r
-                if (validRes &&\r
-                        (row.annotations[column].displayCharacter.length() > 0))\r
-                {\r
-\r
-                    int charOffset = (av.charWidth -\r
-                        fm.charWidth(row.annotations[column].displayCharacter.charAt(\r
-                                0))) / 2;\r
-                    g.setColor(row.annotations[column].colour);\r
-\r
-                    if (column == 0 || row.graph>0)\r
-                    {\r
-                        g.drawString(row.annotations[column].displayCharacter, x+charOffset,\r
-                            y + iconOffset + 3);\r
-                    }\r
-                    else if (((row.annotations[column - 1] == null)\r
-                              ||\r
-                            (!row.annotations[column].displayCharacter.equals(\r
-                             row.annotations[column - 1].displayCharacter))))\r
-                    {\r
-                        g.drawString(row.annotations[column].displayCharacter, x+charOffset,\r
-                            y + iconOffset + 3);\r
-                    }\r
-                }\r
-\r
-                if (row.hasIcons)\r
-                {\r
-                    if (!validRes ||\r
-                            (row.annotations[column].secondaryStructure != lastSS))\r
-                    {\r
-                        switch (lastSS)\r
-                        {\r
-                        case 'H':\r
-                            g.setColor(HELIX_COLOUR);\r
-                            g.fillRoundRect(lastSSX, y + 4 + iconOffset,\r
-                                x - lastSSX, 7, 8, 8);\r
-\r
-                            break;\r
-\r
-                        case 'E':\r
-                            g.setColor(SHEET_COLOUR);\r
-                            g.fillRect(lastSSX, y + 4 + iconOffset,\r
-                                x - lastSSX - 4, 7);\r
-                            g.fillPolygon(new int[] { x - 4, x - 4, x },\r
-                                new int[]\r
-                                {\r
-                                    y + iconOffset, y + 14 + iconOffset,\r
-                                    y + 8 + iconOffset\r
-                                }, 3);\r
-\r
-                            break;\r
-\r
-\r
-                        default:\r
-                            g.setColor(Color.gray);\r
-                            g.fillRect(lastSSX, y + 6 + iconOffset,\r
-                                x - lastSSX, 2);\r
-\r
-                            break;\r
-                        }\r
-\r
-                        if (validRes)\r
-                        {\r
-                            lastSS = row.annotations[column].secondaryStructure;\r
-                        }\r
-                        else\r
-                        {\r
-                            lastSS = ' ';\r
-                        }\r
-\r
-                        lastSSX = x;\r
-                    }\r
-                }\r
-\r
-                yPos++;\r
-            }\r
-\r
-            x += av.charWidth;\r
-\r
-            if (row.hasIcons)\r
-            {\r
-                switch (lastSS)\r
-                {\r
-                case 'H':\r
-                    g.setColor(HELIX_COLOUR);\r
-                    g.fillRoundRect(lastSSX, y + 4 + iconOffset,\r
-                        x - lastSSX, 7, 8, 8);\r
-\r
-                    break;\r
-\r
-                case 'E':\r
-                    g.setColor(SHEET_COLOUR);\r
-\r
-                    if (row.annotations[endRes] !=null\r
-                        && row.annotations[endRes].secondaryStructure != 'E')\r
-                    {\r
-                      g.fillRect(lastSSX, y + 4 + iconOffset,\r
-                                 x - lastSSX - 4, 7);\r
-                      g.fillPolygon(new int[]\r
-                                    {x - 4, x - 4, x},\r
-                                    new int[]\r
-                                    {\r
-                                    y + iconOffset, y + 14 + iconOffset,\r
-                                    y + 7 + iconOffset\r
-                      }, 3);\r
-                    }\r
-                    else\r
-                      g.fillRect(lastSSX, y + 4 + iconOffset,\r
-                                 x - lastSSX, 7);\r
-\r
-                    break;\r
-\r
-\r
-                default:\r
-                    g.setColor(Color.gray);\r
-                    g.fillRect(lastSSX, y + 6 + iconOffset, x - lastSSX, 2);\r
-\r
-                    break;\r
-                }\r
-            }\r
-\r
-            if (row.graph>0)\r
-            {\r
-                if(row.graph == AlignmentAnnotation.LINE_GRAPH )\r
-                {\r
-                  if(row.graphGroup>-1 && !graphGroupDrawn[row.graphGroup])\r
-                   {\r
-                     float groupmax=-999999, groupmin=9999999;\r
-                     for(int gg=0; gg<aa.length; gg++)\r
-                     {\r
-                       if(aa[gg].graphGroup!=row.graphGroup)\r
-                         continue;\r
-\r
-                       if(aa[gg]!=row)\r
-                         aa[gg].visible = false;\r
-\r
-                       if(aa[gg].graphMax>groupmax)\r
-                         groupmax = aa[gg].graphMax;\r
-                       if(aa[gg].graphMin<groupmin)\r
-                         groupmin = aa[gg].graphMin;\r
-                     }\r
-\r
-                     for (int gg = 0; gg < aa.length; gg++)\r
-                     {\r
-                       if (aa[gg].graphGroup == row.graphGroup)\r
-                       {\r
-                         drawLineGraph(g, aa[gg], startRes, endRes, y,\r
-                                       groupmin, groupmax,\r
-                                       row.graphHeight);\r
-                       }\r
-                     }\r
-\r
-                     graphGroupDrawn[ row.graphGroup ] = true;\r
-                   }\r
-                   else\r
-                     drawLineGraph(g, row, startRes, endRes,\r
-                                   y, row.graphMin, row.graphMax, row.graphHeight  );\r
-                }\r
-                else if(row.graph == AlignmentAnnotation.BAR_GRAPH )\r
-                   drawBarGraph(g, row, startRes, endRes,\r
-                                row.graphMin, row.graphMax, y);\r
-            }\r
-\r
-            if (row.graph>0 && row.hasText)\r
-            {\r
-                y += av.charHeight;\r
-            }\r
-\r
-            if (row.graph==0)\r
-            {\r
-                y += aa[i].height;\r
-            }\r
-        }\r
-    }\r
-\r
-    public void drawLineGraph(Graphics g, AlignmentAnnotation aa,\r
-                              int sRes, int eRes,\r
-                              int y,\r
-                              float min, float max,\r
-                              int graphHeight)\r
-    {\r
-      if(sRes>aa.annotations.length)\r
-        return;\r
-\r
-      eRes = Math.min(eRes, aa.annotations.length);\r
-\r
-      int x = 0;\r
-\r
-      //Adjustment for fastpaint to left\r
-      if(eRes<av.endRes)\r
-        eRes++;\r
-\r
-      if(sRes==0)\r
-      {\r
-        sRes++;\r
-        x+=av.charWidth;\r
-      }\r
-\r
-      int y1=y, y2=y;\r
-      float range = max - min;\r
-\r
-      ////Draw origin\r
-      if(min<0)\r
-        y2 = (int)(y - (0-min / range)*graphHeight);\r
-\r
-      g.setColor(Color.gray);\r
-      g.drawLine(x-av.charWidth,y2,(eRes-sRes+1)*av.charWidth,y2);\r
-\r
-\r
-      if(aa.threshold!=null)\r
-      {\r
-          g.setColor(aa.threshold.colour);\r
-          Graphics2D g2 = (Graphics2D)g;\r
-          g2.setStroke(new BasicStroke(1,\r
-                                        BasicStroke.CAP_SQUARE,\r
-                                        BasicStroke.JOIN_ROUND, 3f,\r
-                                        new float[] { 5f, 3f }, 0f));\r
-\r
-          y2 = (int)(y - ((aa.threshold.value-min) / range)*graphHeight);\r
-          g.drawLine(x-av.charWidth,y2,(eRes-sRes)*av.charWidth,y2);\r
-          g2.setStroke(new BasicStroke());\r
-      }\r
-\r
-      eRes = Math.min(eRes, aa.annotations.length);\r
-\r
-      int column = sRes;\r
-      int yPos = sRes;\r
-      int aaMax = aa.annotations.length-1;\r
-\r
-      while( yPos < eRes )\r
-      {\r
-        if(av.hasHiddenColumns)\r
-        {\r
-          column = av.getColumnSelection().adjustForHiddenColumns(yPos);\r
-          if(column > aaMax)\r
-          {\r
-            break;\r
-          }\r
-        }\r
-        else\r
-          column = yPos;\r
-\r
-        yPos ++;\r
-\r
-        if(aa.annotations[column]==null || aa.annotations[column-1]==null)\r
-        {\r
-          x+=av.charWidth;\r
-          continue;\r
-        }\r
-\r
-          g.setColor(aa.annotations[column].colour);\r
-          y1 = y - (int) (((aa.annotations[column-1].value-min) / range) * graphHeight);\r
-          y2 = y - (int) (((aa.annotations[column].value-min) / range) * graphHeight);\r
-          g.drawLine(x-av.charWidth/2, y1, x+av.charWidth/2, y2);\r
-          x += av.charWidth;\r
-       }\r
-    }\r
-\r
-    public void drawBarGraph(Graphics g, AlignmentAnnotation aa,\r
-                             int sRes, int eRes,\r
-                             float min, float max,\r
-                             int y)\r
-    {\r
-      if(sRes>aa.annotations.length)\r
-        return;\r
-\r
-      eRes = Math.min(eRes, aa.annotations.length);\r
-\r
-      int x=0, y1, y2;\r
-\r
-      float range = max - min;\r
-\r
-      if(aa.threshold!=null)\r
-      {\r
-          g.setColor(aa.threshold.colour);\r
-          Graphics2D g2 = (Graphics2D)g;\r
-          g2.setStroke(new BasicStroke(1,\r
-                                        BasicStroke.CAP_SQUARE,\r
-                                        BasicStroke.JOIN_ROUND, 3f,\r
-                                        new float[] { 5f, 3f }, 0f));\r
-\r
-          y2 = (int)(y - ((aa.threshold.value-min) / range)*aa.graphHeight);\r
-          g.drawLine(x-av.charWidth,y2,(eRes-sRes)*av.charWidth,y2);\r
-          g2.setStroke(new BasicStroke());\r
-      }\r
-\r
-      y1 = y2 = y;\r
-\r
-      if(min<0)\r
-        y2 = (int)(y - (0-min / (range))*aa.graphHeight);\r
-\r
-      g.setColor(Color.gray);\r
-\r
-      g.drawLine(x,y2,(eRes-sRes)*av.charWidth,y2);\r
-\r
-\r
-      int column = sRes;\r
-      int yPos = sRes;\r
-      int aaMax = aa.annotations.length-1;\r
-\r
-      while( yPos < eRes )\r
-      {\r
-        if(av.hasHiddenColumns)\r
-        {\r
-          column = av.getColumnSelection().adjustForHiddenColumns(yPos);\r
-          if(column > aaMax)\r
-          {\r
-            break;\r
-          }\r
-        }\r
-        else\r
-          column = yPos;\r
-\r
-        yPos ++;\r
-\r
-        if (aa.annotations[column] == null)\r
-        {\r
-          x += av.charWidth;\r
-          continue;\r
-        }\r
-\r
-\r
-          g.setColor(aa.annotations[column].colour);\r
-          y1 = y - (int) (((aa.annotations[column].value-min) / (range)) * aa.graphHeight);\r
-\r
-          if(y1-y2>0)\r
-            g.fillRect(x, y2, av.charWidth, y1-y2 );\r
-          else\r
-            g.fillRect(x, y1, av.charWidth, y2-y1 );\r
-\r
-          x += av.charWidth;\r
-      }\r
-\r
-    }\r
-\r
-    // used by overview window\r
-    public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)\r
-    {\r
-      g.setColor(Color.white);\r
-      g.fillRect(0, 0, width, y);\r
-      g.setColor(new Color(0, 0, 180));\r
-\r
-      int x = 0, height;\r
-\r
-      for (int j = sRes; j < eRes; j++)\r
-      {\r
-          g.setColor(aa.annotations[j].colour);\r
-\r
-          height = (int) ((aa.annotations[j].value / aa.graphMax) * y);\r
-          if(height>y)\r
-            height = y;\r
-\r
-          g.fillRect(x, y - height, av.charWidth, height);\r
-          x += av.charWidth;\r
-      }\r
-    }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class AnnotationPanel extends JPanel implements MouseListener,
+    MouseMotionListener, ActionListener, AdjustmentListener
+{
+    final String HELIX = "Helix";
+    final String SHEET = "Sheet";
+    final String LABEL = "Label";
+    final String REMOVE = "Remove Annotation";
+    final String COLOUR = "Colour";
+    final Color HELIX_COLOUR = Color.red.darker();
+    final Color SHEET_COLOUR = Color.green.darker().darker();
+
+    /** DOCUMENT ME!! */
+    AlignViewport av;
+    AlignmentPanel ap;
+    int activeRow = -1;
+    BufferedImage image;
+    Graphics2D gg;
+    FontMetrics fm;
+    int imgWidth = 0;
+    boolean fastPaint = false;
+
+    //Used For mouse Dragging and resizing graphs
+    int graphStretch = -1;
+    int graphStretchY = -1;
+    int min; //used by mouseDragged to see if user
+    int max; //used by mouseDragged to see if user
+    boolean mouseDragging = false;
+
+    boolean MAC = false;
+
+    /**
+     * Creates a new AnnotationPanel object.
+     *
+     * @param ap DOCUMENT ME!
+     */
+    public AnnotationPanel(AlignmentPanel ap)
+    {
+
+    if(System.getProperty("os.name").startsWith("Mac"))
+      MAC = true;
+
+        ToolTipManager.sharedInstance().registerComponent(this);
+        ToolTipManager.sharedInstance().setInitialDelay(0);
+        ToolTipManager.sharedInstance().setDismissDelay(10000);
+        this.ap = ap;
+        av = ap.av;
+        this.setLayout(null);
+        addMouseListener(this);
+        addMouseMotionListener(this);
+        ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener(this);
+    }
+
+    public AnnotationPanel(AlignViewport av)
+    {
+      this.av = av;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void adjustmentValueChanged(AdjustmentEvent evt)
+    {
+        ap.alabels.setScrollOffset(-evt.getValue());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public int adjustPanelHeight()
+    {
+        // setHeight of panels
+        image = null;
+        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+        int height = 0;
+
+        if (aa != null)
+        {
+            for (int i = 0; i < aa.length; i++)
+            {
+                if (!aa[i].visible)
+                {
+                    continue;
+                }
+
+                aa[i].height = 0;
+
+                if (aa[i].hasText)
+                {
+                    aa[i].height += av.charHeight;
+                }
+
+                if (aa[i].hasIcons)
+                {
+                    aa[i].height += 16;
+                }
+
+                if (aa[i].graph>0)
+                {
+                    aa[i].height += aa[i].graphHeight;
+                }
+
+                if (aa[i].height == 0)
+                {
+                    aa[i].height = 20;
+                }
+
+                height += aa[i].height;
+            }
+        }
+        else
+        {
+            height = 20;
+        }
+
+        this.setPreferredSize(new Dimension(1, height));
+
+        return height;
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void actionPerformed(ActionEvent evt)
+    {
+        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+        Annotation[] anot = aa[activeRow].annotations;
+
+        if (evt.getActionCommand().equals(REMOVE))
+        {
+            for (int i = 0; i < av.getColumnSelection().size(); i++)
+            {
+                anot[av.getColumnSelection().columnAt(i)] = null;
+            }
+        }
+        else if (evt.getActionCommand().equals(LABEL))
+        {
+            String label = JOptionPane.showInputDialog(this, "Enter Label ",
+                    "Enter label", JOptionPane.QUESTION_MESSAGE);
+
+            if (label == null)
+            {
+                return;
+            }
+
+            if ((label.length() > 0) && !aa[activeRow].hasText)
+            {
+                aa[activeRow].hasText = true;
+            }
+
+            for (int i = 0; i < av.getColumnSelection().size(); i++)
+            {
+                int index = av.getColumnSelection().columnAt(i);
+
+                if (anot[index] == null)
+                {
+                    anot[index] = new Annotation(label, "", ' ', 0);
+                }
+
+                anot[index].displayCharacter = label;
+            }
+        }
+        else if (evt.getActionCommand().equals(COLOUR))
+        {
+            Color col = JColorChooser.showDialog(this,
+                    "Choose foreground colour", Color.black);
+
+            for (int i = 0; i < av.getColumnSelection().size(); i++)
+            {
+                int index = av.getColumnSelection().columnAt(i);
+
+                if (anot[index] == null)
+                {
+                    anot[index] = new Annotation("", "", ' ', 0);
+                }
+
+                anot[index].colour = col;
+            }
+        }
+        else // HELIX OR SHEET
+        {
+            char type = 0;
+            String symbol = "\u03B1";
+
+            if (evt.getActionCommand().equals(HELIX))
+            {
+                type = 'H';
+            }
+            else if (evt.getActionCommand().equals(SHEET))
+            {
+                type = 'E';
+                symbol = "\u03B2";
+            }
+
+            if (!aa[activeRow].hasIcons)
+            {
+                aa[activeRow].hasIcons = true;
+            }
+
+            String label = JOptionPane.showInputDialog("Enter a label for the structure?",
+                    symbol);
+
+            if (label == null)
+            {
+                return;
+            }
+
+            if ((label.length() > 0) && !aa[activeRow].hasText)
+            {
+                aa[activeRow].hasText = true;
+            }
+
+            for (int i = 0; i < av.getColumnSelection().size(); i++)
+            {
+                int index = av.getColumnSelection().columnAt(i);
+
+                if (anot[index] == null)
+                {
+                    anot[index] = new Annotation(label, "", type, 0);
+                }
+
+                anot[index].secondaryStructure = type;
+                anot[index].displayCharacter = label;
+            }
+        }
+
+        adjustPanelHeight();
+        repaint();
+
+        return;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent evt)
+    {
+
+
+        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+        if(aa==null)
+          return;
+
+
+        int height = 0;
+        activeRow = -1;
+
+
+        for (int i = 0; i < aa.length; i++)
+        {
+            if (aa[i].visible)
+            {
+              height += aa[i].height;
+            }
+
+            if (evt.getY() < height)
+            {
+                if (aa[i].editable)
+                {
+                    activeRow = i;
+                }
+                else if(aa[i].graph>0)
+                {
+                    //Stretch Graph
+                    graphStretch = i;
+                    graphStretchY = evt.getY();
+                }
+
+                break;
+            }
+        }
+
+
+        if (SwingUtilities.isRightMouseButton(evt))
+        {
+            if (av.getColumnSelection() == null)
+            {
+                return;
+            }
+
+            JPopupMenu pop = new JPopupMenu("Structure type");
+            JMenuItem item = new JMenuItem(HELIX);
+            item.addActionListener(this);
+            pop.add(item);
+            item = new JMenuItem(SHEET);
+            item.addActionListener(this);
+            pop.add(item);
+            item = new JMenuItem(LABEL);
+            item.addActionListener(this);
+            pop.add(item);
+            item = new JMenuItem(COLOUR);
+            item.addActionListener(this);
+            pop.add(item);
+            item = new JMenuItem(REMOVE);
+            item.addActionListener(this);
+            pop.add(item);
+            pop.show(this, evt.getX(), evt.getY());
+
+            return;
+        }
+
+        if (aa == null)
+        {
+            return;
+        }
+
+        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+        min = res;
+        max = res;
+
+        if (av.getColumnSelection().contains(res))
+          av.getColumnSelection().removeElement(res);
+        else
+        {
+            av.getColumnSelection().addElement(res);
+            SequenceGroup sg = new SequenceGroup();
+
+            for (int i = 0; i < av.alignment.getSequences().size(); i++)
+            {
+                sg.addSequence(av.alignment.getSequenceAt(i), false);
+            }
+
+            sg.setStartRes(res);
+            sg.setEndRes(res);
+            av.setSelectionGroup(sg);
+        }
+
+        ap.repaint();
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent evt)
+    {
+      graphStretch = -1;
+      graphStretchY = -1;
+      mouseDragging = false;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent evt)
+    {
+      if(mouseDragging)
+        ap.seqPanel.scrollCanvas(null);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent evt)
+    {
+      if(mouseDragging)
+        ap.seqPanel.scrollCanvas(evt);
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent evt)
+    {
+      if(graphStretch>-1)
+      {
+        av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight += graphStretchY - evt.getY();
+        if(av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight <0)
+          av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight = 0;
+        graphStretchY = evt.getY();
+        adjustPanelHeight();
+        ap.repaint();
+      }
+      else
+      {
+        mouseDragging = true;
+
+        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+        SequenceGroup sg = av.getSelectionGroup();
+
+        if (res < min)
+        {
+            min = res;
+        }
+
+        if (res > max)
+        {
+            max = res;
+        }
+
+        if (sg != null)
+        {
+            if (!av.getColumnSelection().contains(res))
+            {
+                av.getColumnSelection().addElement(res);
+            }
+
+            if (res > sg.getStartRes())
+            {
+                sg.setEndRes(res);
+            }
+            else if (res < sg.getStartRes())
+            {
+                sg.setStartRes(res);
+            }
+
+            for (int i = min; i <= max; i++)
+            {
+                if ((i < sg.getStartRes()) || (i > sg.getEndRes()))
+                {
+                    av.getColumnSelection().removeElement(i);
+                }
+                else
+                {
+                    av.getColumnSelection().addElement(i);
+                }
+            }
+
+            ap.repaint();
+        }
+
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseMoved(MouseEvent evt)
+    {
+        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+
+        if (aa == null)
+        {
+            return;
+        }
+
+        int row = -1;
+        int height = 0;
+
+        for (int i = 0; i < aa.length; i++)
+        {
+            if (aa[i].visible)
+            {
+                height += aa[i].height;
+            }
+
+            if (evt.getY() < height)
+            {
+                row = i;
+
+                break;
+            }
+        }
+
+        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+        if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+        if (row > -1 && res<aa[row].annotations.length)
+        {
+            if(aa[row].graphGroup>-1)
+            {
+              StringBuffer tip = new StringBuffer("<html>");
+              for (int gg = 0; gg < aa.length; gg++)
+              {
+                if (aa[gg].graphGroup == aa[row].graphGroup && aa[gg].annotations[res]!=null)
+                  tip.append(aa[gg].label+" "+aa[gg].annotations[res].description+"<br>" );
+              }
+              if(tip.length()!=6)
+              {
+                tip.setLength(tip.length() - 4);
+                this.setToolTipText(tip.toString() + "</html>");
+              }
+            }
+            else if(aa[row].annotations[res] != null)
+              this.setToolTipText(aa[row].annotations[res].description);
+
+            if(aa[row].annotations[res]!=null)
+            {
+              StringBuffer text = new StringBuffer("Sequence position " +
+                                                   (res + 1) + "  " +
+                                                   aa[row].annotations[res].description);
+
+              ap.alignFrame.statusBar.setText(text.toString());
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseClicked(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+      g.setColor(Color.white);
+      g.fillRect(0, 0, getWidth(), getHeight());
+
+      if(image!=null)
+      {if (fastPaint
+            || (getVisibleRect().width != g.getClipBounds().width)
+            || (getVisibleRect().height != g.getClipBounds().height))
+        {
+          g.drawImage(image, 0, 0, this);
+          fastPaint = false;
+          return;
+        }
+      }
+      imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;
+
+      if (image == null || imgWidth != image.getWidth()
+          || image.getHeight(this) != getHeight())
+      {
+        image = new BufferedImage(imgWidth, ap.annotationPanel.getHeight(),
+                                  BufferedImage.TYPE_INT_RGB);
+        gg = (Graphics2D) image.getGraphics();
+
+        if(av.antiAlias)
+        gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                            RenderingHints.VALUE_ANTIALIAS_ON);
+
+        gg.setFont(av.getFont());
+        fm = gg.getFontMetrics();
+      }
+
+
+      drawComponent(gg, av.startRes, av.endRes + 1);
+      g.drawImage(image, 0, 0, this);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param horizontal DOCUMENT ME!
+     */
+    public void fastPaint(int horizontal)
+    {
+        if ((horizontal == 0) || gg==null ||
+                (av.alignment.getAlignmentAnnotation() == null) ||
+                (av.alignment.getAlignmentAnnotation().length < 1))
+        {
+            repaint();
+            return;
+        }
+
+        gg.copyArea(0, 0, imgWidth, getHeight(), -horizontal * av.charWidth, 0);
+
+        int sr = av.startRes;
+        int er = av.endRes + 1;
+        int transX = 0;
+
+        if (horizontal > 0) // scrollbar pulled right, image to the left
+        {
+            transX = (er - sr - horizontal) * av.charWidth;
+            sr = er - horizontal;
+        }
+        else if (horizontal < 0)
+        {
+            er = sr - horizontal;
+        }
+
+        gg.translate(transX, 0);
+
+        drawComponent(gg, sr, er);
+
+        gg.translate(-transX, 0);
+
+        fastPaint = true;
+
+        repaint();
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param startRes DOCUMENT ME!
+     * @param endRes DOCUMENT ME!
+     */
+    public void drawComponent(Graphics g, int startRes, int endRes)
+    {
+      g.setFont(av.getFont());
+
+      if (fm == null)
+        fm = g.getFontMetrics();
+
+
+        g.setColor(Color.white);
+        g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getHeight());
+
+        if ( (av.alignment.getAlignmentAnnotation() == null) ||
+                (av.alignment.getAlignmentAnnotation().length < 1))
+        {
+            g.setColor(Color.white);
+            g.fillRect(0, 0, getWidth(), getHeight());
+            g.setColor(Color.black);
+            if(av.validCharWidth)
+              g.drawString("Alignment has no annotations", 20, 15);
+
+            return;
+        }
+
+        AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+
+        int x = 0, y = 0;
+        int column=0;
+        char lastSS;
+        int lastSSX;
+        int iconOffset = av.charHeight / 2;
+        boolean validRes = false;
+
+        boolean [] graphGroupDrawn = new boolean[aa.length];
+
+
+        //\u03B2 \u03B1
+        for (int i = 0; i < aa.length; i++)
+        {
+            AlignmentAnnotation row = aa[i];
+
+            if (!row.visible)
+            {
+                continue;
+            }
+
+            lastSS = ' ';
+            lastSSX = 0;
+
+            if (row.graph>0)
+            {
+                if(row.graphGroup>-1 && graphGroupDrawn[ row.graphGroup ] )
+                  continue;
+
+                // this is so that we draw the characters below the graph
+                y += row.height;
+
+                if (row.hasText)
+                {
+                    y -= av.charHeight;
+                }
+            }
+
+            if (row.hasText)
+            {
+                iconOffset = av.charHeight / 2 + 4;
+            }
+            else
+            {
+                iconOffset = 0;
+            }
+
+            x = 0;
+            while (x < endRes-startRes)
+            {
+              if (av.hasHiddenColumns)
+              {
+                column = av.getColumnSelection().adjustForHiddenColumns(startRes+x);
+                if (column > row.annotations.length-1)
+                {
+                  break;
+                }
+              }
+              else
+                column = startRes+x;
+
+
+                if ((row.annotations.length <= column) ||
+                        (row.annotations[column] == null))
+                {
+                    validRes = false;
+                }
+                else
+                {
+                    validRes = true;
+                }
+
+
+                if (activeRow == i)
+                {
+                    g.setColor(Color.red);
+
+                    if (av.getColumnSelection() != null)
+                    {
+                        for (int n = 0; n < av.getColumnSelection().size(); n++)
+                        {
+                            int v = av.getColumnSelection().columnAt(n);
+
+                            if (v == column)
+                            {
+                                g.fillRect(x * av.charWidth, y,
+                                    av.charWidth, av.charHeight);
+                            }
+                        }
+                    }
+                }
+
+                if (av.validCharWidth && validRes &&
+                        (row.annotations[column].displayCharacter.length() > 0))
+                {
+
+                    int charOffset = (av.charWidth -
+                        fm.charWidth(row.annotations[column].displayCharacter.charAt(
+                                0))) / 2;
+                    g.setColor(row.annotations[column].colour);
+
+                    if (column == 0 || row.graph>0)
+                    {
+                        g.drawString(row.annotations[column].displayCharacter,
+                                     (x*av.charWidth)+charOffset,
+                            y + iconOffset );
+                    }
+                    else if (
+                        row.annotations[column - 1] == null
+                        ||(!row.annotations[column].displayCharacter.equals(
+                            row.annotations[column - 1].displayCharacter)
+                        ||
+                  (row.annotations[column].displayCharacter.length() <2 &&
+                   row.annotations[column].secondaryStructure==' ')))
+                    {
+                        g.drawString(row.annotations[column].displayCharacter,
+                                     x*av.charWidth+charOffset,
+                                     y + iconOffset );
+                    }
+                }
+
+                if (row.hasIcons)
+                {
+                    if (!validRes ||
+                            (row.annotations[column].secondaryStructure != lastSS))
+                    {
+                        switch (lastSS)
+                        {
+                        case 'H':
+                          g.setColor(HELIX_COLOUR);
+                          if (MAC)
+                          {
+                            //Off by 1 offset when drawing rects and ovals
+                            //to offscreen image on the MAC
+                            g.fillRoundRect(lastSSX, y + 4 + iconOffset,
+                                            (x*av.charWidth) - lastSSX, 7, 8, 8);
+                            break;
+                          }
+
+                          int sCol = (lastSSX / av.charWidth) + startRes;
+                          int x1 = lastSSX;
+                          int x2 = (x*av.charWidth);
+
+                         if(sCol==0 ||
+                            row.annotations[sCol-1]==null ||
+                            row.annotations[sCol-1].secondaryStructure!='H')
+                         {
+                           g.fillArc(lastSSX, y+4+iconOffset, av.charWidth, 8, 90,180) ;
+                           x1 += av.charWidth/2;
+                         }
+
+                          if(row.annotations[column]==null ||
+                             row.annotations[column].secondaryStructure!='H')
+                          {
+                            g.fillArc((x*av.charWidth)-av.charWidth,
+                                      y+4+iconOffset, av.charWidth, 8, 270,180);
+                            x2 -= av.charWidth/2;
+                          }
+
+                          g.fillRect(x1, y+4+iconOffset, x2-x1, 8);
+                              break;
+
+                        case 'E':
+                            g.setColor(SHEET_COLOUR);
+                            g.fillRect(lastSSX, y + 4 + iconOffset,
+                                (x*av.charWidth) - lastSSX - 4, 7);
+                            g.fillPolygon(new int[] { (x*av.charWidth) - 4,
+                                          (x*av.charWidth) - 4,
+                                          (x*av.charWidth) },
+                                new int[]
+                                {
+                                    y + iconOffset, y + 14 + iconOffset,
+                                    y + 8 + iconOffset
+                                }, 3);
+
+                            break;
+
+
+                        default:
+                            g.setColor(Color.gray);
+                            g.fillRect(lastSSX, y + 6 + iconOffset,
+                                (x*av.charWidth) - lastSSX, 2);
+
+                            break;
+                        }
+
+                        if (validRes)
+                        {
+                            lastSS = row.annotations[column].secondaryStructure;
+                        }
+                        else
+                        {
+                            lastSS = ' ';
+                        }
+
+                        lastSSX = (x*av.charWidth);
+                    }
+                }
+
+
+            column++;
+            x++;
+            }
+
+            if(column>=row.annotations.length)
+                column = row.annotations.length-1;
+
+          //  x ++;
+
+            if (row.hasIcons)
+            {
+              switch (lastSS)
+              {
+                case 'H':
+                  g.setColor(HELIX_COLOUR);
+                  if (MAC)
+                  {
+                    //Off by 1 offset when drawing rects and ovals
+                    //to offscreen image on the MAC
+                    g.fillRoundRect(lastSSX, y + 4 + iconOffset,
+                                    (x*av.charWidth) - lastSSX, 7, 8, 8);
+                    break;
+                  }
+
+                  int sCol = (lastSSX / av.charWidth) + startRes;
+                  int x1 = lastSSX;
+                  int x2 = (x*av.charWidth);
+
+                  if (sCol == 0 ||
+                      row.annotations[sCol - 1] == null ||
+                      row.annotations[sCol - 1].secondaryStructure != 'H')
+                  {
+                    g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90, 180);
+                    x1 += av.charWidth / 2;
+                  }
+
+                  if (row.annotations[column] == null ||
+                      row.annotations[column].secondaryStructure != 'H')
+                  {
+                    g.fillArc((x*av.charWidth) - av.charWidth,
+                              y + 4 + iconOffset, av.charWidth, 8, 270,
+                              180);
+                    x2 -= av.charWidth / 2;
+                  }
+
+                  g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
+
+                  break;
+
+                case 'E':
+                  g.setColor(SHEET_COLOUR);
+
+                  if (row.annotations[endRes] == null
+                      || row.annotations[endRes].secondaryStructure != 'E')
+                  {
+                    g.fillRect(lastSSX, y + 4 + iconOffset,
+                               (x*av.charWidth) - lastSSX - 4, 7);
+                    g.fillPolygon(new int[]
+                                  {(x*av.charWidth) - 4,
+                                  (x*av.charWidth) - 4,
+                                 (x*av.charWidth)},
+                                  new int[]
+                                  {
+                                  y + iconOffset, y + 14 + iconOffset,
+                                  y + 7 + iconOffset
+                    }, 3);
+                  }
+                  else
+                   {
+                     g.fillRect(lastSSX, y + 4 + iconOffset,
+                                (x+1) * av.charWidth - lastSSX, 7);
+                   }
+                  break;
+
+                default:
+                  g.setColor(Color.gray);
+                  if(!av.wrapAlignment || endRes==av.endRes)
+                  g.fillRect(lastSSX, y + 6 + iconOffset,
+                             (x*av.charWidth) - lastSSX, 2);
+
+                  break;
+              }
+          }
+
+            if (row.graph>0 && row.graphHeight>0)
+            {
+                if(row.graph == AlignmentAnnotation.LINE_GRAPH )
+                {
+                  if(row.graphGroup>-1 && !graphGroupDrawn[row.graphGroup])
+                   {
+                     float groupmax=-999999, groupmin=9999999;
+                     for(int gg=0; gg<aa.length; gg++)
+                     {
+                       if(aa[gg].graphGroup!=row.graphGroup)
+                         continue;
+
+                       if(aa[gg]!=row)
+                         aa[gg].visible = false;
+
+                       if(aa[gg].graphMax>groupmax)
+                         groupmax = aa[gg].graphMax;
+                       if(aa[gg].graphMin<groupmin)
+                         groupmin = aa[gg].graphMin;
+                     }
+
+                     for (int gg = 0; gg < aa.length; gg++)
+                     {
+                       if (aa[gg].graphGroup == row.graphGroup)
+                       {
+                         drawLineGraph(g, aa[gg], startRes, endRes, y,
+                                       groupmin, groupmax,
+                                       row.graphHeight);
+                       }
+                     }
+
+                     graphGroupDrawn[ row.graphGroup ] = true;
+                   }
+                   else
+                     drawLineGraph(g, row, startRes, endRes,
+                                   y, row.graphMin, row.graphMax, row.graphHeight  );
+                }
+                else if(row.graph == AlignmentAnnotation.BAR_GRAPH )
+                   drawBarGraph(g, row, startRes, endRes,
+                                row.graphMin, row.graphMax, y);
+            }
+
+            if (row.graph>0 && row.hasText)
+            {
+                y += av.charHeight;
+            }
+
+            if (row.graph==0)
+            {
+                y += aa[i].height;
+            }
+        }
+    }
+
+    public void drawLineGraph(Graphics g, AlignmentAnnotation aa,
+                              int sRes, int eRes,
+                              int y,
+                              float min, float max,
+                              int graphHeight)
+    {
+      if(sRes>aa.annotations.length)
+        return;
+
+
+      int x = 0;
+
+      //Adjustment for fastpaint to left
+      if(eRes<av.endRes)
+        eRes++;
+
+      eRes = Math.min(eRes, aa.annotations.length);
+
+      if(sRes==0)
+      {
+        x++;
+      }
+
+      int y1=y, y2=y;
+      float range = max - min;
+
+      ////Draw origin
+      if(min<0)
+        y2 = y - (int)((0-min / range)*graphHeight);
+
+      g.setColor(Color.gray);
+      g.drawLine(x-av.charWidth,y2,(eRes-sRes+1)*av.charWidth,y2);
+
+      eRes = Math.min(eRes, aa.annotations.length);
+
+      int column;
+      int aaMax = aa.annotations.length-1;
+
+      while( x < eRes - sRes )
+      {
+        column = sRes + x;
+        if(av.hasHiddenColumns)
+        {
+          column = av.getColumnSelection().adjustForHiddenColumns(column);
+        }
+
+        if (column > aaMax)
+        {
+          break;
+        }
+
+        if(aa.annotations[column]==null || aa.annotations[column-1]==null)
+        {
+          x++;
+          continue;
+        }
+
+
+          g.setColor(aa.annotations[column].colour);
+          y1 = y - (int) (((aa.annotations[column-1].value-min) / range) * graphHeight);
+          y2 = y - (int) (((aa.annotations[column].value-min) / range) * graphHeight);
+
+          g.drawLine(x*av.charWidth-av.charWidth/2, y1, x*av.charWidth+av.charWidth/2, y2);
+          x ++;
+       }
+
+       if(aa.threshold!=null)
+       {
+           g.setColor(aa.threshold.colour);
+           Graphics2D g2 = (Graphics2D)g;
+           g2.setStroke(new BasicStroke(1,
+                                         BasicStroke.CAP_SQUARE,
+                                         BasicStroke.JOIN_ROUND, 3f,
+                                         new float[] { 5f, 3f }, 0f));
+
+           y2 = (int)(y - ((aa.threshold.value-min) / range)*graphHeight);
+           g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);
+           g2.setStroke(new BasicStroke());
+      }
+    }
+
+    public void drawBarGraph(Graphics g, AlignmentAnnotation aa,
+                             int sRes, int eRes,
+                             float min, float max,
+                             int y)
+    {
+      if(sRes>aa.annotations.length)
+        return;
+
+      eRes = Math.min(eRes, aa.annotations.length);
+
+      int x=0, y1=y, y2=y;
+
+      float range = max - min;
+
+      if(min<0)
+        y2 = y - (int)((0-min / (range))*aa.graphHeight);
+
+      g.setColor(Color.gray);
+
+      g.drawLine(x,y2,(eRes-sRes)*av.charWidth,y2);
+
+      int column;
+      int aaMax = aa.annotations.length-1;
+
+      while( x < eRes-sRes )
+      {
+        column = sRes + x;
+        if(av.hasHiddenColumns)
+        {
+          column = av.getColumnSelection().adjustForHiddenColumns(column);
+        }
+
+        if(column > aaMax)
+        {
+            break;
+        }
+
+        if (aa.annotations[column] == null)
+        {
+          x ++;
+          continue;
+        }
+
+          g.setColor(aa.annotations[column].colour);
+          y1 = y - (int) (((aa.annotations[column].value-min) / (range)) * aa.graphHeight);
+
+          if(y1-y2>0)
+            g.fillRect(x*av.charWidth, y2, av.charWidth, y1-y2 );
+          else
+            g.fillRect(x*av.charWidth, y1, av.charWidth, y2-y1 );
+
+          x ++ ;
+
+      }
+      if(aa.threshold!=null)
+      {
+          g.setColor(aa.threshold.colour);
+          Graphics2D g2 = (Graphics2D)g;
+          g2.setStroke(new BasicStroke(1,
+                                        BasicStroke.CAP_SQUARE,
+                                        BasicStroke.JOIN_ROUND, 3f,
+                                        new float[] { 5f, 3f }, 0f));
+
+          y2 = (int)(y - ((aa.threshold.value-min) / range)*aa.graphHeight);
+          g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);
+          g2.setStroke(new BasicStroke());
+      }
+    }
+
+    // used by overview window
+    public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)
+    {
+      eRes = Math.min(eRes, aa.annotations.length);
+      g.setColor(Color.white);
+      g.fillRect(0, 0, width, y);
+      g.setColor(new Color(0, 0, 180));
+
+      int x = 0, height;
+
+      for (int j = sRes; j < eRes; j++)
+      {
+          g.setColor(aa.annotations[j].colour);
+
+          height = (int) ((aa.annotations[j].value / aa.graphMax) * y);
+          if(height>y)
+            height = y;
+
+          g.fillRect(x, y - height, av.charWidth, height);
+          x += av.charWidth;
+      }
+    }
+
+}
diff --git a/src/jalview/gui/ColumnSelection.java b/src/jalview/gui/ColumnSelection.java
deleted file mode 100755 (executable)
index 26dba83..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import java.util.*;\r
-\r
-/**\r
- * NOTE: Columns are zero based.\r
- */\r
-public class ColumnSelection\r
-{\r
-    Vector selected = new Vector();\r
-\r
-    //Vector of int [] {startCol, endCol}\r
-    Vector hiddenColumns;\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param col DOCUMENT ME!\r
-     */\r
-    public void addElement(int col)\r
-    {\r
-        if (!selected.contains(new Integer(col)))\r
-        {\r
-            selected.addElement(new Integer(col));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void clear()\r
-    {\r
-        selected.removeAllElements();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param col DOCUMENT ME!\r
-     */\r
-    public void removeElement(int col)\r
-    {\r
-        Integer colInt = new Integer(col);\r
-\r
-        if (selected.contains(colInt))\r
-        {\r
-            selected.removeElement(colInt);\r
-        }\r
-    }\r
-\r
-    public void removeElements(int start, int end)\r
-    {\r
-      Integer colInt;\r
-      for(int i=start; i<end; i++)\r
-      {\r
-        colInt = new Integer(i);\r
-        if (selected.contains(colInt))\r
-        {\r
-            selected.removeElement(colInt);\r
-        }\r
-      }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param col DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean contains(int col)\r
-    {\r
-        return selected.contains(new Integer(col));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int columnAt(int i)\r
-    {\r
-        return ((Integer) selected.elementAt(i)).intValue();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int size()\r
-    {\r
-        return selected.size();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getMax()\r
-    {\r
-        int max = -1;\r
-\r
-        for (int i = 0; i < selected.size(); i++)\r
-        {\r
-            if (columnAt(i) > max)\r
-            {\r
-                max = columnAt(i);\r
-            }\r
-        }\r
-\r
-        return max;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getMin()\r
-    {\r
-        int min = 1000000000;\r
-\r
-        for (int i = 0; i < selected.size(); i++)\r
-        {\r
-            if (columnAt(i) < min)\r
-            {\r
-                min = columnAt(i);\r
-            }\r
-        }\r
-\r
-        return min;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param start DOCUMENT ME!\r
-     * @param change DOCUMENT ME!\r
-     */\r
-    public void compensateForEdit(int start, int change)\r
-    {\r
-        for (int i = 0; i < size(); i++)\r
-        {\r
-            int temp = columnAt(i);\r
-\r
-            if (temp >= start)\r
-            {\r
-                selected.setElementAt(new Integer(temp - change), i);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * This Method is used to return all the HiddenColumn regions\r
-     * less than the given index.\r
-     * @param end int\r
-     * @return Vector\r
-     */\r
-    public Vector getHiddenColumns()\r
-    {\r
-      return hiddenColumns;\r
-    }\r
-\r
-    public int adjustForHiddenColumns(int column)\r
-    {\r
-      int result = column;\r
-      if (hiddenColumns != null)\r
-      {\r
-        for (int i = 0; i < hiddenColumns.size(); i++)\r
-        {\r
-          int[] region = (int[]) hiddenColumns.elementAt(i);\r
-          if (result >= region[0])\r
-          {\r
-            result += region[1] - region[0] + 1;\r
-          }\r
-        }\r
-      }\r
-      return result;\r
-    }\r
-\r
-    /**\r
-     * Use this method to find out where a visible column is in the alignment\r
-     * when hidden columns exist\r
-     * @param hiddenColumn int\r
-     * @return int\r
-     */\r
-    public int findColumnPosition(int hiddenColumn)\r
-    {\r
-      int result = hiddenColumn;\r
-      if (hiddenColumns != null)\r
-      {\r
-        int index = 0;\r
-        int gaps = 0;\r
-        do\r
-        {\r
-          int[] region = (int[]) hiddenColumns.elementAt(index);\r
-          if (hiddenColumn > region[1])\r
-          {\r
-            result -= region[1]+1-region[0];\r
-          }\r
-          index++;\r
-        }\r
-        while (index < hiddenColumns.size());\r
-\r
-        result -= gaps;\r
-      }\r
-\r
-      return result;\r
-    }\r
-\r
-    /**\r
-     * Use this method to determine where the next hiddenRegion starts\r
-    */\r
-    public int findHiddenRegionPosition(int hiddenRegion)\r
-    {\r
-      int result = 0;\r
-      if (hiddenColumns != null)\r
-      {\r
-        int index = 0;\r
-        int gaps = 0;\r
-        do\r
-        {\r
-          int[] region = (int[]) hiddenColumns.elementAt(index);\r
-          if(hiddenRegion==0)\r
-          {\r
-            return region[0];\r
-          }\r
-\r
-            gaps +=  region[1] +1 - region[0];\r
-            result = region[1] +1;\r
-            index++;\r
-        }\r
-        while(index < hiddenRegion+1);\r
-\r
-        result -= gaps;\r
-      }\r
-\r
-      return result;\r
-    }\r
-\r
-    /**\r
-     * THis method returns the rightmost limit of a\r
-     * region of an alignment with hidden columns.\r
-     * In otherwords, the next hidden column.\r
-     * @param index int\r
-     */\r
-    public int getHiddenRegionBoundary(int alPos)\r
-    {\r
-      if (hiddenColumns != null)\r
-      {\r
-        int index = 0;\r
-        do\r
-        {\r
-          int[] region = (int[]) hiddenColumns.elementAt(index);\r
-          if(alPos < region[0])\r
-            return region[0];\r
-\r
-          index++;\r
-        }\r
-        while(index < hiddenColumns.size());\r
-      }\r
-\r
-      return alPos;\r
-\r
-    }\r
-\r
-\r
-    public void hideColumns(int res, AlignViewport av)\r
-    {\r
-      if(hiddenColumns==null)\r
-        hiddenColumns = new Vector();\r
-\r
-      // First find out range of columns to hide\r
-      int min = res, max = res+1;\r
-      while( contains(min) )\r
-      {  removeElement(min); min --;  }\r
-\r
-      while( contains(max) )\r
-      { removeElement(max);  max ++;  }\r
-\r
-      min++; max--;\r
-\r
-      boolean added = false;\r
-      for(int i=0; i<hiddenColumns.size(); i++)\r
-      {\r
-        int [] region = (int[])hiddenColumns.elementAt(i);\r
-        if( max < region[0])\r
-        {\r
-          hiddenColumns.insertElementAt(new int[]{min, max}, i);\r
-          added = true;\r
-          break;\r
-        }\r
-      }\r
-\r
-      if(!added)\r
-        hiddenColumns.addElement(new int[]{min, max});\r
-\r
-\r
-      av.setSelectionGroup(null);\r
-      av.hasHiddenColumns = true;\r
-    }\r
-\r
-    public void revealAllHiddenColumns(AlignViewport av)\r
-    {\r
-      av.hasHiddenColumns = false;\r
-      hiddenColumns = null;\r
-    }\r
-\r
-    public void revealHiddenColumns(int res, AlignViewport av)\r
-    {\r
-      for(int i=0; i<hiddenColumns.size(); i++)\r
-      {\r
-        int [] region = (int[])hiddenColumns.elementAt(i);\r
-        if( res == region[0])\r
-        {\r
-          hiddenColumns.remove(region);\r
-          break;\r
-        }\r
-      }\r
-\r
-\r
-      if(hiddenColumns.size()<1)\r
-        av.hasHiddenColumns = false;\r
-    }\r
-\r
-    public boolean isVisible(int column)\r
-    {\r
-      for(int i=0; i<hiddenColumns.size(); i++)\r
-      {\r
-        int [] region = (int[])hiddenColumns.elementAt(i);\r
-        if( column >= region[0] && column <= region[1])\r
-        {\r
-          return false;\r
-        }\r
-      }\r
-      return true;\r
-    }\r
-\r
-}\r
index 12f9e28..aca666a 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.io.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.*;\r
-import java.awt.datatransfer.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class CutAndPasteTransfer extends GCutAndPasteTransfer\r
-{\r
-\r
-  public CutAndPasteTransfer()\r
-  {\r
-    SwingUtilities.invokeLater(new Runnable()\r
-    {\r
-      public void run()\r
-      {\r
-        textarea.requestFocus();\r
-      }\r
-    });\r
-\r
-  }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void setForInput()\r
-    {\r
-        getContentPane().add(inputButtonPanel, java.awt.BorderLayout.SOUTH);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getText()\r
-    {\r
-        return textarea.getText();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param text DOCUMENT ME!\r
-     */\r
-    public void setText(String text)\r
-    {\r
-        textarea.setText(text);\r
-    }\r
-\r
-    public void appendText(String text)\r
-    {\r
-      textarea.append(text);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void copyItem_actionPerformed(ActionEvent e)\r
-    {\r
-        textarea.getSelectedText();\r
-        Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
-        c.setContents(new StringSelection(textarea.getSelectedText()), null);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void pasteMenu_actionPerformed(ActionEvent e)\r
-    {\r
-        Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
-        Transferable contents = c.getContents(this);\r
-\r
-        if (contents == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        try\r
-        {\r
-            textarea.append((String) contents.getTransferData(\r
-                    DataFlavor.stringFlavor));\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void ok_actionPerformed(ActionEvent e)\r
-    {\r
-        String format = new IdentifyFile().Identify(getText(), "Paste");\r
-        SequenceI[] sequences = null;\r
-\r
-        if (FormatAdapter.formats.contains(format))\r
-        {\r
-          try{\r
-            sequences = new FormatAdapter().readFile(getText(), "Paste", format);\r
-          }catch(java.io.IOException ex)\r
-          {\r
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                                  "Couldn't read the pasted text.\n" +ex.toString(),\r
-                                                  "Error parsing text",\r
-                                                  JOptionPane.WARNING_MESSAGE);\r
-          }\r
-        }\r
-\r
-        if (sequences != null)\r
-        {\r
-            AlignFrame af = new AlignFrame(new Alignment(sequences));\r
-            af.currentFileFormat = format;\r
-            Desktop.addInternalFrame(af, "Cut & Paste input - " + format,\r
-                AlignFrame.NEW_WINDOW_WIDTH, AlignFrame.NEW_WINDOW_HEIGHT);\r
-            af.statusBar.setText("Successfully pasted alignment file");\r
-\r
-            try\r
-            {\r
-                af.setMaximum( jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-            }\r
-\r
-            try\r
-            {\r
-                this.setClosed(true);\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-        try\r
-        {\r
-            this.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    public void textarea_mousePressed(MouseEvent e)\r
-    {\r
-      if(SwingUtilities.isRightMouseButton(e))\r
-      {\r
-        JPopupMenu popup = new JPopupMenu("Edit");\r
-        JMenuItem item = new JMenuItem("Copy");\r
-        item.addActionListener(new ActionListener()\r
-            {public void actionPerformed(ActionEvent e)\r
-                  {\r
-                    copyItem_actionPerformed(e);\r
-                  }\r
-            });\r
-        popup.add(item);\r
-        item = new JMenuItem("Paste");\r
-        item.addActionListener(new ActionListener()\r
-            {public void actionPerformed(ActionEvent e)\r
-                  {\r
-                    pasteMenu_actionPerformed(e);\r
-                  }\r
-            });\r
-        popup.add(item);\r
-        popup.show(this, e.getX(), e.getY()+textarea.getY()+30);\r
-\r
-      }\r
-    }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.io.*;
+
+import jalview.jbgui.*;
+
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class CutAndPasteTransfer extends GCutAndPasteTransfer
+{
+
+  AlignViewport viewport;
+
+  public CutAndPasteTransfer()
+  {
+    SwingUtilities.invokeLater(new Runnable()
+    {
+      public void run()
+      {
+        textarea.requestFocus();
+      }
+    });
+
+  }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void setForInput(AlignViewport viewport)
+    {
+      this.viewport = viewport;
+      getContentPane().add(inputButtonPanel, java.awt.BorderLayout.SOUTH);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getText()
+    {
+        return textarea.getText();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param text DOCUMENT ME!
+     */
+    public void setText(String text)
+    {
+        textarea.setText(text);
+    }
+
+    public void appendText(String text)
+    {
+      textarea.append(text);
+    }
+
+
+    public void save_actionPerformed(ActionEvent e)
+    {
+      JalviewFileChooser chooser = new JalviewFileChooser(
+          jalview.bin.Cache.getProperty(
+              "LAST_DIRECTORY"));
+
+      chooser.setAcceptAllFileFilterUsed(false);
+      chooser.setFileView(new JalviewFileView());
+      chooser.setDialogTitle("Save Text to File");
+      chooser.setToolTipText("Save");
+
+      int value = chooser.showSaveDialog(this);
+
+      if (value == JalviewFileChooser.APPROVE_OPTION)
+      {
+        try
+        {
+          java.io.PrintWriter out = new java.io.PrintWriter(
+              new java.io.FileWriter(chooser.getSelectedFile()));
+
+          out.print(getText());
+          out.close();
+        }
+        catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+
+      }
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void copyItem_actionPerformed(ActionEvent e)
+    {
+        textarea.getSelectedText();
+        Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
+        c.setContents(new StringSelection(textarea.getSelectedText()), null);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void pasteMenu_actionPerformed(ActionEvent e)
+    {
+        Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
+        Transferable contents = c.getContents(this);
+
+        if (contents == null)
+        {
+            return;
+        }
+
+        try
+        {
+            textarea.append((String) contents.getTransferData(
+                    DataFlavor.stringFlavor));
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void ok_actionPerformed(ActionEvent e)
+    {
+        String format = new IdentifyFile().Identify(getText(), "Paste");
+        SequenceI[] sequences = null;
+
+        if (FormatAdapter.isValidFormat(format))
+        {
+          try{
+            sequences = new FormatAdapter().readFile(getText(), "Paste", format);
+          }catch(java.io.IOException ex)
+          {
+            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                                  "Couldn't read the pasted text.\n" +ex.toString(),
+                                                  "Error parsing text",
+                                                  JOptionPane.WARNING_MESSAGE);
+          }
+        }
+
+        if (sequences != null)
+        {
+          if(viewport!=null)
+          {
+            for(int i=0; i<sequences.length; i++)
+              viewport.getAlignment().addSequence(sequences[i]);
+
+            viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+          }
+          else
+          {
+            AlignFrame af = new AlignFrame(new Alignment(sequences));
+            af.currentFileFormat = format;
+            Desktop.addInternalFrame(af, "Cut & Paste input - " + format,
+                                     AlignFrame.NEW_WINDOW_WIDTH,
+                                     AlignFrame.NEW_WINDOW_HEIGHT);
+            af.statusBar.setText("Successfully pasted alignment file");
+
+            try
+            {
+              af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));
+            }
+            catch (Exception ex)
+            {
+            }
+          }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void cancel_actionPerformed(ActionEvent e)
+    {
+        try
+        {
+            this.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    public void textarea_mousePressed(MouseEvent e)
+    {
+      if(SwingUtilities.isRightMouseButton(e))
+      {
+        JPopupMenu popup = new JPopupMenu("Edit");
+        JMenuItem item = new JMenuItem("Copy");
+        item.addActionListener(new ActionListener()
+            {public void actionPerformed(ActionEvent e)
+                  {
+                    copyItem_actionPerformed(e);
+                  }
+            });
+        popup.add(item);
+        item = new JMenuItem("Paste");
+        item.addActionListener(new ActionListener()
+            {public void actionPerformed(ActionEvent e)
+                  {
+                    pasteMenu_actionPerformed(e);
+                  }
+            });
+        popup.add(item);
+        popup.show(this, e.getX()+10, e.getY()+textarea.getY()+40);
+
+      }
+    }
+
+}
index 31ebe44..eb480a1 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.io.*;\r
-\r
-import java.awt.*;\r
-import java.awt.datatransfer.*;\r
-import java.awt.dnd.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-import org.vamsas.test.simpleclient.ArchiveClient;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Desktop extends jalview.jbgui.GDesktop\r
-    implements DropTargetListener\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public static JDesktopPane desktop;\r
-    static int openFrameCount = 0;\r
-    static final int xOffset = 30;\r
-    static final int yOffset = 30;\r
-    public static jalview.ws.Discoverer discoverer;\r
-\r
-    public static Object [] jalviewClipboard;\r
-\r
-\r
-    /**\r
-     * Creates a new Desktop object.\r
-     */\r
-    public Desktop()\r
-    {\r
-        Image image = null;\r
-\r
-\r
-        try\r
-        {\r
-            java.net.URL url = getClass().getResource("/images/logo.gif");\r
-\r
-            if (url != null)\r
-            {\r
-                image = java.awt.Toolkit.getDefaultToolkit().createImage(url);\r
-\r
-                MediaTracker mt = new MediaTracker(this);\r
-                mt.addImage(image, 0);\r
-                mt.waitForID(0);\r
-                setIconImage(image);\r
-            }\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-\r
-        setTitle("Jalview "+jalview.bin.Cache.getProperty("VERSION"));\r
-        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r
-        desktop = new JDesktopPane();\r
-        desktop.setBackground(Color.white);\r
-        setContentPane(desktop);\r
-        desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);\r
-\r
-        // This line prevents Windows Look&Feel resizing all new windows to maximum\r
-        // if previous window was maximised\r
-        desktop.setDesktopManager(new DefaultDesktopManager());\r
-\r
-        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();\r
-        String x = jalview.bin.Cache.getProperty("SCREEN_X");\r
-        String y = jalview.bin.Cache.getProperty("SCREEN_Y");\r
-        String width = jalview.bin.Cache.getProperty("SCREEN_WIDTH");\r
-        String height = jalview.bin.Cache.getProperty("SCREEN_HEIGHT");\r
-\r
-        if ((x != null) && (y != null) && (width != null) && (height != null))\r
-        {\r
-            setBounds(Integer.parseInt(x), Integer.parseInt(y),\r
-                Integer.parseInt(width), Integer.parseInt(height));\r
-        }\r
-        else\r
-        {\r
-            setBounds((int) (screenSize.width - 900) / 2,\r
-                (int) (screenSize.height - 650) / 2, 900, 650);\r
-        }\r
-\r
-        this.addWindowListener(new WindowAdapter()\r
-            {\r
-                public void windowClosing(WindowEvent evt)\r
-                {\r
-                    quit();\r
-                }\r
-            });\r
-\r
-        this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));\r
-\r
-        /////////Add a splashscreen on startup\r
-        /////////Add a splashscreen on startup\r
-        JInternalFrame frame = new JInternalFrame();\r
-\r
-        SplashScreen splash = new SplashScreen(frame, image);\r
-        frame.setContentPane(splash);\r
-        frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
-        frame.setLocation((int) ((getWidth() - 750) / 2),\r
-            (int) ((getHeight() - 160) / 2));\r
-\r
-        addInternalFrame(frame, "", 750, 160, false);\r
-\r
-        discoverer=new jalview.ws.Discoverer(); // Only gets started if gui is displayed.\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param frame DOCUMENT ME!\r
-     * @param title DOCUMENT ME!\r
-     * @param w DOCUMENT ME!\r
-     * @param h DOCUMENT ME!\r
-     */\r
-    public static synchronized void addInternalFrame(final JInternalFrame frame,\r
-        String title, int w, int h)\r
-    {\r
-        addInternalFrame(frame, title, w, h, true);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param frame DOCUMENT ME!\r
-     * @param title DOCUMENT ME!\r
-     * @param w DOCUMENT ME!\r
-     * @param h DOCUMENT ME!\r
-     * @param resizable DOCUMENT ME!\r
-     */\r
-    public static synchronized void addInternalFrame(final JInternalFrame frame,\r
-        String title, int w, int h, boolean resizable)\r
-    {\r
-\r
-      frame.setTitle(title);\r
-      if(frame.getWidth()<1 || frame.getHeight()<1)\r
-      {\r
-        frame.setSize(w, h);\r
-      }\r
-      // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN\r
-      // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN\r
-      // IF JALVIEW IS RUNNING HEADLESS\r
-      /////////////////////////////////////////////////\r
-      if (System.getProperty("java.awt.headless") != null\r
-          && System.getProperty("java.awt.headless").equals("true"))\r
-      {\r
-        return;\r
-      }\r
-\r
-\r
-        openFrameCount++;\r
-\r
-        frame.setVisible(true);\r
-        frame.setClosable(true);\r
-        frame.setResizable(resizable);\r
-        frame.setMaximizable(resizable);\r
-        frame.setIconifiable(resizable);\r
-        frame.setFrameIcon(null);\r
-\r
-        if (frame.getX()<1 && frame.getY()<1)\r
-       {\r
-         frame.setLocation(xOffset * openFrameCount, yOffset * ((openFrameCount-1)%10)+yOffset);\r
-       }\r
-\r
-        final JMenuItem menuItem = new JMenuItem(title);\r
-        frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
-            {\r
-              public void internalFrameActivated(javax.swing.event.\r
-                                                 InternalFrameEvent evt)\r
-              {\r
-                JInternalFrame itf = desktop.getSelectedFrame();\r
-                if (itf != null)\r
-                  itf.requestFocus();\r
-\r
-              }\r
-\r
-                public void internalFrameClosed(\r
-                    javax.swing.event.InternalFrameEvent evt)\r
-                {\r
-                    openFrameCount--;\r
-                    windowMenu.remove(menuItem);\r
-                    JInternalFrame itf = desktop.getSelectedFrame();\r
-                       if (itf != null)\r
-                        itf.requestFocus();\r
-                }\r
-                ;\r
-            });\r
-\r
-        menuItem.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    try\r
-                    {\r
-                        frame.setSelected(true);\r
-                        frame.setIcon(false);\r
-                    }\r
-                    catch (java.beans.PropertyVetoException ex)\r
-                    {\r
-\r
-                    }\r
-                }\r
-            });\r
-\r
-        windowMenu.add(menuItem);\r
-\r
-        desktop.add(frame);\r
-        frame.toFront();\r
-        try{\r
-          frame.setSelected(true);\r
-          frame.requestFocus();\r
-        }catch(java.beans.PropertyVetoException ve)\r
-        {}\r
-    }\r
-\r
-    public void dragEnter(DropTargetDragEvent evt)\r
-    {}\r
-\r
-    public void dragExit(DropTargetEvent evt)\r
-    {}\r
-\r
-    public void dragOver(DropTargetDragEvent evt)\r
-    {}\r
-\r
-    public void dropActionChanged(DropTargetDragEvent evt)\r
-    {}\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void drop(DropTargetDropEvent evt)\r
-    {\r
-        Transferable t = evt.getTransferable();\r
-        java.util.List files = null;\r
-\r
-        try\r
-        {\r
-          DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");\r
-          if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))\r
-          {\r
-            //Works on Windows and MacOSX\r
-            evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
-            files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);\r
-          }\r
-          else if (t.isDataFlavorSupported(uriListFlavor))\r
-          {\r
-            // This is used by Unix drag system\r
-            evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
-            String data = (String) t.getTransferData(uriListFlavor);\r
-            files = new java.util.ArrayList(1);\r
-            for (java.util.StringTokenizer st = new java.util.StringTokenizer(\r
-                data,\r
-                "\r\n");\r
-                 st.hasMoreTokens(); )\r
-            {\r
-              String s = st.nextToken();\r
-              if (s.startsWith("#"))\r
-              {\r
-                // the line is a comment (as per the RFC 2483)\r
-                continue;\r
-              }\r
-\r
-              java.net.URI uri = new java.net.URI(s);\r
-              java.io.File file = new java.io.File(uri);\r
-              files.add(file);\r
-            }\r
-          }\r
-        }\r
-        catch (Exception e)\r
-        {\r
-          e.printStackTrace();\r
-        }\r
-\r
-        if (files != null)\r
-        {\r
-          try\r
-          {\r
-            for (int i = 0; i < files.size(); i++)\r
-            {\r
-              String file = files.get(i).toString();\r
-              String protocol = FormatAdapter.FILE;\r
-              String format = null;\r
-\r
-              if (file.endsWith(".jar"))\r
-              {\r
-                format = "Jalview";\r
-\r
-              }\r
-              else\r
-              {\r
-                format = new IdentifyFile().Identify(file,\r
-                                                          protocol);\r
-              }\r
-              LoadFile(file, protocol, format);\r
-            }\r
-          }\r
-          catch (Exception ex)\r
-          {\r
-            ex.printStackTrace();\r
-          }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void inputLocalFileMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"),\r
-                new String[]\r
-                {\r
-                    "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
-                    "jar"\r
-                },\r
-                new String[]\r
-                {\r
-                    "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
-                }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));\r
-\r
-        chooser.setFileView(new JalviewFileView());\r
-        chooser.setDialogTitle("Open local file");\r
-        chooser.setToolTipText("Open");\r
-\r
-        int value = chooser.showOpenDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            String choice = chooser.getSelectedFile().getPath();\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                chooser.getSelectedFile().getParent());\r
-\r
-            String format = null;\r
-            if (chooser.getSelectedFormat().equals("Jalview"))\r
-            {\r
-              format = "Jalview";\r
-            }\r
-            else\r
-            {\r
-                format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);\r
-            }\r
-\r
-            jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT", format);\r
-            LoadFile(choice, FormatAdapter.FILE, format);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param file DOCUMENT ME!\r
-     * @param protocol DOCUMENT ME!\r
-     * @param format DOCUMENT ME!\r
-     */\r
-    public void LoadFile(String file, String protocol, String format)\r
-    {\r
-      FileLoader fileLoader = new FileLoader();\r
-      fileLoader.LoadFile(file, protocol, format);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void inputURLMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-      // This construct allows us to have a wider textfield\r
-      // for viewing\r
-      JLabel label = new JLabel("Enter URL of Input File");\r
-      JTextField textinput = new JTextField("http://www.", 40);\r
-      JPanel panel = new JPanel(new BorderLayout());\r
-      panel.add(label, BorderLayout.NORTH);\r
-      panel.add(textinput, BorderLayout.SOUTH);\r
-\r
-\r
-       int reply = JOptionPane.showInternalConfirmDialog(desktop,\r
-          panel, "Input Alignment From URL",\r
-          JOptionPane.OK_CANCEL_OPTION );\r
-\r
-\r
-        if (reply != JOptionPane.OK_OPTION )\r
-        {\r
-            return;\r
-        }\r
-\r
-        String url = textinput.getText();\r
-\r
-        if (url.toLowerCase().endsWith(".jar"))\r
-        {\r
-               jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT", "Jalview");\r
-               Jalview2XML.LoadJalviewAlign(url);\r
-        }\r
-        else\r
-        {\r
-\r
-          String format = new IdentifyFile().Identify(url, FormatAdapter.URL);\r
-\r
-          if (format.equals("URL NOT FOUND"))\r
-          {\r
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                                  "Couldn't locate " + url,\r
-                                                  "URL not found",\r
-                                                  JOptionPane.WARNING_MESSAGE);\r
-\r
-            return;\r
-          }\r
-\r
-          LoadFile(url, FormatAdapter.URL, format);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void inputTextboxMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
-        cap.setForInput();\r
-        Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);\r
-    }\r
-\r
-    /*\r
-     * Exit the program\r
-     */\r
-    public void quit()\r
-    {\r
-        jalview.bin.Cache.setProperty("SCREEN_X", getBounds().x + "");\r
-        jalview.bin.Cache.setProperty("SCREEN_Y", getBounds().y + "");\r
-        jalview.bin.Cache.setProperty("SCREEN_WIDTH", getWidth() + "");\r
-        jalview.bin.Cache.setProperty("SCREEN_HEIGHT", getHeight() + "");\r
-        System.exit(0);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void aboutMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-      StringBuffer message = new StringBuffer("JalView version " +\r
-                                              jalview.bin.Cache.getProperty(\r
-          "VERSION") +\r
-                                              "; last updated: " +\r
-                                              jalview.bin.\r
-                                              Cache.getDefault("BUILD_DATE", "unknown"));\r
-\r
-      if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(\r
-          jalview.bin.Cache.getProperty("VERSION")))\r
-      {\r
-        message.append("\n\n!! Jalview version "\r
-                       + jalview.bin.Cache.getProperty("LATEST_VERSION")\r
-                       + " is available for download from http://www.jalview.org !!\n");\r
-\r
-      }\r
-\r
-      message.append( "\nAuthors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton." +\r
-            "\nCurrent development managed by Andrew Waterhouse; Barton Group, University of Dundee." +\r
-            "\nFor all issues relating to Jalview, email help@jalview.org" +\r
-            "\n\nIf  you use JalView, please cite:" +\r
-            "\n\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"" +\r
-            "\nBioinformatics,  2004 12;426-7.");\r
-\r
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-\r
-           message.toString(), "About Jalview",\r
-            JOptionPane.INFORMATION_MESSAGE);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void documentationMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        try\r
-        {\r
-            ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();\r
-            java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");\r
-            javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);\r
-\r
-            javax.help.HelpBroker hb = hs.createHelpBroker();\r
-            hb.setCurrentID("home");\r
-            hb.setDisplayed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void preferences_actionPerformed(ActionEvent e)\r
-    {\r
-        new Preferences();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void saveState_actionPerformed(ActionEvent e)\r
-    {\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"), new String[] { "jar" },\r
-                new String[] { "Jalview Project" }, "Jalview Project");\r
-\r
-        chooser.setFileView(new JalviewFileView());\r
-        chooser.setDialogTitle("Save State");\r
-\r
-        int value = chooser.showSaveDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            java.io.File choice = chooser.getSelectedFile();\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());\r
-            Jalview2XML.SaveState(choice);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void loadState_actionPerformed(ActionEvent e)\r
-    {\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"), new String[] { "jar" },\r
-                new String[] { "Jalview Project" }, "Jalview Project");\r
-        chooser.setFileView(new JalviewFileView());\r
-        chooser.setDialogTitle("Restore state");\r
-\r
-        int value = chooser.showOpenDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            String choice = chooser.getSelectedFile().getAbsolutePath();\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                chooser.getSelectedFile().getParent());\r
-            Jalview2XML.LoadJalviewAlign(choice);\r
-        }\r
-    }\r
-    jalview.gui.VamsasClient v_client=null;\r
-    public void vamsasLoad_actionPerformed(ActionEvent e)\r
-    {\r
-      if (v_client==null) {\r
-        // Start a session.\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
-            getProperty("LAST_DIRECTORY"));\r
-\r
-        chooser.setFileView(new JalviewFileView());\r
-        chooser.setDialogTitle("Load Vamsas file");\r
-        chooser.setToolTipText("Import");\r
-\r
-        int value = chooser.showOpenDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-          v_client = new jalview.gui.VamsasClient(this,\r
-              chooser.getSelectedFile());\r
-          this.vamsasLoad.setText("Session Update");\r
-          this.vamsasStop.setVisible(true);\r
-          v_client.initial_update();\r
-        }\r
-      } else {\r
-        // store current data in session.\r
-         v_client.push_update();\r
-      }\r
-    }\r
-    public void vamsasStop_actionPerformed(ActionEvent e) {\r
-       if (v_client!=null) {\r
-               v_client.end_session();\r
-               v_client=null;\r
-               this.vamsasStop.setVisible(false);\r
-               this.vamsasLoad.setText("Start Vamsas Session...");\r
-       }\r
-    }\r
-    \r
-    public void inputSequence_actionPerformed(ActionEvent e)\r
-    {\r
-      SequenceFetcher sf = new SequenceFetcher(null);\r
-    }\r
-\r
-}\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.io.*;
+
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.dnd.*;
+import java.awt.event.*;
+import java.util.*;
+
+import javax.swing.*;
+
+import org.vamsas.test.simpleclient.ArchiveClient;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Desktop extends jalview.jbgui.GDesktop
+    implements DropTargetListener, ClipboardOwner
+{
+    /** DOCUMENT ME!! */
+    public static Desktop instance;
+    public static JDesktopPane desktop;
+    static int openFrameCount = 0;
+    static final int xOffset = 30;
+    static final int yOffset = 30;
+    public static jalview.ws.Discoverer discoverer;
+
+    public static Object [] jalviewClipboard;
+
+    static int fileLoadingCount= 0;
+
+    /**
+     * Creates a new Desktop object.
+     */
+    public Desktop()
+    {
+        instance = this;
+
+        Image image = null;
+
+        try
+        {
+            java.net.URL url = getClass().getResource("/images/logo.gif");
+
+            if (url != null)
+            {
+                image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
+
+                MediaTracker mt = new MediaTracker(this);
+                mt.addImage(image, 0);
+                mt.waitForID(0);
+                setIconImage(image);
+            }
+        }
+        catch (Exception ex)
+        {
+        }
+
+        setTitle("Jalview "+jalview.bin.Cache.getProperty("VERSION"));
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        desktop = new JDesktopPane();
+        desktop.setBackground(Color.white);
+        getContentPane().setLayout(new BorderLayout());
+        getContentPane().add(desktop, BorderLayout.CENTER);
+        desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+
+        // This line prevents Windows Look&Feel resizing all new windows to maximum
+        // if previous window was maximised
+        desktop.setDesktopManager(new DefaultDesktopManager());
+
+        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+        String x = jalview.bin.Cache.getProperty("SCREEN_X");
+        String y = jalview.bin.Cache.getProperty("SCREEN_Y");
+        String width = jalview.bin.Cache.getProperty("SCREEN_WIDTH");
+        String height = jalview.bin.Cache.getProperty("SCREEN_HEIGHT");
+
+        if ((x != null) && (y != null) && (width != null) && (height != null))
+        {
+            setBounds(Integer.parseInt(x), Integer.parseInt(y),
+                Integer.parseInt(width), Integer.parseInt(height));
+        }
+        else
+        {
+            setBounds((int) (screenSize.width - 900) / 2,
+                (int) (screenSize.height - 650) / 2, 900, 650);
+        }
+
+        this.addWindowListener(new WindowAdapter()
+            {
+                public void windowClosing(WindowEvent evt)
+                {
+                    quit();
+                }
+            });
+
+        this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
+
+        /////////Add a splashscreen on startup
+        /////////Add a splashscreen on startup
+        JInternalFrame frame = new JInternalFrame();
+
+        SplashScreen splash = new SplashScreen(frame, image);
+        frame.setContentPane(splash);
+        frame.setLayer(JLayeredPane.PALETTE_LAYER);
+        frame.setLocation((int) ((getWidth() - 750) / 2),
+            (int) ((getHeight() - 160) / 2));
+
+        addInternalFrame(frame, "", 750, 160, false);
+
+        discoverer=new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param frame DOCUMENT ME!
+     * @param title DOCUMENT ME!
+     * @param w DOCUMENT ME!
+     * @param h DOCUMENT ME!
+     */
+    public static synchronized void addInternalFrame(final JInternalFrame frame,
+        String title, int w, int h)
+    {
+        addInternalFrame(frame, title, w, h, true);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param frame DOCUMENT ME!
+     * @param title DOCUMENT ME!
+     * @param w DOCUMENT ME!
+     * @param h DOCUMENT ME!
+     * @param resizable DOCUMENT ME!
+     */
+    public static synchronized void addInternalFrame(final JInternalFrame frame,
+        String title, int w, int h, boolean resizable)
+    {
+
+      frame.setTitle(title);
+      if(frame.getWidth()<1 || frame.getHeight()<1)
+      {
+        frame.setSize(w, h);
+      }
+      // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
+      // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
+      // IF JALVIEW IS RUNNING HEADLESS
+      /////////////////////////////////////////////////
+      if (System.getProperty("java.awt.headless") != null
+          && System.getProperty("java.awt.headless").equals("true"))
+      {
+        return;
+      }
+
+
+        openFrameCount++;
+
+        frame.setVisible(true);
+        frame.setClosable(true);
+        frame.setResizable(resizable);
+        frame.setMaximizable(resizable);
+        frame.setIconifiable(resizable);
+        frame.setFrameIcon(null);
+
+        if (frame.getX()<1 && frame.getY()<1)
+       {
+         frame.setLocation(xOffset * openFrameCount, yOffset * ((openFrameCount-1)%10)+yOffset);
+       }
+
+        final JMenuItem menuItem = new JMenuItem(title);
+        frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+            {
+              public void internalFrameActivated(javax.swing.event.
+                                                 InternalFrameEvent evt)
+              {
+                JInternalFrame itf = desktop.getSelectedFrame();
+                if (itf != null)
+                  itf.requestFocus();
+
+              }
+
+                public void internalFrameClosed(
+                    javax.swing.event.InternalFrameEvent evt)
+                {
+                    openFrameCount--;
+                    windowMenu.remove(menuItem);
+                    JInternalFrame itf = desktop.getSelectedFrame();
+                       if (itf != null)
+                        itf.requestFocus();
+                }
+                ;
+            });
+
+        menuItem.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    try
+                    {
+                        frame.setSelected(true);
+                        frame.setIcon(false);
+                    }
+                    catch (java.beans.PropertyVetoException ex)
+                    {
+
+                    }
+                }
+            });
+
+        windowMenu.add(menuItem);
+
+        desktop.add(frame);
+        frame.toFront();
+        try{
+          frame.setSelected(true);
+          frame.requestFocus();
+        }catch(java.beans.PropertyVetoException ve)
+        {}
+    }
+
+    public void lostOwnership(Clipboard clipboard, Transferable contents)
+    {
+      Desktop.jalviewClipboard = null;
+    }
+
+    public void dragEnter(DropTargetDragEvent evt)
+    {}
+
+    public void dragExit(DropTargetEvent evt)
+    {}
+
+    public void dragOver(DropTargetDragEvent evt)
+    {}
+
+    public void dropActionChanged(DropTargetDragEvent evt)
+    {}
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void drop(DropTargetDropEvent evt)
+    {
+        Transferable t = evt.getTransferable();
+        java.util.List files = null;
+
+        try
+        {
+          DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
+          if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+          {
+            //Works on Windows and MacOSX
+            evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+            files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);
+          }
+          else if (t.isDataFlavorSupported(uriListFlavor))
+          {
+            // This is used by Unix drag system
+            evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+            String data = (String) t.getTransferData(uriListFlavor);
+            files = new java.util.ArrayList(1);
+            for (java.util.StringTokenizer st = new java.util.StringTokenizer(
+                data,
+                "\r\n");
+                 st.hasMoreTokens(); )
+            {
+              String s = st.nextToken();
+              if (s.startsWith("#"))
+              {
+                // the line is a comment (as per the RFC 2483)
+                continue;
+              }
+
+              java.net.URI uri = new java.net.URI(s);
+              java.io.File file = new java.io.File(uri);
+              files.add(file);
+            }
+          }
+        }
+        catch (Exception e)
+        {
+          e.printStackTrace();
+        }
+
+        if (files != null)
+        {
+          try
+          {
+            for (int i = 0; i < files.size(); i++)
+            {
+              String file = files.get(i).toString();
+              String protocol = FormatAdapter.FILE;
+              String format = null;
+
+              if (file.endsWith(".jar"))
+              {
+                format = "Jalview";
+
+              }
+              else
+              {
+                format = new IdentifyFile().Identify(file,
+                                                          protocol);
+              }
+
+
+              new FileLoader().LoadFile(file, protocol, format);
+
+            }
+          }
+          catch (Exception ex)
+          {
+            ex.printStackTrace();
+          }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
+    {
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"),
+                new String[]
+                {
+                    "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
+                    "jar"
+                },
+                new String[]
+                {
+                    "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
+                }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
+
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Open local file");
+        chooser.setToolTipText("Open");
+
+        int value = chooser.showOpenDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            String choice = chooser.getSelectedFile().getPath();
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                chooser.getSelectedFile().getParent());
+
+            String format = null;
+            if (chooser.getSelectedFormat().equals("Jalview"))
+            {
+                format = "Jalview";
+            }
+            else
+            {
+                format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
+            }
+
+            if (viewport != null)
+              new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE, format);
+            else
+              new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
+        }
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
+    {
+      // This construct allows us to have a wider textfield
+      // for viewing
+      JLabel label = new JLabel("Enter URL of Input File");
+      final JComboBox history = new JComboBox();
+
+      JPanel panel = new JPanel(new GridLayout(2,1));
+      panel.add(label);
+      panel.add(history);
+      history.setPreferredSize(new Dimension(400,20));
+      history.setEditable(true);
+      history.addItem("http://www.");
+
+      String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
+
+      StringTokenizer st;
+
+      if (historyItems != null)
+      {
+        st = new StringTokenizer(historyItems, "\t");
+
+        while (st.hasMoreTokens())
+        {
+          history.addItem(st.nextElement());
+        }
+      }
+
+       int reply = JOptionPane.showInternalConfirmDialog(desktop,
+          panel, "Input Alignment From URL",
+          JOptionPane.OK_CANCEL_OPTION );
+
+
+        if (reply != JOptionPane.OK_OPTION )
+        {
+            return;
+        }
+
+        String url = history.getSelectedItem().toString();
+
+        if (url.toLowerCase().endsWith(".jar"))
+        {
+          if (viewport != null)
+            new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, "Jalview");
+          else
+            new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
+        }
+        else
+        {
+          String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
+
+          if (format.equals("URL NOT FOUND"))
+          {
+            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                                  "Couldn't locate " + url,
+                                                  "URL not found",
+                                                  JOptionPane.WARNING_MESSAGE);
+
+            return;
+          }
+
+          if (viewport != null)
+            new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
+          else
+            new FileLoader().LoadFile(url, FormatAdapter.URL, format);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
+    {
+        CutAndPasteTransfer cap = new CutAndPasteTransfer();
+        cap.setForInput(viewport);
+        Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
+    }
+
+    /*
+     * Exit the program
+     */
+    public void quit()
+    {
+        jalview.bin.Cache.setProperty("SCREEN_X", getBounds().x + "");
+        jalview.bin.Cache.setProperty("SCREEN_Y", getBounds().y + "");
+        jalview.bin.Cache.setProperty("SCREEN_WIDTH", getWidth() + "");
+        jalview.bin.Cache.setProperty("SCREEN_HEIGHT", getHeight() + "");
+        System.exit(0);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void aboutMenuItem_actionPerformed(ActionEvent e)
+    {
+      StringBuffer message = new StringBuffer("JalView version " +
+                                              jalview.bin.Cache.getProperty(
+          "VERSION") +
+                                              "; last updated: " +
+                                              jalview.bin.
+                                              Cache.getDefault("BUILD_DATE", "unknown"));
+
+      if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
+          jalview.bin.Cache.getProperty("VERSION")))
+      {
+        message.append("\n\n!! Jalview version "
+                       + jalview.bin.Cache.getProperty("LATEST_VERSION")
+                       + " is available for download from http://www.jalview.org !!\n");
+
+      }
+
+      message.append( "\nAuthors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton." +
+            "\nCurrent development managed by Andrew Waterhouse; Barton Group, University of Dundee." +
+            "\nFor all issues relating to Jalview, email help@jalview.org" +
+            "\n\nIf  you use JalView, please cite:" +
+            "\n\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"" +
+            "\nBioinformatics,  2004 20;426-7.");
+
+        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+
+           message.toString(), "About Jalview",
+            JOptionPane.INFORMATION_MESSAGE);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void documentationMenuItem_actionPerformed(ActionEvent e)
+    {
+        try
+        {
+            ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
+            java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
+            javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
+
+            javax.help.HelpBroker hb = hs.createHelpBroker();
+            hb.setCurrentID("home");
+            hb.setDisplayed(true);
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void preferences_actionPerformed(ActionEvent e)
+    {
+        new Preferences();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void saveState_actionPerformed(ActionEvent e)
+    {
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"), new String[] { "jar" },
+                new String[] { "Jalview Project" }, "Jalview Project");
+
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Save State");
+
+        int value = chooser.showSaveDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            java.io.File choice = chooser.getSelectedFile();
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+            new Jalview2XML().SaveState(choice);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void loadState_actionPerformed(ActionEvent e)
+    {
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"), new String[] { "jar" },
+                new String[] { "Jalview Project" }, "Jalview Project");
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Restore state");
+
+        int value = chooser.showOpenDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            String choice = chooser.getSelectedFile().getAbsolutePath();
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                chooser.getSelectedFile().getParent());
+            new Jalview2XML().LoadJalviewAlign(choice);
+        }
+    }
+
+  /*  public void vamsasLoad_actionPerformed(ActionEvent e)
+    {
+      JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+          getProperty("LAST_DIRECTORY"));
+
+      chooser.setFileView(new JalviewFileView());
+      chooser.setDialogTitle("Load Vamsas file");
+      chooser.setToolTipText("Import");
+
+      int value = chooser.showOpenDialog(this);
+
+      if (value == JalviewFileChooser.APPROVE_OPTION)
+      {
+        jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(null);
+        vs.load(
+            chooser.getSelectedFile().getAbsolutePath()
+            );
+      }
+
+    }*/
+
+
+    public void inputSequence_actionPerformed(ActionEvent e)
+    {
+      new SequenceFetcher(null);
+    }
+
+    JPanel progressPanel;
+
+    public void startLoading(final String fileName)
+    {
+      if (fileLoadingCount == 0)
+      {
+        progressPanel = new JPanel(new BorderLayout());
+        JProgressBar progressBar = new JProgressBar();
+        progressBar.setIndeterminate(true);
+
+        progressPanel.add(new JLabel("Loading File: " + fileName + "   "),
+                          BorderLayout.WEST);
+
+        progressPanel.add(progressBar, BorderLayout.CENTER);
+
+        instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
+      }
+      fileLoadingCount++;
+      validate();
+    }
+
+    public void stopLoading()
+    {
+      fileLoadingCount--;
+      if (fileLoadingCount < 1)
+      {
+        if(progressPanel!=null)
+        {
+          this.getContentPane().remove(progressPanel);
+          progressPanel = null;
+        }
+        fileLoadingCount = 0;
+      }
+      validate();
+    }
+    jalview.gui.VamsasClient v_client=null;
+    public void vamsasLoad_actionPerformed(ActionEvent e)
+    {
+      if (v_client==null) {
+        // Start a session.
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+            getProperty("LAST_DIRECTORY"));
+
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Load Vamsas file");
+        chooser.setToolTipText("Import");
+
+        int value = chooser.showOpenDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+          v_client = new jalview.gui.VamsasClient(this,
+              chooser.getSelectedFile());
+          this.vamsasLoad.setText("Session Update");
+          this.vamsasStop.setVisible(true);
+          v_client.initial_update();
+        }
+      } else {
+        // store current data in session.
+         v_client.push_update();
+      }
+    }
+    public void vamsasStop_actionPerformed(ActionEvent e) {
+       if (v_client!=null) {
+               v_client.end_session();
+               v_client=null;
+               this.vamsasStop.setVisible(false);
+               this.vamsasLoad.setText("Start Vamsas Session...");
+       }
+    }
+}
+
index a9a60f2..afe0cdb 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import javax.swing.*;\r
-import java.awt.*;\r
-import java.awt.event.ActionListener;\r
-import java.awt.event.ActionEvent;\r
-\r
-public class EPSOptions\r
-    extends JPanel\r
-{\r
-  JDialog dialog;\r
-  public boolean cancelled = false;\r
-  String value;\r
-\r
-  public EPSOptions()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    ButtonGroup bg = new ButtonGroup();\r
-    bg.add(lineart);\r
-    bg.add(text);\r
-\r
-    JOptionPane pane = new JOptionPane(null,\r
-        JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION,\r
-       null, new Object[]{this});\r
-\r
-    dialog = pane.createDialog(Desktop.desktop, "EPS Rendering options");\r
-    dialog.setVisible(true);\r
-\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    lineart.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    lineart.setSelected(true);\r
-    lineart.setText("Lineart");\r
-    text.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    text.setText("Text");\r
-    askAgain.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    askAgain.setText("Don\'t ask me again");\r
-    ok.setText("OK");\r
-    ok.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        ok_actionPerformed(e);\r
-      }\r
-    });\r
-    cancel.setText("Cancel");\r
-    cancel.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        cancel_actionPerformed(e);\r
-      }\r
-    });\r
-    jLabel1.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    jLabel1.setText("Select EPS character rendering style");\r
-    this.setLayout(borderLayout1);\r
-    jPanel3.setBorder(BorderFactory.createEtchedBorder());\r
-    jPanel2.add(lineart);\r
-    jPanel2.add(text);\r
-    jPanel2.add(askAgain);\r
-    jPanel1.add(ok);\r
-    jPanel1.add(cancel);\r
-    jPanel3.add(jLabel1);\r
-    jPanel3.add(jPanel2);\r
-    this.add(jPanel3, java.awt.BorderLayout.CENTER);\r
-    this.add(jPanel1, java.awt.BorderLayout.SOUTH);\r
-  }\r
-\r
-  JRadioButton lineart = new JRadioButton();\r
-  JRadioButton text = new JRadioButton();\r
-  JCheckBox askAgain = new JCheckBox();\r
-  JButton ok = new JButton();\r
-  JButton cancel = new JButton();\r
-  JPanel jPanel1 = new JPanel();\r
-  JLabel jLabel1 = new JLabel();\r
-  JPanel jPanel2 = new JPanel();\r
-  JPanel jPanel3 = new JPanel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-\r
-  public void ok_actionPerformed(ActionEvent e)\r
-  {\r
-    if (lineart.isSelected())\r
-      value = "Lineart";\r
-    else\r
-      value = "Text";\r
-\r
-    if (!askAgain.isSelected())\r
-    {\r
-      jalview.bin.Cache.applicationProperties.remove("EPS_RENDERING");\r
-    }\r
-    else\r
-    {\r
-      jalview.bin.Cache.setProperty("EPS_RENDERING", value);\r
-    }\r
-\r
-    dialog.setVisible(false);\r
-  }\r
-\r
-  public void cancel_actionPerformed(ActionEvent e)\r
-  {\r
-    cancelled = true;\r
-    dialog.setVisible(false);\r
-  }\r
-\r
-  public String getValue()\r
-  {\r
-    return value;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+public class EPSOptions
+    extends JPanel
+{
+  JDialog dialog;
+  public boolean cancelled = false;
+  String value;
+
+  public EPSOptions()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    ButtonGroup bg = new ButtonGroup();
+    bg.add(lineart);
+    bg.add(text);
+
+    JOptionPane pane = new JOptionPane(null,
+        JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION,
+       null, new Object[]{this});
+
+    dialog = pane.createDialog(Desktop.desktop, "EPS Rendering options");
+    dialog.setVisible(true);
+
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    lineart.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    lineart.setSelected(true);
+    lineart.setText("Lineart");
+    text.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    text.setText("Text");
+    askAgain.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    askAgain.setText("Don\'t ask me again");
+    ok.setText("OK");
+    ok.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+    cancel.setText("Cancel");
+    cancel.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        cancel_actionPerformed(e);
+      }
+    });
+    jLabel1.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    jLabel1.setText("Select EPS character rendering style");
+    this.setLayout(borderLayout1);
+    jPanel3.setBorder(BorderFactory.createEtchedBorder());
+    jPanel2.add(lineart);
+    jPanel2.add(text);
+    jPanel2.add(askAgain);
+    jPanel1.add(ok);
+    jPanel1.add(cancel);
+    jPanel3.add(jLabel1);
+    jPanel3.add(jPanel2);
+    this.add(jPanel3, java.awt.BorderLayout.CENTER);
+    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+  }
+
+  JRadioButton lineart = new JRadioButton();
+  JRadioButton text = new JRadioButton();
+  JCheckBox askAgain = new JCheckBox();
+  JButton ok = new JButton();
+  JButton cancel = new JButton();
+  JPanel jPanel1 = new JPanel();
+  JLabel jLabel1 = new JLabel();
+  JPanel jPanel2 = new JPanel();
+  JPanel jPanel3 = new JPanel();
+  BorderLayout borderLayout1 = new BorderLayout();
+
+  public void ok_actionPerformed(ActionEvent e)
+  {
+    if (lineart.isSelected())
+      value = "Lineart";
+    else
+      value = "Text";
+
+    if (!askAgain.isSelected())
+    {
+      jalview.bin.Cache.applicationProperties.remove("EPS_RENDERING");
+    }
+    else
+    {
+      jalview.bin.Cache.setProperty("EPS_RENDERING", value);
+    }
+
+    dialog.setVisible(false);
+  }
+
+  public void cancel_actionPerformed(ActionEvent e)
+  {
+    cancelled = true;
+    dialog.setVisible(false);
+  }
+
+  public String getValue()
+  {
+    return value;
+  }
+}
index 6fbdee8..a2d6bde 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.image.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class FeatureRenderer\r
-{\r
-    AlignViewport av;\r
-    Color resBoxColour;\r
-    float transparency = 1.0f;\r
-    FontMetrics fm;\r
-    int charOffset;\r
-\r
-    // A higher level for grouping features of a\r
-   // particular type\r
-    Hashtable featureGroups = null;\r
-\r
-\r
-    // This is actually an Integer held in the hashtable,\r
-    // Retrieved using the key feature type\r
-    Object currentColour;\r
-\r
-    String [] renderOrder;\r
-\r
-\r
-    /**\r
-     * Creates a new FeatureRenderer object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     */\r
-    public FeatureRenderer(AlignViewport av)\r
-    {\r
-        this.av = av;\r
-        initColours();\r
-    }\r
-\r
-    public void transferSettings(FeatureRenderer fr)\r
-    {\r
-      renderOrder = fr.renderOrder;\r
-      featureGroups = fr.featureGroups;\r
-      featureColours = fr.featureColours;\r
-      transparency =  fr.transparency;\r
-    }\r
-\r
-    BufferedImage offscreenImage;\r
-    boolean offscreenRender = false;\r
-    public Color findFeatureColour(Color initialCol, SequenceI seq, int res)\r
-    {\r
-      int seqindex = av.alignment.findIndex(seq);\r
-\r
-      return new Color( findFeatureColour (initialCol.getRGB(),\r
-                        seqindex, res ));\r
-    }\r
-\r
-    /**\r
-     * This is used by the Molecule Viewer to get the accurate colour\r
-     * of the rendered sequence\r
-     */\r
-    public int findFeatureColour(int initialCol, int seqIndex, int column)\r
-    {\r
-      if(!av.showSequenceFeatures)\r
-        return initialCol;\r
-\r
-      if(seqIndex!=lastSequenceIndex)\r
-      {\r
-        lastSequence = av.alignment.getSequenceAt(seqIndex);\r
-        lastSequenceIndex = seqIndex;\r
-        sequenceFeatures = lastSequence.getDatasetSequence().getSequenceFeatures();\r
-        if(sequenceFeatures==null)\r
-          return initialCol;\r
-\r
-        sfSize = sequenceFeatures.length;\r
-      }\r
-\r
-      if(jalview.util.Comparison.isGap(lastSequence.getCharAt(column)))\r
-        return Color.white.getRGB();\r
-\r
-\r
-      //Only bother making an offscreen image if transparency is applied\r
-      if(transparency!=1.0f && offscreenImage==null)\r
-      {\r
-        offscreenImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);\r
-      }\r
-\r
-      currentColour = null;\r
-\r
-      offscreenRender = true;\r
-\r
-      if(offscreenImage!=null)\r
-      {\r
-        offscreenImage.setRGB(0,0,initialCol);\r
-        drawSequence(offscreenImage.getGraphics(),\r
-                     lastSequence,\r
-                     column,column,0);\r
-\r
-        return offscreenImage.getRGB(0,0);\r
-      }\r
-      else\r
-      {\r
-        drawSequence(null,\r
-                    lastSequence,\r
-                    lastSequence.findPosition(column),\r
-                    -1, -1);\r
-\r
-        if (currentColour == null)\r
-          return initialCol;\r
-        else\r
-          return  ((Integer)currentColour).intValue();\r
-      }\r
-\r
-\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     * @param sg DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-   // String type;\r
-   // SequenceFeature sf;\r
-    int lastSequenceIndex=-1;\r
-    SequenceI lastSequence;\r
-    SequenceFeature [] sequenceFeatures;\r
-    int sfSize, sfindex, spos, epos;\r
-\r
-    public void drawSequence(Graphics g, SequenceI seq,\r
-                             int start, int end, int y1)\r
-    {\r
-      if ( seq.getDatasetSequence().getSequenceFeatures() == null\r
-          || seq.getDatasetSequence().getSequenceFeatures().length==0)\r
-        return;\r
-\r
-\r
-      if(g!=null)\r
-        fm = g.getFontMetrics();\r
-\r
-\r
-      if (av.featuresDisplayed == null || renderOrder==null)\r
-       {\r
-         findAllFeatures();\r
-         if(av.featuresDisplayed.size()<1)\r
-           return;\r
-\r
-         sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();\r
-         sfSize = sequenceFeatures.length;\r
-       }\r
-\r
-       if(lastSequence==null || seq!=lastSequence)\r
-      {\r
-        lastSequence = seq;\r
-        sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();\r
-        sfSize = sequenceFeatures.length;\r
-      }\r
-\r
-\r
-      if (transparency != 1 && g!=null)\r
-      {\r
-        Graphics2D g2 = (Graphics2D) g;\r
-        g2.setComposite(\r
-            AlphaComposite.getInstance(\r
-                AlphaComposite.SRC_OVER, transparency));\r
-      }\r
-\r
-      if(!offscreenRender)\r
-      {\r
-        spos = lastSequence.findPosition(start);\r
-        epos = lastSequence.findPosition(end);\r
-      }\r
-\r
-\r
-      String type;\r
-      for(int renderIndex=0; renderIndex<renderOrder.length; renderIndex++)\r
-       {\r
-        type =  renderOrder[renderIndex];\r
-        if(!av.featuresDisplayed.containsKey(type))\r
-          continue;\r
-\r
-        // loop through all features in sequence to find\r
-        // current feature to render\r
-        for (sfindex = 0; sfindex < sfSize; sfindex++)\r
-        {\r
-          if(sequenceFeatures.length<=sfindex)\r
-          {\r
-            continue;\r
-          }\r
-          if (!sequenceFeatures[sfindex].type.equals(type))\r
-            continue;\r
-\r
-          if (featureGroups != null\r
-              && sequenceFeatures[sfindex].featureGroup != null\r
-              &&\r
-              featureGroups.containsKey(sequenceFeatures[sfindex].featureGroup)\r
-              &&\r
-              ! ( (Boolean) featureGroups.get(sequenceFeatures[sfindex].featureGroup)).\r
-              booleanValue())\r
-          {\r
-            continue;\r
-          }\r
-\r
-          if (!offscreenRender && (sequenceFeatures[sfindex].getBegin() > epos\r
-                            || sequenceFeatures[sfindex].getEnd() < spos))\r
-            continue;\r
-\r
-          if (offscreenRender && offscreenImage==null)\r
-          {\r
-            if (sequenceFeatures[sfindex].begin <= start &&\r
-                sequenceFeatures[sfindex].end  >= start)\r
-            {\r
-              currentColour = av.featuresDisplayed.get(sequenceFeatures[sfindex].\r
-                 type);\r
-            }\r
-          }\r
-          else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))\r
-          {\r
-\r
-            renderFeature(g, seq,\r
-                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
-                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
-                          new Color( ( (Integer) av.featuresDisplayed.get(\r
-                sequenceFeatures[sfindex].type)).intValue()),\r
-                          start, end, y1);\r
-            renderFeature(g, seq,\r
-                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
-                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
-                          new Color( ( (Integer) av.featuresDisplayed.get(\r
-                sequenceFeatures[sfindex].type)).intValue()),\r
-                          start, end, y1);\r
-\r
-          }\r
-          else\r
-            renderFeature(g, seq,\r
-                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
-                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
-                          getColour(sequenceFeatures[sfindex].type),\r
-                          start, end, y1);\r
-\r
-\r
-        }\r
-\r
-      }\r
-\r
-        if(transparency!=1.0f && g!=null)\r
-        {\r
-          Graphics2D g2 = (Graphics2D) g;\r
-          g2.setComposite(\r
-              AlphaComposite.getInstance(\r
-                  AlphaComposite.SRC_OVER, 1.0f));\r
-        }\r
-    }\r
-\r
-\r
-    char s;\r
-    int i;\r
-    void renderFeature(Graphics g, SequenceI seq,\r
-                       int fstart, int fend, Color featureColour, int start, int end,  int y1)\r
-    {\r
-\r
-      if (((fstart <= end) && (fend >= start)))\r
-      {\r
-        if (fstart < start)\r
-        { // fix for if the feature we have starts before the sequence start,\r
-          fstart = start; // but the feature end is still valid!!\r
-        }\r
-\r
-        if (fend >= end)\r
-        {\r
-          fend = end;\r
-        }\r
-          int pady = (y1 + av.charHeight) - av.charHeight / 5;\r
-          for (i = fstart; i <= fend; i++)\r
-          {\r
-            s = seq.getSequence().charAt(i);\r
-\r
-            if (jalview.util.Comparison.isGap(s))\r
-            {\r
-              continue;\r
-            }\r
-\r
-            g.setColor(featureColour);\r
-\r
-            g.fillRect( (i - start) * av.charWidth, y1, av.charWidth,av.charHeight);\r
-\r
-            if(offscreenRender)\r
-              continue;\r
-\r
-            g.setColor(Color.white);\r
-            charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
-            g.drawString(String.valueOf(s),\r
-                         charOffset + (av.charWidth * (i - start)),\r
-                         pady);\r
-\r
-          }\r
-      }\r
-    }\r
-\r
-    void findAllFeatures()\r
-    {\r
-      av.featuresDisplayed = new Hashtable();\r
-      Vector allfeatures = new Vector();\r
-      for (int i = 0; i < av.alignment.getHeight(); i++)\r
-      {\r
-        SequenceFeature [] features\r
-            = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
-\r
-        if (features == null)\r
-          continue;\r
-\r
-        int index = 0;\r
-        while (index < features.length)\r
-        {\r
-          if (!av.featuresDisplayed.containsKey(features[index].getType()))\r
-          {\r
-            av.featuresDisplayed.put(features[index].getType(),\r
-                                  new Integer( getColour(features[index].getType()).getRGB()) );\r
-            allfeatures.addElement(features[index].getType());\r
-          }\r
-          index++;\r
-        }\r
-      }\r
-\r
-      renderOrder = new String[allfeatures.size()];\r
-      Enumeration en = allfeatures.elements();\r
-      int i = allfeatures.size()-1;\r
-      while(en.hasMoreElements())\r
-      {\r
-        renderOrder[i] = en.nextElement().toString();\r
-        i--;\r
-      }\r
-    }\r
-\r
-    public Color getColour(String featureType)\r
-    {\r
-      return (Color)featureColours.get(featureType);\r
-    }\r
-\r
-    public void addNewFeature(String name, Color col, String group)\r
-    {\r
-\r
-      setColour(name, col);\r
-      if(av.featuresDisplayed==null)\r
-        av.featuresDisplayed = new Hashtable();\r
-\r
-      if(group == null)\r
-        group = "NOGROUP";\r
-\r
-      av.featuresDisplayed.put(name, new Integer(col.getRGB()));\r
-    }\r
-\r
-    public void setColour(String featureType, Color col)\r
-    {\r
-      featureColours.put(featureType, col);\r
-    }\r
-\r
-    public void setTransparency(float value)\r
-    {\r
-      transparency = value;\r
-    }\r
-\r
-    public float getTransparency()\r
-    {\r
-      return transparency;\r
-    }\r
-\r
-    public void setFeaturePriority(Object [][] data)\r
-    {\r
-      // The feature table will display high priority\r
-      // features at the top, but theses are the ones\r
-      // we need to render last, so invert the data\r
-      if(av.featuresDisplayed!=null)\r
-        av.featuresDisplayed.clear();\r
-      else\r
-        av.featuresDisplayed = new Hashtable();\r
-\r
-      renderOrder = new String[data.length];\r
-\r
-      if (data.length > 0)\r
-        for (int i = 0; i < data.length; i++)\r
-        {\r
-          String type = data[i][0].toString();\r
-          setColour(type, (Color) data[i][1]);\r
-          if ( ( (Boolean) data[i][2]).booleanValue())\r
-          {\r
-            av.featuresDisplayed.put(type, new Integer(getColour(type).getRGB()));\r
-          }\r
-\r
-          renderOrder[data.length - i - 1] = type;\r
-        }\r
-\r
-    }\r
-\r
-    Hashtable featureColours = new Hashtable();\r
-    void initColours()\r
-    {\r
-      featureColours.put("active site", new Color(255, 75, 0));\r
-      featureColours.put("binding site", new Color(245, 85, 0));\r
-      featureColours.put("calcium-binding region", new Color(235, 95, 0));\r
-      featureColours.put("chain", new Color(225, 105, 0));\r
-      featureColours.put("coiled-coil region", new Color(215, 115, 0));\r
-      featureColours.put("compositionally biased region", new Color(205, 125, 0));\r
-      featureColours.put("cross-link", new Color(195, 135, 0));\r
-      featureColours.put("disulfide bond", new Color(230,230,0));\r
-      featureColours.put("DNA-binding region", new Color(175, 155, 0));\r
-      featureColours.put("domain", new Color(165, 165, 0));\r
-      featureColours.put("glycosylation site", new Color(155, 175, 0));\r
-      featureColours.put("helix", new Color(145, 185, 0));\r
-      featureColours.put("initiator methionine", new Color(135, 195, 5));\r
-      featureColours.put("lipid moiety-binding region", new Color(125, 205, 15));\r
-      featureColours.put("metal ion-binding site", new Color(115, 215, 25));\r
-      featureColours.put("modified residue", new Color(105, 225, 35));\r
-      featureColours.put("mutagenesis site", new Color(95, 235, 45));\r
-      featureColours.put("non-consecutive residues", new Color(85, 245, 55));\r
-      featureColours.put("non-terminal residue", new Color(75, 255, 65));\r
-      featureColours.put("nucleotide phosphate-binding region",new Color(65, 245, 75));\r
-      featureColours.put("peptide", new Color(55, 235, 85));\r
-      featureColours.put("propeptide", new Color(45, 225, 95));\r
-      featureColours.put("region of interest", new Color(35, 215, 105));\r
-      featureColours.put("repeat", new Color(25, 205, 115));\r
-      featureColours.put("selenocysteine", new Color(15, 195, 125));\r
-      featureColours.put("sequence conflict", new Color(5, 185, 135));\r
-      featureColours.put("sequence variant", new Color(0, 175, 145));\r
-      featureColours.put("short sequence motif", new Color(0, 165, 155));\r
-      featureColours.put("signal peptide", new Color(0, 155, 165));\r
-      featureColours.put("site", new Color(0, 145, 175));\r
-      featureColours.put("splice variant", new Color(0, 135, 185));\r
-      featureColours.put("strand", new Color(0, 125, 195));\r
-      featureColours.put("topological domain", new Color(0, 115, 205));\r
-      featureColours.put("transit peptide", new Color(0, 105, 215));\r
-      featureColours.put("transmembrane region", new Color(0, 95, 225));\r
-      featureColours.put("turn", new Color(0, 85, 235));\r
-      featureColours.put("unsure residue", new Color(0, 75, 245));\r
-      featureColours.put("zinc finger region", new Color(0, 65, 255));\r
-    }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+import java.awt.image.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class FeatureRenderer
+{
+    AlignViewport av;
+    Color resBoxColour;
+    float transparency = 1.0f;
+    FontMetrics fm;
+    int charOffset;
+
+    Hashtable featureColours = new Hashtable();
+
+
+    // A higher level for grouping features of a
+   // particular type
+    Hashtable featureGroups = null;
+
+    // This is actually an Integer held in the hashtable,
+    // Retrieved using the key feature type
+    Object currentColour;
+
+    String [] renderOrder;
+
+    /**
+     * Creates a new FeatureRenderer object.
+     *
+     * @param av DOCUMENT ME!
+     */
+    public FeatureRenderer(AlignViewport av)
+    {
+        this.av = av;
+    }
+
+    public void transferSettings(FeatureRenderer fr)
+    {
+      renderOrder = fr.renderOrder;
+      featureGroups = fr.featureGroups;
+      featureColours = fr.featureColours;
+      transparency =  fr.transparency;
+    }
+
+    BufferedImage offscreenImage;
+    boolean offscreenRender = false;
+    public Color findFeatureColour(Color initialCol, SequenceI seq, int res)
+    {
+      return new Color( findFeatureColour (initialCol.getRGB(),
+                        seq, res ));
+    }
+
+    /**
+     * This is used by the Molecule Viewer and Overview to
+     * get the accurate colourof the rendered sequence
+     */
+    public int findFeatureColour(int initialCol, SequenceI seq, int column)
+    {
+      if(!av.showSequenceFeatures)
+        return initialCol;
+
+      if(seq!=lastSeq)
+      {
+        lastSeq = seq;
+        sequenceFeatures = lastSeq.getDatasetSequence().getSequenceFeatures();
+        if(sequenceFeatures==null)
+          return initialCol;
+
+        sfSize = sequenceFeatures.length;
+      }
+
+      if(jalview.util.Comparison.isGap(lastSeq.getCharAt(column)))
+        return Color.white.getRGB();
+
+
+      //Only bother making an offscreen image if transparency is applied
+      if(transparency!=1.0f && offscreenImage==null)
+      {
+        offscreenImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);
+      }
+
+      currentColour = null;
+
+      offscreenRender = true;
+
+      if(offscreenImage!=null)
+      {
+        offscreenImage.setRGB(0,0,initialCol);
+        drawSequence(offscreenImage.getGraphics(),
+                     lastSeq,
+                     column,column,0);
+
+        return offscreenImage.getRGB(0,0);
+      }
+      else
+      {
+        drawSequence(null,
+                    lastSeq,
+                    lastSeq.findPosition(column),
+                    -1, -1);
+
+        if (currentColour == null)
+          return initialCol;
+        else
+          return  ((Integer)currentColour).intValue();
+      }
+
+
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     * @param sg DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+   // String type;
+   // SequenceFeature sf;
+    SequenceI lastSeq;
+    SequenceFeature [] sequenceFeatures;
+    int sfSize, sfindex, spos, epos;
+
+    public void drawSequence(Graphics g, SequenceI seq,
+                             int start, int end, int y1)
+    {
+      if ( seq.getDatasetSequence().getSequenceFeatures() == null
+          || seq.getDatasetSequence().getSequenceFeatures().length==0)
+        return;
+
+      if(g!=null)
+        fm = g.getFontMetrics();
+
+
+      if (av.featuresDisplayed == null
+          || renderOrder==null
+          || newFeatureAdded)
+       {
+         findAllFeatures();
+         if(av.featuresDisplayed.size()<1)
+           return;
+
+         sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();
+         sfSize = sequenceFeatures.length;
+       }
+
+       if(lastSeq==null || seq!=lastSeq)
+      {
+        lastSeq = seq;
+        sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();
+        sfSize = sequenceFeatures.length;
+      }
+
+
+      if (transparency != 1 && g!=null)
+      {
+        Graphics2D g2 = (Graphics2D) g;
+        g2.setComposite(
+            AlphaComposite.getInstance(
+                AlphaComposite.SRC_OVER, transparency));
+      }
+
+      if(!offscreenRender)
+      {
+        spos = lastSeq.findPosition(start);
+        epos = lastSeq.findPosition(end);
+      }
+
+
+      String type;
+      for(int renderIndex=0; renderIndex<renderOrder.length; renderIndex++)
+       {
+        type =  renderOrder[renderIndex];
+
+        if(!av.featuresDisplayed.containsKey(type))
+          continue;
+
+        // loop through all features in sequence to find
+        // current feature to render
+        for (sfindex = 0; sfindex < sfSize; sfindex++)
+        {
+          if(sequenceFeatures.length<=sfindex)
+          {
+            continue;
+          }
+          if (!sequenceFeatures[sfindex].type.equals(type))
+            continue;
+
+          if (featureGroups != null
+              && sequenceFeatures[sfindex].featureGroup != null
+              &&
+              featureGroups.containsKey(sequenceFeatures[sfindex].featureGroup)
+              &&
+              ! ( (Boolean) featureGroups.get(sequenceFeatures[sfindex].featureGroup)).
+              booleanValue())
+          {
+            continue;
+          }
+
+          if (!offscreenRender && (sequenceFeatures[sfindex].getBegin() > epos
+                            || sequenceFeatures[sfindex].getEnd() < spos))
+            continue;
+
+          if (offscreenRender && offscreenImage==null)
+          {
+            if (sequenceFeatures[sfindex].begin <= start &&
+                sequenceFeatures[sfindex].end  >= start)
+            {
+              currentColour = av.featuresDisplayed.get(sequenceFeatures[sfindex].
+                 type);
+            }
+          }
+          else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
+          {
+
+            renderFeature(g, seq,
+                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                          new Color( ( (Integer) av.featuresDisplayed.get(
+                sequenceFeatures[sfindex].type)).intValue()),
+                          start, end, y1);
+            renderFeature(g, seq,
+                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                          new Color( ( (Integer) av.featuresDisplayed.get(
+                sequenceFeatures[sfindex].type)).intValue()),
+                          start, end, y1);
+
+          }
+          else
+            renderFeature(g, seq,
+                          seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                          seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                          getColour(sequenceFeatures[sfindex].type),
+                          start, end, y1);
+
+
+        }
+
+      }
+
+        if(transparency!=1.0f && g!=null)
+        {
+          Graphics2D g2 = (Graphics2D) g;
+          g2.setComposite(
+              AlphaComposite.getInstance(
+                  AlphaComposite.SRC_OVER, 1.0f));
+        }
+    }
+
+
+    char s;
+    int i;
+    void renderFeature(Graphics g, SequenceI seq,
+                       int fstart, int fend, Color featureColour, int start, int end,  int y1)
+    {
+
+      if (((fstart <= end) && (fend >= start)))
+      {
+        if (fstart < start)
+        { // fix for if the feature we have starts before the sequence start,
+          fstart = start; // but the feature end is still valid!!
+        }
+
+        if (fend >= end)
+        {
+          fend = end;
+        }
+          int pady = (y1 + av.charHeight) - av.charHeight / 5;
+          for (i = fstart; i <= fend; i++)
+          {
+            s = seq.getSequence().charAt(i);
+
+            if (jalview.util.Comparison.isGap(s))
+            {
+              continue;
+            }
+
+            g.setColor(featureColour);
+
+            g.fillRect( (i - start) * av.charWidth, y1, av.charWidth,av.charHeight);
+
+            if(offscreenRender || !av.validCharWidth)
+              continue;
+
+            g.setColor(Color.white);
+            charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+            g.drawString(String.valueOf(s),
+                         charOffset + (av.charWidth * (i - start)),
+                         pady);
+
+          }
+      }
+    }
+
+
+    boolean newFeatureAdded = false;
+
+    public void featuresAdded()
+    {
+      findAllFeatures();
+    }
+
+   boolean findingFeatures = false;
+   synchronized void findAllFeatures()
+   {
+      newFeatureAdded = false;
+
+      if(findingFeatures)
+      {
+        newFeatureAdded = true;
+        return;
+      }
+
+      findingFeatures = true;
+      jalview.schemes.UserColourScheme ucs = new
+          jalview.schemes.UserColourScheme();
+
+      if(av.featuresDisplayed==null)
+        av.featuresDisplayed = new Hashtable();
+
+      av.featuresDisplayed.clear();
+
+      Vector allfeatures = new Vector();
+      for (int i = 0; i < av.alignment.getHeight(); i++)
+      {
+        SequenceFeature [] features
+            = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();
+
+        if (features == null)
+          continue;
+
+        int index = 0;
+        while (index < features.length)
+        {
+          if (!av.featuresDisplayed.containsKey(features[index].getType()))
+          {
+            if(!(features[index].begin == 0 && features[index].end ==0))
+            {
+              // If beginning and end are 0, the feature is for the whole sequence
+              // and we don't want to render the feature in the normal way
+
+              if (getColour(features[index].getType()) == null)
+              {
+                 featureColours.put(features[index].getType(),
+                                   ucs.createColourFromName(features[index].
+                    getType()));
+              }
+
+              av.featuresDisplayed.put(features[index].getType(),
+                                       new Integer(getColour(features[index].
+                  getType()).getRGB()));
+              allfeatures.addElement(features[index].getType());
+            }
+          }
+          index++;
+        }
+      }
+
+      renderOrder = new String[allfeatures.size()];
+      Enumeration en = allfeatures.elements();
+      int i = allfeatures.size()-1;
+      while(en.hasMoreElements())
+      {
+        renderOrder[i] = en.nextElement().toString();
+        i--;
+      }
+
+      findingFeatures = false;
+    }
+
+    public Color getColour(String featureType)
+    {
+      Color colour = (Color)featureColours.get(featureType);
+      return colour;
+    }
+
+
+    public void addNewFeature(String name, Color col, String group)
+    {
+
+      setColour(name, col);
+      if(av.featuresDisplayed==null)
+        av.featuresDisplayed = new Hashtable();
+
+      if(group == null)
+        group = "NOGROUP";
+
+      av.featuresDisplayed.put(name, new Integer(col.getRGB()));
+    }
+
+    public void setColour(String featureType, Color col)
+    {
+      featureColours.put(featureType, col);
+    }
+
+    public void setTransparency(float value)
+    {
+      transparency = value;
+    }
+
+    public float getTransparency()
+    {
+      return transparency;
+    }
+
+    public void setFeaturePriority(Object [][] data)
+    {
+      // The feature table will display high priority
+      // features at the top, but theses are the ones
+      // we need to render last, so invert the data
+      if(av.featuresDisplayed!=null)
+        av.featuresDisplayed.clear();
+      else
+        av.featuresDisplayed = new Hashtable();
+
+      renderOrder = new String[data.length];
+
+      if (data.length > 0)
+        for (int i = 0; i < data.length; i++)
+        {
+          String type = data[i][0].toString();
+          setColour(type, (Color) data[i][1]);
+          if ( ( (Boolean) data[i][2]).booleanValue())
+          {
+            av.featuresDisplayed.put(type, new Integer(getColour(type).getRGB()));
+          }
+
+          renderOrder[data.length - i - 1] = type;
+        }
+
+    }
+
+
+
+
+}
index f14ec51..ffa01d5 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-import javax.swing.*;\r
-import javax.swing.event.*;\r
-import java.awt.*;\r
-import java.util.*;\r
-import javax.swing.BorderFactory;\r
-import java.awt.event.*;\r
-import javax.swing.table.*;\r
-import java.io.*;\r
-import jalview.io.JalviewFileChooser;\r
-\r
-public class FeatureSettings extends JPanel\r
-{\r
-\r
-  final FeatureRenderer fr;\r
-  final AlignmentPanel ap;\r
-  final AlignViewport av;\r
-  Object [][] originalData;\r
-  final JInternalFrame frame;\r
-  JScrollPane scrollPane = new JScrollPane();\r
-  JTable table;\r
-  JPanel groupPanel;\r
-\r
-  boolean alignmentHasFeatures = false;\r
-\r
-  public FeatureSettings(AlignViewport av, final AlignmentPanel ap)\r
-  {\r
-    this.ap = ap;\r
-    this.av = av;\r
-    fr = ap.seqPanel.seqCanvas.getFeatureRenderer();\r
-    av.alignment.getSequences();\r
-    frame = new JInternalFrame();\r
-    frame.setContentPane(this);\r
-    Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 300);\r
-\r
-    setTableData();\r
-\r
-    final JSlider transparency = new JSlider(0, 70, 0);\r
-    transparency.addChangeListener(new ChangeListener()\r
-    {\r
-      public void stateChanged(ChangeEvent evt)\r
-      {\r
-        fr.setTransparency( (float) (100 - transparency.getValue()) / 100f);\r
-        ap.repaint();\r
-      }\r
-    });\r
-\r
-    JPanel transPanel = new JPanel(new FlowLayout());\r
-    transPanel.add(new JLabel("Transparency"));\r
-    transPanel.add(transparency);\r
-\r
-    //////////////////////////////////////////////\r
-    //We're going to need those OK cancel buttons\r
-    JPanel buttonPanel = new JPanel(new FlowLayout());\r
-    JButton button = new JButton("OK");\r
-    button.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent evt)\r
-      {\r
-        try\r
-        {\r
-          frame.setClosed(true);\r
-        }\r
-        catch (Exception exe)\r
-        {}\r
-      }\r
-    });\r
-    buttonPanel.add(button);\r
-    button = new JButton("Cancel");\r
-    button.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent evt)\r
-      {\r
-        try\r
-        {\r
-          updateFeatureRenderer(originalData);\r
-          frame.setClosed(true);\r
-        }\r
-        catch (Exception exe)\r
-        {}\r
-      }\r
-    });\r
-    buttonPanel.add(button);\r
-\r
-    button = new JButton("Load Colours");\r
-    button.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent evt)\r
-      {\r
-        load();\r
-      }\r
-    });\r
-    buttonPanel.add(button);\r
-    button = new JButton("Save Colours");\r
-    button.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent evt)\r
-      {\r
-        save();\r
-      }\r
-    });\r
-    buttonPanel.add(button);\r
-\r
-    this.setLayout(new BorderLayout());\r
-    JPanel bigPanel = new JPanel(new BorderLayout());\r
-    bigPanel.add(transPanel, BorderLayout.SOUTH);\r
-    bigPanel.add(scrollPane, BorderLayout.CENTER);\r
-    if(groupPanel!=null)\r
-    {\r
-      groupPanel.setLayout(\r
-          new GridLayout(fr.featureGroups.size() / 4 + 1, 4));\r
-\r
-      groupPanel.validate();\r
-      bigPanel.add(groupPanel, BorderLayout.NORTH);\r
-    }\r
-    add(bigPanel, BorderLayout.CENTER);\r
-    add(buttonPanel, BorderLayout.SOUTH);\r
-\r
-\r
-  }\r
-\r
-  void setTableData()\r
-  {\r
-    alignmentHasFeatures = false;\r
-\r
-    if (fr.featureGroups == null)\r
-      fr.featureGroups = new Hashtable();\r
-\r
-    Vector allFeatures = new Vector();\r
-    Vector allGroups = new Vector();\r
-    SequenceFeature[] tmpfeatures;\r
-    String group;\r
-\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
-    {\r
-      if (av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures() == null)\r
-        continue;\r
-\r
-      alignmentHasFeatures = true;\r
-\r
-      tmpfeatures = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
-      int index = 0;\r
-      while (index < tmpfeatures.length)\r
-      {\r
-        if(tmpfeatures[index].getFeatureGroup()!=null)\r
-        {\r
-          group = tmpfeatures[index].featureGroup;\r
-          if(!allGroups.contains(group))\r
-           {\r
-             allGroups.addElement(group);\r
-\r
-             boolean visible = true;\r
-             if (fr.featureGroups.containsKey(group))\r
-             {\r
-               visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();\r
-             }\r
-\r
-             fr.featureGroups.put(group, new Boolean(visible));\r
-\r
-             if (groupPanel == null)\r
-             {\r
-               groupPanel = new JPanel();\r
-             }\r
-\r
-             final JCheckBox check = new JCheckBox(group, visible);\r
-             check.setFont(new Font("Serif", Font.BOLD, 12));\r
-             check.addItemListener(new ItemListener()\r
-             {\r
-               public void itemStateChanged(ItemEvent evt)\r
-               {\r
-                 fr.featureGroups.put(check.getText(),\r
-                                      new Boolean(check.isSelected()));\r
-                 ap.seqPanel.seqCanvas.repaint();\r
-                 if (ap.overviewPanel != null)\r
-                   ap.overviewPanel.updateOverviewImage();\r
-\r
-                 resetTable(true);\r
-               }\r
-             });\r
-             groupPanel.add(check);\r
-\r
-           }\r
-\r
-       }\r
-\r
-       if (!allFeatures.contains(tmpfeatures[index].getType()))\r
-       {\r
-           allFeatures.addElement(tmpfeatures[index].getType());\r
-       }\r
-       index ++;\r
-    }\r
-  }\r
-\r
-\r
-    if(!alignmentHasFeatures)\r
-     {\r
-       try\r
-       { frame.setClosed(true);  }\r
-       catch (Exception ex){}\r
-\r
-       JOptionPane.showInternalMessageDialog(\r
-           Desktop.desktop, "No features have been added to this alignment!",\r
-           "No Sequence Features", JOptionPane.WARNING_MESSAGE);\r
-\r
-       return;\r
-     }\r
-\r
-     resetTable(false);\r
-  }\r
-\r
-  void resetTable(boolean groupsChanged)\r
-  {\r
-   SequenceFeature [] tmpfeatures;\r
-   String group=null, type;\r
-   Vector visibleChecks = new Vector();\r
-\r
-   //Find out which features should be visible depending on which groups\r
-   //are selected / deselected\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
-    {\r
-        if (av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures() == null)\r
-          continue;\r
-\r
-        tmpfeatures = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
-        int index = 0;\r
-        while (index < tmpfeatures.length)\r
-        {\r
-          group = tmpfeatures[index].featureGroup;\r
-\r
-          if (group==null || fr.featureGroups.get(group)==null ||\r
-              ((Boolean) fr.featureGroups.get(group)).booleanValue())\r
-          {\r
-            type = tmpfeatures[index].getType();\r
-            if(!visibleChecks.contains(type) )\r
-            {\r
-              visibleChecks.addElement(type);\r
-            }\r
-          }\r
-          index++;\r
-        }\r
-    }\r
-\r
-    int fSize = visibleChecks.size();\r
-    Object [][] data = new Object[fSize][3];\r
-    int dataIndex = 0;\r
-\r
-    if(fr.renderOrder!=null)\r
-    {\r
-      //First add the checks in the previous render order,\r
-      //in case the window has been closed and reopened\r
-      for(int ro=fr.renderOrder.length-1; ro>-1; ro--)\r
-      {\r
-           type = fr.renderOrder[ro];\r
-\r
-           if(!visibleChecks.contains(type))\r
-             continue;\r
-\r
-           data[dataIndex][0] = type;\r
-           data[dataIndex][1] = fr.getColour(type);\r
-           data[dataIndex][2] = new Boolean(av.featuresDisplayed.containsKey(type));\r
-           dataIndex++;\r
-           visibleChecks.removeElement(type);\r
-      }\r
-    }\r
-\r
-    fSize = visibleChecks.size();\r
-    for(int i=0; i<fSize; i++)\r
-    {\r
-      //These must be extra features belonging to the group\r
-      //which was just selected\r
-      type = visibleChecks.elementAt(i).toString();\r
-      data[dataIndex][0] = type;\r
-      data[dataIndex][1] = fr.getColour(type);\r
-      data[dataIndex][2] = new Boolean(true);\r
-      dataIndex++;\r
-    }\r
-\r
-    if(originalData==null)\r
-    {\r
-      originalData = new Object[data.length][3];\r
-      System.arraycopy(data,0,originalData,0,data.length);\r
-    }\r
-\r
-    table = new JTable(new FeatureTableModel(data));\r
-    scrollPane.setViewportView(table);\r
-    table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));\r
-    table.setFont(new Font("Verdana", Font.PLAIN, 12));\r
-    table.setDefaultRenderer(Color.class,\r
-                         new ColorRenderer());\r
-\r
-    table.setDefaultEditor(Color.class,\r
-                      new ColorEditor());\r
-\r
-    table.getColumnModel().getColumn(0).setPreferredWidth(200);\r
-\r
-    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
-\r
-    table.addMouseListener(new MouseAdapter()\r
-        {\r
-          public void mousePressed(MouseEvent evt)\r
-          {\r
-            selectedRow = table.rowAtPoint(evt.getPoint());\r
-          }\r
-        });\r
-\r
-    table.addMouseMotionListener(new MouseMotionAdapter()\r
-        {\r
-          public void mouseDragged(MouseEvent evt)\r
-          {\r
-            int newRow = table.rowAtPoint(evt.getPoint());\r
-            if(newRow!=selectedRow\r
-               && selectedRow!=-1\r
-               && newRow!=-1)\r
-            {\r
-              Object[] temp = new Object[3];\r
-              temp[0] = table.getValueAt(selectedRow, 0);\r
-              temp[1] = table.getValueAt(selectedRow, 1);\r
-              temp[2] = table.getValueAt(selectedRow, 2);\r
-\r
-              table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);\r
-              table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);\r
-              table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);\r
-\r
-              table.setValueAt(temp[0], newRow, 0);\r
-              table.setValueAt(temp[1], newRow, 1);\r
-              table.setValueAt(temp[2], newRow, 2);\r
-\r
-              selectedRow = newRow;\r
-            }\r
-          }\r
-    });\r
-\r
-    updateFeatureRenderer(data);\r
-\r
-  }\r
-\r
-  void load()\r
-  {\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                 "LAST_DIRECTORY"), new String[] { "fc" },\r
-             new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");\r
-     chooser.setFileView(new jalview.io.JalviewFileView());\r
-     chooser.setDialogTitle("Load Feature Colours");\r
-     chooser.setToolTipText("Load");\r
-\r
-     int value = chooser.showOpenDialog(this);\r
-\r
-     if (value == JalviewFileChooser.APPROVE_OPTION)\r
-     {\r
-       File file = chooser.getSelectedFile();\r
-\r
-       try\r
-       {\r
-         InputStreamReader in = new InputStreamReader(new FileInputStream(\r
-             file), "UTF-8");\r
-\r
-         jalview.binding.JalviewUserColours jucs = new jalview.binding.\r
-             JalviewUserColours();\r
-         jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
-\r
-\r
-         for (int i = 0; i < jucs.getColourCount(); i++)\r
-         {\r
-           fr.setColour( jucs.getColour(i).getName(),\r
-                          new Color(Integer.parseInt( jucs.getColour(i).getRGB(), 16)));\r
-         }\r
-\r
-         setTableData();\r
-         ap.repaint();\r
-       }\r
-       catch (Exception ex)\r
-       {\r
-         System.out.println("Error loading User ColourFile\n" + ex);\r
-       }\r
-     }\r
-  }\r
-\r
-  void save()\r
-  {\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                "LAST_DIRECTORY"), new String[] { "fc" },\r
-            new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");\r
-    chooser.setFileView(new jalview.io.JalviewFileView());\r
-    chooser.setDialogTitle("Save Feature Colour Scheme");\r
-    chooser.setToolTipText("Save");\r
-\r
-    int value = chooser.showSaveDialog(this);\r
-\r
-    if (value == JalviewFileChooser.APPROVE_OPTION)\r
-    {\r
-        String choice = chooser.getSelectedFile().getPath();\r
-        jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
-        ucs.setSchemeName("Sequence Features");\r
-        try\r
-        {\r
-            PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
-                        new FileOutputStream(choice), "UTF-8"));\r
-\r
-            Enumeration e = fr.featureColours.keys();\r
-           while(e.hasMoreElements())\r
-           {\r
-\r
-\r
-                jalview.binding.Colour col = new jalview.binding.Colour();\r
-                col.setName(e.nextElement().toString());\r
-                col.setRGB(jalview.util.Format.getHexString(\r
-                        fr.getColour(col.getName())));\r
-                ucs.addColour(col);\r
-            }\r
-\r
-            ucs.marshal(out);\r
-            out.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-  }\r
-\r
-  public void updateFeatureRenderer(Object [][] data)\r
-  {\r
-    fr.setFeaturePriority( data );\r
-    ap.repaint();\r
-\r
-    if(ap.overviewPanel!=null)\r
-      ap.overviewPanel.updateOverviewImage();\r
-  }\r
-\r
-  int selectedRow =-1;\r
-\r
-\r
-  /////////////////////////////////////////////////////////////////////////\r
-  // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html\r
-  /////////////////////////////////////////////////////////////////////////\r
-  class FeatureTableModel\r
-      extends AbstractTableModel\r
-  {\r
-    FeatureTableModel(Object[][] data)\r
-    {\r
-      this.data = data;\r
-    }\r
-\r
-    private String[] columnNames = {"Feature Type", "Colour","Display"};\r
-          private Object[][] data;\r
-\r
-          public Object[][] getData()\r
-          {\r
-            return data;\r
-          }\r
-\r
-          public void setData(Object[][] data)\r
-          {\r
-            this.data = data;\r
-          }\r
-\r
-          public int getColumnCount() {\r
-              return columnNames.length;\r
-          }\r
-\r
-          public Object[] getRow(int row)\r
-          {\r
-            return data[row];\r
-          }\r
-\r
-          public int getRowCount() {\r
-              return data.length;\r
-          }\r
-\r
-          public String getColumnName(int col) {\r
-              return columnNames[col];\r
-          }\r
-\r
-          public Object getValueAt(int row, int col) {\r
-              return data[row][col];\r
-          }\r
-\r
-          public Class getColumnClass(int c) {\r
-              return getValueAt(0, c).getClass();\r
-          }\r
-\r
-          public boolean isCellEditable(int row, int col) {\r
-              return col==0 ? false:true;\r
-          }\r
-\r
-          public void setValueAt(Object value, int row, int col) {\r
-              data[row][col] = value;\r
-              fireTableCellUpdated(row, col);\r
-              updateFeatureRenderer(data);\r
-          }\r
-\r
-    }\r
-    class ColorRenderer extends JLabel\r
-                              implements TableCellRenderer {\r
-       javax.swing.border.Border unselectedBorder = null;\r
-       javax.swing.border.Border selectedBorder = null;\r
-\r
-       public ColorRenderer() {\r
-           setOpaque(true); //MUST do this for background to show up.\r
-       }\r
-\r
-       public Component getTableCellRendererComponent(\r
-                               JTable table, Object color,\r
-                               boolean isSelected, boolean hasFocus,\r
-                               int row, int column) {\r
-           Color newColor = (Color)color;\r
-           setBackground(newColor);\r
-               if (isSelected) {\r
-                   if (selectedBorder == null) {\r
-                       selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,\r
-                                                 table.getSelectionBackground());\r
-                   }\r
-                   setBorder(selectedBorder);\r
-               } else {\r
-                   if (unselectedBorder == null) {\r
-                       unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,\r
-                                                 table.getBackground());\r
-                   }\r
-                   setBorder(unselectedBorder);\r
-               }\r
-\r
-           setToolTipText("RGB value: " + newColor.getRed() + ", "\r
-                                        + newColor.getGreen() + ", "\r
-                                        + newColor.getBlue());\r
-           return this;\r
-       }\r
-   }\r
-}\r
-\r
- class ColorEditor extends AbstractCellEditor\r
-                          implements TableCellEditor,\r
-                                     ActionListener {\r
-     Color currentColor;\r
-     JButton button;\r
-     JColorChooser colorChooser;\r
-     JDialog dialog;\r
-     protected static final String EDIT = "edit";\r
-\r
-     public ColorEditor() {\r
-         //Set up the editor (from the table's point of view),\r
-         //which is a button.\r
-         //This button brings up the color chooser dialog,\r
-         //which is the editor from the user's point of view.\r
-         button = new JButton();\r
-         button.setActionCommand(EDIT);\r
-         button.addActionListener(this);\r
-         button.setBorderPainted(false);\r
-         //Set up the dialog that the button brings up.\r
-         colorChooser = new JColorChooser();\r
-         dialog = JColorChooser.createDialog(button,\r
-                                         "Select new Colour",\r
-                                         true,  //modal\r
-                                         colorChooser,\r
-                                         this,  //OK button handler\r
-                                         null); //no CANCEL button handler\r
-     }\r
-\r
-     /**\r
-      * Handles events from the editor button and from\r
-      * the dialog's OK button.\r
-      */\r
-     public void actionPerformed(ActionEvent e) {\r
-\r
-          if (EDIT.equals(e.getActionCommand())) {\r
-             //The user has clicked the cell, so\r
-             //bring up the dialog.\r
-             button.setBackground(currentColor);\r
-             colorChooser.setColor(currentColor);\r
-             dialog.setVisible(true);\r
-\r
-             //Make the renderer reappear.\r
-             fireEditingStopped();\r
-\r
-         } else { //User pressed dialog's "OK" button.\r
-             currentColor = colorChooser.getColor();\r
-         }\r
-     }\r
-\r
-     //Implement the one CellEditor method that AbstractCellEditor doesn't.\r
-     public Object getCellEditorValue() {\r
-         return currentColor;\r
-     }\r
-\r
-     //Implement the one method defined by TableCellEditor.\r
-     public Component getTableCellEditorComponent(JTable table,\r
-                                                  Object value,\r
-                                                  boolean isSelected,\r
-                                                  int row,\r
-                                                  int column) {\r
-         currentColor = (Color)value;\r
-         return button;\r
-     }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.BorderFactory;
+import java.awt.event.*;
+import javax.swing.table.*;
+import java.io.*;
+import jalview.io.JalviewFileChooser;
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.Color;
+
+public class FeatureSettings extends JPanel
+{
+  DasSourceBrowser dassourceBrowser;
+  JPanel settingsPane = new JPanel();
+  JPanel dasSettingsPane = new JPanel();
+
+  final FeatureRenderer fr;
+  final AlignFrame af;
+  Object [][] originalData;
+  final JInternalFrame frame;
+  JScrollPane scrollPane = new JScrollPane();
+  JTable table;
+  JPanel groupPanel;
+  JSlider transparency = new JSlider();
+
+  JPanel transPanel = new JPanel(new FlowLayout());
+
+  public FeatureSettings(AlignFrame af)
+  {
+    this.af = af;
+    fr = af.getFeatureRenderer();
+
+    transparency.setMaximum( 100 - (int)(fr.transparency*100) ) ;
+
+   try
+   {
+     jbInit();
+   }
+   catch (Exception ex)
+   {
+     ex.printStackTrace();
+   }
+
+   table = new JTable();
+   table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
+   table.setFont(new Font("Verdana", Font.PLAIN, 12));
+   table.setDefaultRenderer(Color.class,
+                            new ColorRenderer());
+
+   table.setDefaultEditor(Color.class,
+                          new ColorEditor());
+
+   table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+   table.addMouseListener(new MouseAdapter()
+   {
+     public void mousePressed(MouseEvent evt)
+     {
+       selectedRow = table.rowAtPoint(evt.getPoint());
+     }
+   });
+
+   table.addMouseMotionListener(new MouseMotionAdapter()
+   {
+     public void mouseDragged(MouseEvent evt)
+     {
+       int newRow = table.rowAtPoint(evt.getPoint());
+       if (newRow != selectedRow
+           && selectedRow != -1
+           && newRow != -1)
+       {
+         Object[] temp = new Object[3];
+         temp[0] = table.getValueAt(selectedRow, 0);
+         temp[1] = table.getValueAt(selectedRow, 1);
+         temp[2] = table.getValueAt(selectedRow, 2);
+
+         table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
+         table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
+         table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
+
+         table.setValueAt(temp[0], newRow, 0);
+         table.setValueAt(temp[1], newRow, 1);
+         table.setValueAt(temp[2], newRow, 2);
+
+         selectedRow = newRow;
+       }
+     }
+   });
+
+   scrollPane.setViewportView(table);
+
+    dassourceBrowser = new DasSourceBrowser();
+    dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
+
+
+
+    if (af.getViewport().featuresDisplayed == null || fr.renderOrder==null)
+       fr.findAllFeatures();
+
+    setTableData();
+
+    frame = new JInternalFrame();
+    frame.setContentPane(this);
+    Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 450);
+    frame.setLayer(JLayeredPane.PALETTE_LAYER);
+  }
+
+  synchronized public void setTableData()
+  {
+    if (fr.featureGroups == null)
+      fr.featureGroups = new Hashtable();
+
+    Vector allFeatures = new Vector();
+    Vector allGroups = new Vector();
+    SequenceFeature[] tmpfeatures;
+    String group;
+
+    for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
+    {
+      if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures() == null)
+        continue;
+
+      tmpfeatures = af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();
+
+      int index = 0;
+      while (index < tmpfeatures.length)
+      {
+        if(tmpfeatures[index].begin == 0 && tmpfeatures[index].end ==0)
+        {
+          index++;
+          continue;
+        }
+
+        if(tmpfeatures[index].getFeatureGroup()!=null)
+        {
+          group = tmpfeatures[index].featureGroup;
+          if(!allGroups.contains(group))
+           {
+             allGroups.addElement(group);
+
+             boolean visible = true;
+             if (fr.featureGroups.containsKey(group))
+             {
+               visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();
+             }
+
+               if (groupPanel == null)
+               {
+                 groupPanel = new JPanel();
+               }
+
+               boolean alreadyAdded = false;
+               for(int g=0; g<groupPanel.getComponentCount(); g++)
+               {
+                 if(((JCheckBox)groupPanel.getComponent(g))
+                    .getText().equals(group))
+                 {
+                   alreadyAdded = true;
+                   break;
+                 }
+               }
+
+               if(alreadyAdded)
+                 continue;
+
+               fr.featureGroups.put(group, new Boolean(visible));
+
+               final JCheckBox check = new JCheckBox(group, visible);
+               check.setFont(new Font("Serif", Font.BOLD, 12));
+               check.addItemListener(new ItemListener()
+               {
+                 public void itemStateChanged(ItemEvent evt)
+                 {
+                   fr.featureGroups.put(check.getText(),
+                                        new Boolean(check.isSelected()));
+                   af.alignPanel.seqPanel.seqCanvas.repaint();
+                   if (af.alignPanel.overviewPanel != null)
+                     af.alignPanel.overviewPanel.updateOverviewImage();
+
+                   resetTable(true);
+                 }
+               });
+               groupPanel.add(check);
+             }
+       }
+
+       if (!allFeatures.contains(tmpfeatures[index].getType()))
+       {
+           allFeatures.addElement(tmpfeatures[index].getType());
+       }
+       index ++;
+    }
+  }
+
+     resetTable(false);
+
+     validate();
+  }
+
+
+  void resetTable(boolean groupsChanged)
+  {
+   SequenceFeature [] tmpfeatures;
+   String group=null, type;
+   Vector visibleChecks = new Vector();
+
+   //Find out which features should be visible depending on which groups
+   //are selected / deselected
+    for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
+    {
+
+        tmpfeatures = af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();
+        if (tmpfeatures == null)
+          continue;
+
+        int index = 0;
+        while (index < tmpfeatures.length)
+        {
+          group = tmpfeatures[index].featureGroup;
+
+          if(tmpfeatures[index].begin==0 && tmpfeatures[index].end==0)
+          {
+            index ++;
+            continue;
+          }
+
+          if (group==null || fr.featureGroups.get(group)==null ||
+              ((Boolean) fr.featureGroups.get(group)).booleanValue())
+          {
+            type = tmpfeatures[index].getType();
+            if(!visibleChecks.contains(type) )
+            {
+              visibleChecks.addElement(type);
+            }
+          }
+          index++;
+        }
+    }
+
+    int fSize = visibleChecks.size();
+    Object [][] data = new Object[fSize][3];
+    int dataIndex = 0;
+
+    if(fr.renderOrder!=null)
+    {
+      //First add the checks in the previous render order,
+      //in case the window has been closed and reopened
+      for(int ro=fr.renderOrder.length-1; ro>-1; ro--)
+      {
+           type = fr.renderOrder[ro];
+
+           if(!visibleChecks.contains(type))
+             continue;
+
+           data[dataIndex][0] = type;
+           data[dataIndex][1] = fr.getColour(type);
+           data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed.containsKey(type));
+           dataIndex++;
+           visibleChecks.removeElement(type);
+      }
+    }
+
+    fSize = visibleChecks.size();
+    for(int i=0; i<fSize; i++)
+    {
+      //These must be extra features belonging to the group
+      //which was just selected
+      type = visibleChecks.elementAt(i).toString();
+      data[dataIndex][0] = type;
+
+      data[dataIndex][1] = fr.getColour(type);
+      data[dataIndex][2] = new Boolean(true);
+      dataIndex++;
+    }
+
+    if(originalData==null)
+    {
+      originalData = new Object[data.length][3];
+      System.arraycopy(data,0,originalData,0,data.length);
+    }
+
+    table.setModel(new FeatureTableModel(data));
+    table.getColumnModel().getColumn(0).setPreferredWidth(200);
+
+
+    if (groupPanel != null)
+    {
+      groupPanel.setLayout(
+          new GridLayout(fr.featureGroups.size() / 4 + 1, 4));
+
+      groupPanel.validate();
+      bigPanel.add(groupPanel, BorderLayout.NORTH);
+    }
+
+    updateFeatureRenderer(data);
+
+  }
+
+  void load()
+  {
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                 "LAST_DIRECTORY"), new String[] { "fc" },
+             new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");
+     chooser.setFileView(new jalview.io.JalviewFileView());
+     chooser.setDialogTitle("Load Feature Colours");
+     chooser.setToolTipText("Load");
+
+     int value = chooser.showOpenDialog(this);
+
+     if (value == JalviewFileChooser.APPROVE_OPTION)
+     {
+       File file = chooser.getSelectedFile();
+
+       try
+       {
+         InputStreamReader in = new InputStreamReader(new FileInputStream(
+             file), "UTF-8");
+
+         jalview.binding.JalviewUserColours jucs = new jalview.binding.
+             JalviewUserColours();
+         jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
+
+
+         for (int i = 0; i < jucs.getColourCount(); i++)
+         {
+           fr.setColour( jucs.getColour(i).getName(),
+                          new Color(Integer.parseInt( jucs.getColour(i).getRGB(), 16)));
+         }
+
+         setTableData();
+         af.alignPanel.repaint();
+       }
+       catch (Exception ex)
+       {
+         System.out.println("Error loading User Colour File\n" + ex);
+       }
+     }
+  }
+
+  void save()
+  {
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                "LAST_DIRECTORY"), new String[] { "fc" },
+            new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");
+    chooser.setFileView(new jalview.io.JalviewFileView());
+    chooser.setDialogTitle("Save Feature Colour Scheme");
+    chooser.setToolTipText("Save");
+
+    int value = chooser.showSaveDialog(this);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+        String choice = chooser.getSelectedFile().getPath();
+        jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();
+        ucs.setSchemeName("Sequence Features");
+        try
+        {
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(
+                        new FileOutputStream(choice), "UTF-8"));
+
+            Enumeration e = fr.featureColours.keys();
+           while(e.hasMoreElements())
+           {
+                jalview.binding.Colour col = new jalview.binding.Colour();
+                col.setName(e.nextElement().toString());
+                col.setRGB(jalview.util.Format.getHexString(
+                        fr.getColour(col.getName())));
+                ucs.addColour(col);
+            }
+
+            ucs.marshal(out);
+            out.close();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+  }
+
+  public void invertSelection()
+  {
+    for(int i=0; i<table.getRowCount(); i++)
+    {
+      Boolean value = (Boolean)table.getValueAt(i,2);
+
+      table.setValueAt(
+          new Boolean(!value.booleanValue()),
+                       i,2);
+    }
+  }
+
+  public void close()
+  {
+    try
+    {
+      frame.setClosed(true);
+    }
+    catch (Exception exe)
+    {}
+
+  }
+
+  public void updateFeatureRenderer(Object [][] data)
+  {
+    fr.setFeaturePriority( data );
+    af.alignPanel.repaint();
+
+    if(af.alignPanel.overviewPanel!=null)
+      af.alignPanel.overviewPanel.updateOverviewImage();
+  }
+
+  int selectedRow =-1;
+  JTabbedPane tabbedPane = new JTabbedPane();
+  BorderLayout borderLayout1 = new BorderLayout();
+  BorderLayout borderLayout2 = new BorderLayout();
+  BorderLayout borderLayout3 = new BorderLayout();
+  JPanel bigPanel = new JPanel();
+  BorderLayout borderLayout4 = new BorderLayout();
+  JButton invert = new JButton();
+  JPanel buttonPanel = new JPanel();
+  JButton cancel = new JButton();
+  JButton ok = new JButton();
+  JButton loadColours = new JButton();
+  JButton saveColours = new JButton();
+  JPanel dasButtonPanel = new JPanel();
+  JButton fetchDAS = new JButton();
+  JButton saveDAS = new JButton();
+  private void jbInit()
+      throws Exception
+  {
+    this.setLayout(borderLayout1);
+    settingsPane.setLayout(borderLayout2);
+    dasSettingsPane.setLayout(borderLayout3);
+    bigPanel.setLayout(borderLayout4);
+    invert.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    invert.setText("Invert Selection");
+    invert.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        invertSelection();
+      }
+    });
+    cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    cancel.setText("Cancel");
+    cancel.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+          updateFeatureRenderer(originalData);
+          close();
+      }
+    });
+    ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    ok.setText("OK");
+    ok.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        close();
+      }
+    });
+    loadColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    loadColours.setText("Load Colours");
+    loadColours.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        load();
+      }
+    });
+    saveColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    saveColours.setText("Save Colours");
+    saveColours.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        save();
+      }
+    });
+    transparency.addChangeListener(new ChangeListener()
+    {
+      public void stateChanged(ChangeEvent evt)
+      {
+        fr.setTransparency( (float) (100 - transparency.getValue()) / 100f);
+        af.alignPanel.repaint();
+      }
+    });
+
+
+    transparency.setMaximum(70);
+    fetchDAS.setText("Fetch DAS Features");
+    fetchDAS.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        fetchDAS_actionPerformed(e);
+      }
+    });
+    saveDAS.setText("Save as default");
+    saveDAS.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        saveDAS_actionPerformed(e);
+      }
+    });
+    dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
+    dasSettingsPane.setBorder(null);
+    this.add(tabbedPane, java.awt.BorderLayout.CENTER);
+    tabbedPane.addTab("Feature Settings", settingsPane );
+    tabbedPane.addTab("DAS Settings", dasSettingsPane);
+    bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
+    transPanel.add(transparency);
+    transPanel.add(invert);
+    buttonPanel.add(ok);
+    buttonPanel.add(cancel);
+    buttonPanel.add(loadColours);
+    buttonPanel.add(saveColours);
+    bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);
+    dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);
+    dasButtonPanel.add(fetchDAS);
+    dasButtonPanel.add(saveDAS);
+    settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);
+    settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
+  }
+
+  public void fetchDAS_actionPerformed(ActionEvent e)
+  {
+    Vector selectedSources = dassourceBrowser.getSelectedSources();
+
+    SequenceI [] dataset, seqs ;
+    int iSize;
+
+    if(af.getViewport().getSelectionGroup()!=null
+      && af.getViewport().getSelectionGroup().getSize(false)>0)
+    {
+      iSize = af.getViewport().getSelectionGroup().getSize(false);
+      dataset = new SequenceI[iSize];
+      seqs = af.getViewport().getSelectionGroup().
+          getSequencesInOrder(
+              af.getViewport().getAlignment());
+    }
+    else
+    {
+       iSize = af.getViewport().getAlignment().getHeight();
+       seqs = af.getViewport().getAlignment().getSequencesArray();
+    }
+
+    dataset = new SequenceI[iSize];
+    for (int i = 0; i < iSize; i++)
+    {
+      dataset[i] = seqs[i].getDatasetSequence();
+    }
+
+    new jalview.io.DasSequenceFeatureFetcher(
+        dataset,
+        af,
+        selectedSources);
+
+    af.getViewport().setShowSequenceFeatures(true);
+    af.showSeqFeatures.setSelected(true);
+  }
+
+  public void saveDAS_actionPerformed(ActionEvent e)
+  {
+    dassourceBrowser.saveProperties(jalview.bin.Cache.applicationProperties);
+  }
+
+  /////////////////////////////////////////////////////////////////////////
+  // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
+  /////////////////////////////////////////////////////////////////////////
+  class FeatureTableModel
+      extends AbstractTableModel
+  {
+    FeatureTableModel(Object[][] data)
+    {
+      this.data = data;
+    }
+
+    private String[] columnNames = {"Feature Type", "Colour","Display"};
+          private Object[][] data;
+
+          public Object[][] getData()
+          {
+            return data;
+          }
+
+          public void setData(Object[][] data)
+          {
+            this.data = data;
+          }
+
+          public int getColumnCount() {
+              return columnNames.length;
+          }
+
+          public Object[] getRow(int row)
+          {
+            return data[row];
+          }
+
+          public int getRowCount() {
+              return data.length;
+          }
+
+          public String getColumnName(int col) {
+              return columnNames[col];
+          }
+
+          public Object getValueAt(int row, int col) {
+              return data[row][col];
+          }
+
+          public Class getColumnClass(int c) {
+              return getValueAt(0, c).getClass();
+          }
+
+          public boolean isCellEditable(int row, int col) {
+              return col==0 ? false:true;
+          }
+
+          public void setValueAt(Object value, int row, int col) {
+              data[row][col] = value;
+              fireTableCellUpdated(row, col);
+              updateFeatureRenderer(data);
+          }
+
+    }
+    class ColorRenderer extends JLabel
+                              implements TableCellRenderer {
+       javax.swing.border.Border unselectedBorder = null;
+       javax.swing.border.Border selectedBorder = null;
+
+       public ColorRenderer() {
+           setOpaque(true); //MUST do this for background to show up.
+       }
+
+       public Component getTableCellRendererComponent(
+                               JTable table, Object color,
+                               boolean isSelected, boolean hasFocus,
+                               int row, int column) {
+           Color newColor = (Color)color;
+           setBackground(newColor);
+               if (isSelected) {
+                   if (selectedBorder == null) {
+                       selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
+                                                 table.getSelectionBackground());
+                   }
+                   setBorder(selectedBorder);
+               } else {
+                   if (unselectedBorder == null) {
+                       unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
+                                                 table.getBackground());
+                   }
+                   setBorder(unselectedBorder);
+               }
+
+           setToolTipText("RGB value: " + newColor.getRed() + ", "
+                                        + newColor.getGreen() + ", "
+                                        + newColor.getBlue());
+           return this;
+       }
+   }
+}
+
+ class ColorEditor extends AbstractCellEditor
+                          implements TableCellEditor,
+                                     ActionListener {
+     Color currentColor;
+     JButton button;
+     JColorChooser colorChooser;
+     JDialog dialog;
+     protected static final String EDIT = "edit";
+
+     public ColorEditor() {
+         //Set up the editor (from the table's point of view),
+         //which is a button.
+         //This button brings up the color chooser dialog,
+         //which is the editor from the user's point of view.
+         button = new JButton();
+         button.setActionCommand(EDIT);
+         button.addActionListener(this);
+         button.setBorderPainted(false);
+         //Set up the dialog that the button brings up.
+         colorChooser = new JColorChooser();
+         dialog = JColorChooser.createDialog(button,
+                                         "Select new Colour",
+                                         true,  //modal
+                                         colorChooser,
+                                         this,  //OK button handler
+                                         null); //no CANCEL button handler
+     }
+
+     /**
+      * Handles events from the editor button and from
+      * the dialog's OK button.
+      */
+     public void actionPerformed(ActionEvent e) {
+
+          if (EDIT.equals(e.getActionCommand())) {
+             //The user has clicked the cell, so
+             //bring up the dialog.
+             button.setBackground(currentColor);
+             colorChooser.setColor(currentColor);
+             dialog.setVisible(true);
+
+             //Make the renderer reappear.
+             fireEditingStopped();
+
+         } else { //User pressed dialog's "OK" button.
+             currentColor = colorChooser.getColor();
+         }
+     }
+
+     //Implement the one CellEditor method that AbstractCellEditor doesn't.
+     public Object getCellEditorValue() {
+         return currentColor;
+     }
+
+     //Implement the one method defined by TableCellEditor.
+     public Component getTableCellEditorComponent(JTable table,
+                                                  Object value,
+                                                  boolean isSelected,
+                                                  int row,
+                                                  int column) {
+         currentColor = (Color)value;
+         return button;
+     }
+}
index 6b8df4b..1e94475 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-import javax.swing.event.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Finder extends GFinder\r
-{\r
-    AlignViewport av;\r
-    AlignmentPanel ap;\r
-    JInternalFrame frame;\r
-    int seqIndex = 0;\r
-    int resIndex = 0;\r
-\r
-    SearchResults searchResults;\r
-\r
-    /**\r
-     * Creates a new Finder object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     * @param ap DOCUMENT ME!\r
-     * @param f DOCUMENT ME!\r
-     */\r
-    public Finder(AlignViewport av, AlignmentPanel ap, JInternalFrame f)\r
-    {\r
-        this.av = av;\r
-        this.ap = ap;\r
-        frame = f;\r
-\r
-        // all a big pain, but we need to wait until the frame is visible before the textfield can\r
-        // obtain the focus/////////////////////////\r
-        frame.addInternalFrameListener(new InternalFrameAdapter()\r
-            {\r
-                public void internalFrameOpened(InternalFrameEvent evt)\r
-                {\r
-                    SwingUtilities.invokeLater(new Runnable()\r
-                        {\r
-                            public void run()\r
-                            {\r
-                                textfield.requestFocus();\r
-                            }\r
-                        });\r
-                }\r
-            });\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void findNext_actionPerformed(ActionEvent e)\r
-    {\r
-        doSearch(false);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void findAll_actionPerformed(ActionEvent e)\r
-    {\r
-        resIndex = 0;\r
-        seqIndex = 0;\r
-        doSearch(true);\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void createNewGroup_actionPerformed(ActionEvent e)\r
-    {\r
-        JLabel label = new JLabel("Enter name of new sequence feature");\r
-        JTextField textinput = new JTextField(textfield.getText());\r
-        JPanel panel = new JPanel(new BorderLayout());\r
-        panel.add(label, BorderLayout.NORTH);\r
-        panel.add(textinput, BorderLayout.SOUTH);\r
-\r
-         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
-            panel, "New Sequence Feature Name",\r
-          JOptionPane.OK_CANCEL_OPTION );\r
-\r
-         if(reply != JOptionPane.OK_OPTION)\r
-           return;\r
-\r
-        for (int i = 0; i < searchResults.getSize(); i ++ )\r
-        {\r
-            SequenceI seq = searchResults.getResultSequence(i);\r
-\r
-            SequenceFeature sf = new SequenceFeature(textinput.getText(),\r
-                "Search Results", null,\r
-                searchResults.getResultStart(i),\r
-               searchResults.getResultEnd(i),\r
-               "Search Results");\r
-\r
-            ap.seqPanel.seqCanvas.getFeatureRenderer().addNewFeature(\r
-                textinput.getText(), new Color(60,160,115),\r
-                    "Search Results");\r
-\r
-            seq.getDatasetSequence().addSequenceFeature(sf);\r
-        }\r
-\r
-        ap.seqPanel.seqCanvas.getFeatureRenderer().findAllFeatures();\r
-        ap.alignFrame.showSeqFeatures.setSelected(true);\r
-        av.setShowSequenceFeatures(true);\r
-        ap.highlightSearchResults(null);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param findAll DOCUMENT ME!\r
-     */\r
-    void doSearch(boolean findAll)\r
-    {\r
-        createNewGroup.setEnabled(false);\r
-\r
-        String searchString = textfield.getText().toUpperCase().trim();\r
-        if(searchString.length()<1)\r
-          return;\r
-\r
-        com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);\r
-\r
-        searchResults = new SearchResults();\r
-\r
-        Sequence seq;\r
-        String item = null;\r
-        boolean found = false;\r
-\r
-        ////// is the searchString a residue number?\r
-        try\r
-        {\r
-            int res = Integer.parseInt(searchString);\r
-            found = true;\r
-            if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize() < 1)\r
-            {\r
-              seq = (Sequence) av.getAlignment().getSequenceAt(0);\r
-            }\r
-            else\r
-            {\r
-              seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));\r
-            }\r
-\r
-            searchResults.addResult(seq, res, res);\r
-        }\r
-        catch (NumberFormatException ex)\r
-        {\r
-        }\r
-\r
-        ///////////////////////////////////////////////\r
-\r
-        int end = av.alignment.getHeight();\r
-\r
-        SequenceGroup selection = av.getSelectionGroup();\r
-\r
-        if (selection != null)\r
-        {\r
-            if ((selection.getSize() < 1) ||\r
-                    ((selection.getEndRes() - selection.getStartRes()) < 2))\r
-            {\r
-                selection = null;\r
-            }\r
-        }\r
-\r
-        while (!found && (seqIndex < end))\r
-        {\r
-            seq = (Sequence) av.alignment.getSequenceAt(seqIndex);\r
-\r
-            if ((selection != null) && !selection.sequences.contains(seq))\r
-            {\r
-                seqIndex++;\r
-                resIndex = 0;\r
-\r
-                continue;\r
-            }\r
-\r
-            item = seq.getSequence().toUpperCase();\r
-\r
-            if ((selection != null) &&\r
-                    (selection.getEndRes() < av.alignment.getWidth()-1))\r
-            {\r
-                item = item.substring(0, selection.getEndRes() + 1);\r
-            }\r
-\r
-            ///Shall we ignore gaps????\r
-            StringBuffer noGapsSB = new StringBuffer();\r
-            int insertCount = 0;\r
-            Vector spaces = new Vector();\r
-\r
-            for (int j = 0; j < item.length(); j++)\r
-            {\r
-                if (!jalview.util.Comparison.isGap(item.charAt(j)))\r
-                {\r
-                    noGapsSB.append(item.charAt(j));\r
-                    spaces.add(new Integer(insertCount));\r
-                }\r
-                else\r
-                {\r
-                    insertCount++;\r
-                }\r
-            }\r
-\r
-            String noGaps = noGapsSB.toString();\r
-\r
-            for (int r = resIndex; r < noGaps.length(); r++)\r
-            {\r
-\r
-                if (regex.searchFrom(noGaps, r))\r
-                {\r
-                    resIndex = regex.matchedFrom();\r
-\r
-                    if ((selection != null) &&\r
-                            ((resIndex +\r
-                            Integer.parseInt(spaces.get(resIndex).toString())) < selection.getStartRes()))\r
-                    {\r
-                        continue;\r
-                    }\r
-\r
-\r
-                    int sres = seq.findPosition(resIndex +\r
-                            Integer.parseInt(spaces.elementAt(resIndex)\r
-                                                   .toString()));\r
-                    int eres = seq.findPosition(regex.matchedTo() - 1 +\r
-                            Integer.parseInt(spaces.elementAt(regex.matchedTo() -\r
-                                    1).toString()));\r
-\r
-                    searchResults.addResult(seq, sres, eres);\r
-\r
-                    if (!findAll)\r
-                    {\r
-                        // thats enough, break and display the result\r
-                        found = true;\r
-                        resIndex++;\r
-\r
-                        break;\r
-                    }\r
-\r
-                    r = resIndex;\r
-                }\r
-                else\r
-                {\r
-                  break;\r
-                }\r
-            }\r
-\r
-            if (!found)\r
-            {\r
-                seqIndex++;\r
-                resIndex = 0;\r
-            }\r
-        }\r
-\r
-        Vector idMatch = new Vector();\r
-\r
-        for (int id = 0; id < av.alignment.getHeight(); id++)\r
-        {\r
-            if (regex.search(av.alignment.getSequenceAt(id).getName()))\r
-            {\r
-                idMatch.add(av.alignment.getSequenceAt(id));\r
-            }\r
-        }\r
-\r
-        if ((searchResults.getSize() == 0) && (idMatch.size() > 0))\r
-        {\r
-            ap.idPanel.highlightSearchResults(idMatch);\r
-        }\r
-\r
-\r
-        int resultSize = searchResults.getSize();\r
-\r
-        if (searchResults.getSize() > 0)\r
-          createNewGroup.setEnabled(true);\r
-        else\r
-          searchResults = null;\r
-\r
-        // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
-        ap.highlightSearchResults(searchResults);\r
-\r
-        if(!findAll && resultSize==0)\r
-        {\r
-            JOptionPane.showInternalMessageDialog(this, "Finished searching",\r
-                null, JOptionPane.INFORMATION_MESSAGE);\r
-            resIndex = 0;\r
-            seqIndex = 0;\r
-        }\r
-\r
-        if (findAll)\r
-        {\r
-          String message = resultSize + " matches found.";\r
-          JOptionPane.showInternalMessageDialog(this, message, null,\r
-                                                JOptionPane.INFORMATION_MESSAGE);\r
-        }\r
-\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.jbgui.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Finder extends GFinder
+{
+    AlignViewport av;
+    AlignmentPanel ap;
+    JInternalFrame frame;
+    int seqIndex = 0;
+    int resIndex = 0;
+
+    SearchResults searchResults;
+
+    /**
+     * Creates a new Finder object.
+     *
+     * @param av DOCUMENT ME!
+     * @param ap DOCUMENT ME!
+     * @param f DOCUMENT ME!
+     */
+    public Finder(AlignViewport av, AlignmentPanel ap, JInternalFrame f)
+    {
+        this.av = av;
+        this.ap = ap;
+        frame = f;
+
+        // all a big pain, but we need to wait until the frame is visible before the textfield can
+        // obtain the focus/////////////////////////
+        frame.addInternalFrameListener(new InternalFrameAdapter()
+            {
+                public void internalFrameOpened(InternalFrameEvent evt)
+                {
+                    SwingUtilities.invokeLater(new Runnable()
+                        {
+                            public void run()
+                            {
+                                textfield.requestFocus();
+                            }
+                        });
+                }
+            });
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void findNext_actionPerformed(ActionEvent e)
+    {
+        doSearch(false);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void findAll_actionPerformed(ActionEvent e)
+    {
+        resIndex = 0;
+        seqIndex = 0;
+        doSearch(true);
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void createNewGroup_actionPerformed(ActionEvent e)
+    {
+        JLabel label = new JLabel("Enter name of new sequence feature");
+        JTextField textinput = new JTextField(textfield.getText());
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.add(label, BorderLayout.NORTH);
+        panel.add(textinput, BorderLayout.SOUTH);
+
+         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+            panel, "New Sequence Feature Name",
+          JOptionPane.OK_CANCEL_OPTION );
+
+         if(reply != JOptionPane.OK_OPTION)
+           return;
+
+        for (int i = 0; i < searchResults.getSize(); i ++ )
+        {
+            SequenceI seq = searchResults.getResultSequence(i);
+
+            SequenceFeature sf = new SequenceFeature(textinput.getText(),
+                "Search Results", null,
+                searchResults.getResultStart(i),
+               searchResults.getResultEnd(i),
+               "Search Results");
+
+            ap.seqPanel.seqCanvas.getFeatureRenderer().addNewFeature(
+                textinput.getText(), new Color(60,160,115),
+                    "Search Results");
+
+            seq.getDatasetSequence().addSequenceFeature(sf);
+        }
+
+        ap.seqPanel.seqCanvas.getFeatureRenderer().findAllFeatures();
+        ap.alignFrame.showSeqFeatures.setSelected(true);
+        av.setShowSequenceFeatures(true);
+        ap.highlightSearchResults(null);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param findAll DOCUMENT ME!
+     */
+    void doSearch(boolean findAll)
+    {
+        createNewGroup.setEnabled(false);
+
+        String searchString = textfield.getText().trim();
+        if(!caseSensitive.isSelected())
+          searchString = searchString.toUpperCase();
+
+        if(searchString.length()<1)
+          return;
+
+        com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);
+
+        searchResults = new SearchResults();
+
+        Sequence seq;
+        String item = null;
+        boolean found = false;
+
+        ////// is the searchString a residue number?
+        try
+        {
+            int res = Integer.parseInt(searchString);
+            found = true;
+            if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize(false) < 1)
+            {
+              seq = (Sequence) av.getAlignment().getSequenceAt(0);
+            }
+            else
+            {
+              seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));
+            }
+
+            searchResults.addResult(seq, res, res);
+        }
+        catch (NumberFormatException ex)
+        {
+        }
+
+        ///////////////////////////////////////////////
+
+        int end = av.alignment.getHeight();
+
+        SequenceGroup selection = av.getSelectionGroup();
+
+        if (selection != null)
+        {
+            if ((selection.getSize(false) < 1) ||
+                    ((selection.getEndRes() - selection.getStartRes()) < 2))
+            {
+                selection = null;
+            }
+        }
+
+        while (!found && (seqIndex < end))
+        {
+            seq = (Sequence) av.alignment.getSequenceAt(seqIndex);
+
+            if ((selection != null) && !selection.getSequences(false).contains(seq))
+            {
+                seqIndex++;
+                resIndex = 0;
+
+                continue;
+            }
+
+            item = seq.getSequence();
+            if(!caseSensitive.isSelected())
+              item = item.toUpperCase();
+
+            if ((selection != null) &&
+                    (selection.getEndRes() < av.alignment.getWidth()-1))
+            {
+                item = item.substring(0, selection.getEndRes() + 1);
+            }
+
+            ///Shall we ignore gaps????
+            StringBuffer noGapsSB = new StringBuffer();
+            int insertCount = 0;
+            Vector spaces = new Vector();
+
+            for (int j = 0; j < item.length(); j++)
+            {
+                if (!jalview.util.Comparison.isGap(item.charAt(j)))
+                {
+                    noGapsSB.append(item.charAt(j));
+                    spaces.add(new Integer(insertCount));
+                }
+                else
+                {
+                    insertCount++;
+                }
+            }
+
+            String noGaps = noGapsSB.toString();
+
+            for (int r = resIndex; r < noGaps.length(); r++)
+            {
+
+                if (regex.searchFrom(noGaps, r))
+                {
+                    resIndex = regex.matchedFrom();
+
+                    if ((selection != null) &&
+                            ((resIndex +
+                            Integer.parseInt(spaces.get(resIndex).toString())) < selection.getStartRes()))
+                    {
+                        continue;
+                    }
+
+
+                    int sres = seq.findPosition(resIndex +
+                            Integer.parseInt(spaces.elementAt(resIndex)
+                                                   .toString()));
+                    int eres = seq.findPosition(regex.matchedTo() - 1 +
+                            Integer.parseInt(spaces.elementAt(regex.matchedTo() -
+                                    1).toString()));
+
+                    searchResults.addResult(seq, sres, eres);
+
+                    if (!findAll)
+                    {
+                        // thats enough, break and display the result
+                        found = true;
+                        resIndex++;
+
+                        break;
+                    }
+
+                    r = resIndex;
+                }
+                else
+                {
+                  break;
+                }
+            }
+
+            if (!found)
+            {
+                seqIndex++;
+                resIndex = 0;
+            }
+        }
+
+        Vector idMatch = new Vector();
+
+        for (int id = 0; id < av.alignment.getHeight(); id++)
+        {
+            if (regex.search(av.alignment.getSequenceAt(id).getName()))
+            {
+                idMatch.add(av.alignment.getSequenceAt(id));
+            }
+        }
+
+        if ((searchResults.getSize() == 0) && (idMatch.size() > 0))
+        {
+            ap.idPanel.highlightSearchResults(idMatch);
+        }
+
+
+        int resultSize = searchResults.getSize();
+
+        if (searchResults.getSize() > 0)
+          createNewGroup.setEnabled(true);
+        else
+          searchResults = null;
+
+        // if allResults is null, this effectively switches displaySearch flag in seqCanvas
+        ap.highlightSearchResults(searchResults);
+
+        if(!findAll && resultSize==0)
+        {
+            JOptionPane.showInternalMessageDialog(this, "Finished searching",
+                null, JOptionPane.INFORMATION_MESSAGE);
+            resIndex = 0;
+            seqIndex = 0;
+        }
+
+        if (findAll)
+        {
+          String message = resultSize + " matches found.";
+          JOptionPane.showInternalMessageDialog(this, message, null,
+                                                JOptionPane.INFORMATION_MESSAGE);
+        }
+
+    }
+}
index 6eab36b..c5fde61 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.bin.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class FontChooser extends GFontChooser\r
-{\r
-    AlignmentPanel ap;\r
-    TreePanel tp;\r
-    Font oldFont;\r
-    boolean init = true;\r
-    JInternalFrame frame;\r
-\r
-    /**\r
-     * Creates a new FontChooser object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     */\r
-    public FontChooser(TreePanel tp)\r
-    {\r
-      this.tp = tp;\r
-      oldFont = tp.getTreeFont();\r
-      defaultButton.setVisible(false);\r
-      init();\r
-    }\r
-    /**\r
-     * Creates a new FontChooser object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     */\r
-    public FontChooser(AlignmentPanel ap)\r
-    {\r
-      oldFont = ap.av.getFont();\r
-      this.ap = ap;\r
-      init();\r
-    }\r
-\r
-    void init()\r
-    {\r
-        frame = new JInternalFrame();\r
-        frame.setContentPane(this);\r
-        if(tp!=null)\r
-           Desktop.addInternalFrame(frame, "Change Font (Tree Panel)", 540, 100, false);\r
-        else\r
-           Desktop.addInternalFrame(frame, "Change Font", 540, 100, false);\r
-\r
-        frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
-\r
-        String[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()\r
-                                                     .getAvailableFontFamilyNames();\r
-\r
-        for (int i = 0; i < fonts.length; i++)\r
-        {\r
-            fontName.addItem(fonts[i]);\r
-        }\r
-\r
-        for (int i = 1; i < 51; i++)\r
-        {\r
-            fontSize.addItem(i + "");\r
-        }\r
-\r
-        fontStyle.addItem("plain");\r
-        fontStyle.addItem("bold");\r
-        fontStyle.addItem("italic");\r
-\r
-        fontName.setSelectedItem(oldFont.getName());\r
-        fontSize.setSelectedItem(oldFont.getSize() + "");\r
-        fontStyle.setSelectedIndex(oldFont.getStyle());\r
-\r
-        FontMetrics fm = getGraphics().getFontMetrics(oldFont);\r
-        monospaced.setSelected( fm.getStringBounds("M",getGraphics()).getWidth()\r
-                              ==fm.getStringBounds("|",getGraphics()).getWidth());\r
-\r
-\r
-        init = false;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void ok_actionPerformed(ActionEvent e)\r
-    {\r
-        try\r
-        {\r
-            frame.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-\r
-        if(ap!=null)\r
-        {\r
-          if (ap.getOverviewPanel() != null)\r
-          {\r
-            ap.getOverviewPanel().updateOverviewImage();\r
-          }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-        if(ap!=null)\r
-        {\r
-          ap.av.setFont(oldFont);\r
-          ap.repaint();\r
-        }\r
-        else if(tp!=null)\r
-        {\r
-          tp.setTreeFont(oldFont);\r
-        }\r
-        fontName.setSelectedItem(oldFont.getName());\r
-        fontSize.setSelectedItem(oldFont.getSize() + "");\r
-        fontStyle.setSelectedIndex(oldFont.getStyle());\r
-\r
-        try\r
-        {\r
-            frame.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    void changeFont()\r
-    {\r
-      Font newFont = new Font(fontName.getSelectedItem().toString(),\r
-                              fontStyle.getSelectedIndex(),\r
-                              Integer.parseInt(fontSize.getSelectedItem().toString()));\r
-      if (ap != null)\r
-      {\r
-        ap.av.setFont(newFont);\r
-        ap.fontChanged();\r
-      }\r
-      else if(tp != null)\r
-      {\r
-        tp.setTreeFont(newFont);\r
-      }\r
-\r
-      FontMetrics fm = getGraphics().getFontMetrics(newFont);\r
-\r
-      monospaced.setSelected( fm.getStringBounds("M",getGraphics()).getWidth()\r
-                                ==fm.getStringBounds("|",getGraphics()).getWidth());\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void fontName_actionPerformed(ActionEvent e)\r
-    {\r
-        if (init)\r
-        {\r
-            return;\r
-        }\r
-\r
-        changeFont();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void fontSize_actionPerformed(ActionEvent e)\r
-    {\r
-        if (init)\r
-        {\r
-            return;\r
-        }\r
-\r
-        changeFont();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void fontStyle_actionPerformed(ActionEvent e)\r
-    {\r
-        if (init)\r
-        {\r
-            return;\r
-        }\r
-\r
-        changeFont();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void defaultButton_actionPerformed(ActionEvent e)\r
-    {\r
-        Cache.setProperty("FONT_NAME", fontName.getSelectedItem().toString());\r
-        Cache.setProperty("FONT_STYLE", fontStyle.getSelectedIndex() + "");\r
-        Cache.setProperty("FONT_SIZE", fontSize.getSelectedItem().toString());\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.bin.*;
+
+import jalview.jbgui.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class FontChooser extends GFontChooser
+{
+    AlignmentPanel ap;
+    TreePanel tp;
+    Font oldFont;
+    boolean init = true;
+    JInternalFrame frame;
+
+    /**
+     * Creates a new FontChooser object.
+     *
+     * @param ap DOCUMENT ME!
+     */
+    public FontChooser(TreePanel tp)
+    {
+      this.tp = tp;
+      oldFont = tp.getTreeFont();
+      defaultButton.setVisible(false);
+      init();
+    }
+    /**
+     * Creates a new FontChooser object.
+     *
+     * @param ap DOCUMENT ME!
+     */
+    public FontChooser(AlignmentPanel ap)
+    {
+      oldFont = ap.av.getFont();
+      this.ap = ap;
+      init();
+    }
+
+    void init()
+    {
+        frame = new JInternalFrame();
+        frame.setContentPane(this);
+        if(tp!=null)
+           Desktop.addInternalFrame(frame, "Change Font (Tree Panel)", 540, 100, false);
+        else
+           Desktop.addInternalFrame(frame, "Change Font", 540, 100, false);
+
+        frame.setLayer(JLayeredPane.PALETTE_LAYER);
+
+        String[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
+                                                     .getAvailableFontFamilyNames();
+
+        for (int i = 0; i < fonts.length; i++)
+        {
+            fontName.addItem(fonts[i]);
+        }
+
+        for (int i = 1; i < 51; i++)
+        {
+            fontSize.addItem(i + "");
+        }
+
+        fontStyle.addItem("plain");
+        fontStyle.addItem("bold");
+        fontStyle.addItem("italic");
+
+        fontName.setSelectedItem(oldFont.getName());
+        fontSize.setSelectedItem(oldFont.getSize() + "");
+        fontStyle.setSelectedIndex(oldFont.getStyle());
+
+        FontMetrics fm = getGraphics().getFontMetrics(oldFont);
+        monospaced.setSelected( fm.getStringBounds("M",getGraphics()).getWidth()
+                              ==fm.getStringBounds("|",getGraphics()).getWidth());
+
+
+        init = false;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void ok_actionPerformed(ActionEvent e)
+    {
+        try
+        {
+            frame.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+
+        if(ap!=null)
+        {
+          if (ap.getOverviewPanel() != null)
+          {
+            ap.getOverviewPanel().updateOverviewImage();
+          }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void cancel_actionPerformed(ActionEvent e)
+    {
+        if(ap!=null)
+        {
+          ap.av.setFont(oldFont);
+          ap.repaint();
+        }
+        else if(tp!=null)
+        {
+          tp.setTreeFont(oldFont);
+        }
+        fontName.setSelectedItem(oldFont.getName());
+        fontSize.setSelectedItem(oldFont.getSize() + "");
+        fontStyle.setSelectedIndex(oldFont.getStyle());
+
+        try
+        {
+            frame.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    void changeFont()
+    {
+      Font newFont = new Font(fontName.getSelectedItem().toString(),
+                              fontStyle.getSelectedIndex(),
+                              Integer.parseInt(fontSize.getSelectedItem().toString()));
+      if (ap != null)
+      {
+        ap.av.setFont(newFont);
+        ap.fontChanged();
+      }
+      else if(tp != null)
+      {
+        tp.setTreeFont(newFont);
+      }
+
+      FontMetrics fm = getGraphics().getFontMetrics(newFont);
+
+      monospaced.setSelected( fm.getStringBounds("M",getGraphics()).getWidth()
+                                ==fm.getStringBounds("|",getGraphics()).getWidth());
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void fontName_actionPerformed(ActionEvent e)
+    {
+        if (init)
+        {
+            return;
+        }
+
+        changeFont();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void fontSize_actionPerformed(ActionEvent e)
+    {
+        if (init)
+        {
+            return;
+        }
+
+        changeFont();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void fontStyle_actionPerformed(ActionEvent e)
+    {
+        if (init)
+        {
+            return;
+        }
+
+        changeFont();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void defaultButton_actionPerformed(ActionEvent e)
+    {
+        Cache.setProperty("FONT_NAME", fontName.getSelectedItem().toString());
+        Cache.setProperty("FONT_STYLE", fontStyle.getSelectedIndex() + "");
+        Cache.setProperty("FONT_SIZE", fontSize.getSelectedItem().toString());
+    }
+}
index 214f218..e7f554c 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-import java.awt.image.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class IdCanvas extends JPanel\r
-{\r
-    protected AlignViewport av;\r
-    protected boolean showScores = true;\r
-    protected int maxIdLength = -1;\r
-    protected String maxIdStr = null;\r
-    BufferedImage image;\r
-    Graphics2D gg;\r
-    int imgHeight = 0;\r
-    boolean fastPaint = false;\r
-    java.util.Vector searchResults;\r
-\r
-    /**\r
-     * Creates a new IdCanvas object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     */\r
-    public IdCanvas(AlignViewport av)\r
-    {\r
-        setLayout(new BorderLayout());\r
-        this.av = av;\r
-        PaintRefresher.Register(this, av.alignment);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param gg DOCUMENT ME!\r
-     * @param s DOCUMENT ME!\r
-     * @param i DOCUMENT ME!\r
-     * @param starty DOCUMENT ME!\r
-     * @param ypos DOCUMENT ME!\r
-     */\r
-    public void drawIdString(Graphics2D gg, SequenceI s, int i, int starty,\r
-        int ypos)\r
-    {\r
-        int charHeight = av.charHeight;\r
-\r
-        if ((searchResults != null) && searchResults.contains(s))\r
-        {\r
-            gg.setColor(Color.black);\r
-            gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
-                charHeight);\r
-            gg.setColor(Color.white);\r
-        }\r
-        else if ((av.getSelectionGroup() != null) &&\r
-                av.getSelectionGroup().sequences.contains(s))\r
-        {\r
-            gg.setColor(Color.lightGray);\r
-            gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
-                charHeight);\r
-            gg.setColor(Color.white);\r
-        }\r
-        else\r
-        {\r
-            gg.setColor(s.getColor());\r
-            gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
-                charHeight);\r
-            gg.setColor(Color.black);\r
-        }\r
-\r
-\r
-        gg.drawString( s.getDisplayId(av.getShowJVSuffix()),\r
-                      0, (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param vertical DOCUMENT ME!\r
-     */\r
-    public void fastPaint(int vertical)\r
-    {\r
-        if (gg == null)\r
-        {\r
-            repaint();\r
-\r
-            return;\r
-        }\r
-\r
-        gg.copyArea(0, 0, getWidth(), imgHeight, 0, -vertical * av.charHeight);\r
-\r
-        int ss = av.startSeq;\r
-        int es = av.endSeq;\r
-        int transY = 0;\r
-\r
-        if (vertical > 0) // scroll down\r
-        {\r
-            ss = es - vertical;\r
-\r
-            if (ss < av.startSeq)\r
-            { // ie scrolling too fast, more than a page at a time\r
-                ss = av.startSeq;\r
-            }\r
-            else\r
-            {\r
-                transY = imgHeight - (vertical * av.charHeight);\r
-            }\r
-        }\r
-        else if (vertical < 0)\r
-        {\r
-            es = ss - vertical;\r
-\r
-            if (es > av.endSeq)\r
-            {\r
-                es = av.endSeq;\r
-            }\r
-        }\r
-\r
-        gg.translate(0, transY);\r
-\r
-        drawIds(ss, es);\r
-\r
-        gg.translate(0, -transY);\r
-\r
-        fastPaint = true;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        g.setColor(Color.white);\r
-        g.fillRect(0, 0, getWidth(), getHeight());\r
-\r
-        if (fastPaint)\r
-        {\r
-            fastPaint = false;\r
-            g.drawImage(image, 0, 0, this);\r
-\r
-            return;\r
-        }\r
-\r
-        imgHeight = getHeight();\r
-        imgHeight -= (imgHeight % av.charHeight);\r
-\r
-        if (imgHeight < 1)\r
-        {\r
-            return;\r
-        }\r
-\r
-        image = new BufferedImage(getWidth(), imgHeight,\r
-                BufferedImage.TYPE_INT_RGB);\r
-        gg = (Graphics2D) image.getGraphics();\r
-\r
-        //Fill in the background\r
-        gg.setColor(Color.white);\r
-        gg.fillRect(0, 0, getWidth(), imgHeight);\r
-\r
-\r
-        drawIds(av.getStartSeq(), av.endSeq);\r
-\r
-        g.drawImage(image, 0, 0, this);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param starty DOCUMENT ME!\r
-     * @param endy DOCUMENT ME!\r
-     */\r
-    void drawIds(int starty, int endy)\r
-    {\r
-      Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
-                             av.getFont().getSize());\r
-      gg.setFont(italic);\r
-\r
-      if (av.antiAlias)\r
-        gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                            RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-        Color currentColor = Color.white;\r
-        Color currentTextColor = Color.black;\r
-\r
-        if (av.getWrapAlignment())\r
-        {\r
-          int annotationHeight = 0;\r
-          AnnotationLabels labels = null;\r
-\r
-          if(av.showAnnotation)\r
-          {\r
-            AnnotationPanel ap = new AnnotationPanel(av);\r
-            annotationHeight = ap.adjustPanelHeight();\r
-            labels = new AnnotationLabels(av);\r
-          }\r
-\r
-          int hgap = av.charHeight;\r
-          if (av.scaleAboveWrapped)\r
-            hgap += av.charHeight;\r
-\r
-          int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-              + hgap\r
-              + annotationHeight;\r
-\r
-            int rowSize = av.getEndRes() - av.getStartRes();\r
-\r
-            // Draw the rest of the panels\r
-            for (int ypos = hgap, row = av.startRes;\r
-                    (ypos <= getHeight()) && (row < av.alignment.getWidth());\r
-                    ypos += cHeight, row += rowSize)\r
-            {\r
-                for (int i = starty; i < av.alignment.getHeight(); i++)\r
-                {\r
-\r
-                    SequenceI s = av.alignment.getSequenceAt(i);\r
-                    gg.setFont(italic);\r
-                    drawIdString(gg, s, i, 0, ypos);\r
-                }\r
-\r
-                if(labels!=null)\r
-                {\r
-                  gg.translate(0, ypos+(av.getAlignment().getHeight() * av.charHeight));\r
-                  labels.drawComponent(gg, getWidth());\r
-                  gg.translate(0, -ypos-(av.getAlignment().getHeight() * av.charHeight));\r
-\r
-                }\r
-            }\r
-        }\r
-        else\r
-        {\r
-            //Now draw the id strings\r
-            int tmp, hiddenIndex = starty;\r
-            boolean markHidden = false;\r
-            for (int i = starty; i < endy; i++)\r
-            {\r
-              if (av.hasHiddenRows)\r
-              {\r
-                tmp = av.adjustForHiddenSeqs(i);\r
-                if(hiddenIndex != tmp)\r
-                {\r
-                    hiddenIndex = tmp;\r
-                    markHidden = true;\r
-                }\r
-                else\r
-                  markHidden = false;\r
-\r
-                hiddenIndex++;\r
-              }\r
-\r
-              if(av.hasHiddenRows && av.alignment.getSequenceAt(i).getHiddenSequences()!=null)\r
-              {\r
-                currentTextColor = Color.blue;\r
-              }\r
-              else\r
-                // Selected sequence colours\r
-                if ((searchResults != null) &&\r
-                        searchResults.contains(av.alignment.getSequenceAt(i)))\r
-                {\r
-                    currentColor = Color.black;\r
-                    currentTextColor = Color.white;\r
-                }\r
-                else if ((av.getSelectionGroup() != null) &&\r
-                        av.getSelectionGroup().sequences.contains(\r
-                            av.alignment.getSequenceAt(i)))\r
-                {\r
-                    currentColor = Color.lightGray;\r
-                    currentTextColor = Color.black;\r
-                }\r
-                else\r
-                {\r
-                    currentColor = av.alignment.getSequenceAt(i).getColor();\r
-                    currentTextColor = Color.black;\r
-                }\r
-\r
-                gg.setColor(currentColor);\r
-\r
-                gg.fillRect(0, (i - starty) * av.charHeight, getWidth(),\r
-                            av.charHeight);\r
-\r
-                if (markHidden)\r
-                {\r
-                  gg.setColor(Color.blue);\r
-               //   gg.drawLine(0, (i-starty)*av.charHeight, getWidth(),(i-starty)*av.charHeight);\r
-                  gg.fillPolygon(new int[] { getWidth() - av.charHeight,\r
-                                         getWidth() - av.charHeight,\r
-                                         getWidth() },\r
-                                new int[]\r
-                                {\r
-                                    (i-starty)*av.charHeight -av.charHeight/4,\r
-                                    (i-starty)*av.charHeight +av.charHeight/4,\r
-                                    (i-starty)*av.charHeight\r
-                                }, 3);\r
-\r
-                }\r
-\r
-                gg.setColor(currentTextColor);\r
-\r
-                String string = av.alignment.getSequenceAt(i).getDisplayId( av.getShowJVSuffix());\r
-\r
-                gg.drawString(string, 0,\r
-                    (((i - starty) * av.charHeight) + av.charHeight) -\r
-                    (av.charHeight / 5));\r
-            }\r
-\r
-            // add a border\r
-         //   gg.setColor(Color.cyan);\r
-          //  gg.fillRect(getWidth() - 4, 0, 4, getHeight());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param found DOCUMENT ME!\r
-     */\r
-    public void setHighlighted(java.util.Vector found)\r
-    {\r
-        searchResults = found;\r
-        repaint();\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+import java.awt.image.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdCanvas extends JPanel
+{
+    protected AlignViewport av;
+    protected boolean showScores = true;
+    protected int maxIdLength = -1;
+    protected String maxIdStr = null;
+    BufferedImage image;
+    Graphics2D gg;
+    int imgHeight = 0;
+    boolean fastPaint = false;
+    java.util.Vector searchResults;
+
+    /**
+     * Creates a new IdCanvas object.
+     *
+     * @param av DOCUMENT ME!
+     */
+    public IdCanvas(AlignViewport av)
+    {
+        setLayout(new BorderLayout());
+        this.av = av;
+        PaintRefresher.Register(this, av.alignment);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param gg DOCUMENT ME!
+     * @param s DOCUMENT ME!
+     * @param i DOCUMENT ME!
+     * @param starty DOCUMENT ME!
+     * @param ypos DOCUMENT ME!
+     */
+    public void drawIdString(Graphics2D gg, SequenceI s, int i, int starty, int ypos)
+    {
+        int charHeight = av.charHeight;
+
+        if ((searchResults != null) && searchResults.contains(s))
+        {
+            gg.setColor(Color.black);
+            gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
+                charHeight);
+            gg.setColor(Color.white);
+        }
+        else if ((av.getSelectionGroup() != null) &&
+                av.getSelectionGroup().getSequences(false).contains(s))
+        {
+            gg.setColor(Color.lightGray);
+            gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
+                charHeight);
+            gg.setColor(Color.white);
+        }
+        else
+        {
+            gg.setColor(s.getColor());
+            gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
+                charHeight);
+            gg.setColor(Color.black);
+        }
+
+
+        gg.drawString( s.getDisplayId(av.getShowJVSuffix()),
+                      0, (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));
+
+        if (av.hasHiddenRows && av.showHiddenMarkers)
+          drawMarker(i, starty, ypos);
+
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param vertical DOCUMENT ME!
+     */
+    public void fastPaint(int vertical)
+    {
+        if (gg == null)
+        {
+            repaint();
+
+            return;
+        }
+
+        gg.copyArea(0, 0, getWidth(), imgHeight, 0, -vertical * av.charHeight);
+
+        int ss = av.startSeq;
+        int es = av.endSeq;
+        int transY = 0;
+
+        if (vertical > 0) // scroll down
+        {
+            ss = es - vertical;
+
+            if (ss < av.startSeq)
+            { // ie scrolling too fast, more than a page at a time
+                ss = av.startSeq;
+            }
+            else
+            {
+                transY = imgHeight - (vertical * av.charHeight);
+            }
+        }
+        else if (vertical < 0)
+        {
+            es = ss - vertical;
+
+            if (es > av.endSeq)
+            {
+                es = av.endSeq;
+            }
+        }
+
+        gg.translate(0, transY);
+
+        drawIds(ss, es);
+
+        gg.translate(0, -transY);
+
+        fastPaint = true;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+        g.setColor(Color.white);
+        g.fillRect(0, 0, getWidth(), getHeight());
+
+        if (fastPaint)
+        {
+            fastPaint = false;
+            g.drawImage(image, 0, 0, this);
+
+            return;
+        }
+
+        int oldHeight = imgHeight;
+
+        imgHeight = getHeight();
+        imgHeight -= (imgHeight % av.charHeight);
+
+        if (imgHeight < 1)
+        {
+            return;
+        }
+
+        if(oldHeight!=imgHeight || image.getWidth(this)!=getWidth())
+        {
+          image = new BufferedImage(getWidth(), imgHeight,
+                                    BufferedImage.TYPE_INT_RGB);
+        }
+
+        gg = (Graphics2D) image.getGraphics();
+        //Fill in the background
+        gg.setColor(Color.white);
+        gg.fillRect(0, 0, getWidth(), imgHeight);
+
+        drawIds(av.getStartSeq(), av.endSeq);
+
+        g.drawImage(image, 0, 0, this);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param starty DOCUMENT ME!
+     * @param endy DOCUMENT ME!
+     */
+    void drawIds(int starty, int endy)
+    {
+      Font italic = new Font(av.getFont().getName(), Font.ITALIC,
+                             av.getFont().getSize());
+
+      gg.setFont(italic);
+
+      if (av.antiAlias)
+        gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                            RenderingHints.VALUE_ANTIALIAS_ON);
+
+        Color currentColor = Color.white;
+        Color currentTextColor = Color.black;
+
+        if (av.getWrapAlignment())
+        {
+          int maxwidth = av.alignment.getWidth();
+          int alheight = av.alignment.getHeight();
+
+          if (av.hasHiddenColumns)
+            maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+          int annotationHeight = 0;
+          AnnotationLabels labels = null;
+
+          if(av.showAnnotation)
+          {
+            AnnotationPanel ap = new AnnotationPanel(av);
+            annotationHeight = ap.adjustPanelHeight();
+            labels = new AnnotationLabels(av);
+          }
+
+          int hgap = av.charHeight;
+          if (av.scaleAboveWrapped)
+            hgap += av.charHeight;
+
+          int cHeight = alheight * av.charHeight
+              + hgap
+              + annotationHeight;
+
+          int rowSize = av.getEndRes() - av.getStartRes();
+
+
+            // Draw the rest of the panels
+            for (int ypos = hgap, row = av.startRes;
+                    (ypos <= getHeight()) && (row < maxwidth);
+                    ypos += cHeight, row += rowSize)
+            {
+              for (int i = starty; i < alheight; i++)
+              {
+                if (av.hasHiddenRows)
+                {
+                  setHiddenFont(i);
+                }
+                else
+                  gg.setFont(italic);
+
+                SequenceI s = av.alignment.getSequenceAt(i);
+                drawIdString(gg, s, i, 0, ypos);
+              }
+
+                if(labels!=null)
+                {
+                  gg.translate(0, ypos+(alheight * av.charHeight));
+                  labels.drawComponent(gg, getWidth());
+                  gg.translate(0, -ypos-(alheight * av.charHeight));
+                }
+
+
+            }
+        }
+        else
+        {
+          //Now draw the id strings
+
+            //Now draw the id strings
+            for (int i = starty; i < endy; i++)
+            {
+              if (av.hasHiddenRows)
+              {
+                setHiddenFont(i);
+              }
+
+                // Selected sequence colours
+                if ( (searchResults != null) &&
+                    searchResults.contains(av.alignment.getSequenceAt(i)))
+                {
+                  currentColor = Color.black;
+                  currentTextColor = Color.white;
+                }
+                else if ( (av.getSelectionGroup() != null) &&
+                         av.getSelectionGroup().getSequences(false).contains(
+                             av.alignment.getSequenceAt(i)))
+                {
+                  currentColor = Color.lightGray;
+                  currentTextColor = Color.black;
+                }
+                else
+                {
+                  currentColor = av.alignment.getSequenceAt(i).getColor();
+                  currentTextColor = Color.black;
+                }
+
+                gg.setColor(currentColor);
+
+                gg.fillRect(0, (i - starty) * av.charHeight, getWidth(),
+                            av.charHeight);
+
+                gg.setColor(currentTextColor);
+
+                String string = av.alignment.getSequenceAt(i).getDisplayId( av.getShowJVSuffix());
+
+                gg.drawString(string, 0,
+                    (((i - starty) * av.charHeight) + av.charHeight) -
+                    (av.charHeight / 5));
+
+               if(av.hasHiddenRows && av.showHiddenMarkers)
+                 drawMarker(i, starty, 0);
+
+            }
+
+        }
+    }
+
+    void drawMarker(int i, int starty, int yoffset)
+    {
+      int hiddenIndex = av.adjustForHiddenSeqs(i);
+      int lastIndex = av.adjustForHiddenSeqs(i - 1);
+      int nextIndex = av.adjustForHiddenSeqs(i + 1);
+
+      boolean below = (hiddenIndex > lastIndex + 1);
+      boolean above = (nextIndex>hiddenIndex+1);
+
+        gg.setColor(Color.blue);
+        if(below)
+        {
+          gg.fillPolygon(new int[]
+                         {getWidth()- av.charHeight,
+                         getWidth()- av.charHeight,
+                         getWidth()},
+                         new int[]
+                         {
+                         (i - starty) * av.charHeight +yoffset,
+                         (i - starty) * av.charHeight +yoffset+ av.charHeight / 4,
+                         (i - starty) * av.charHeight+yoffset
+          }, 3);
+        }
+        if(above)
+        {
+          gg.fillPolygon(new int[]
+                        {getWidth()- av.charHeight,
+                        getWidth()- av.charHeight,
+                        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);
+
+        }
+    }
+
+    void setHiddenFont(int i)
+    {
+      Font italic = new Font(av.getFont().getName(), Font.ITALIC,
+                             av.getFont().getSize());
+      Font bold = new Font(av.getFont().getName(), Font.BOLD,
+                           av.getFont().getSize());
+
+      if (av.alignment.getSequenceAt(i).getHiddenSequences() != null)
+        gg.setFont(bold);
+      else
+        gg.setFont(italic);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param found DOCUMENT ME!
+     */
+    public void setHighlighted(java.util.Vector found)
+    {
+        searchResults = found;
+        repaint();
+    }
+}
index cb13692..163265f 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class IdPanel extends JPanel implements MouseListener,\r
-    MouseMotionListener\r
-{\r
-    protected IdCanvas idCanvas;\r
-    protected AlignViewport av;\r
-    protected AlignmentPanel alignPanel;\r
-    ScrollThread scrollThread = null;\r
-    int offy;\r
-    int width;\r
-    int lastid = -1;\r
-    boolean mouseDragging = false;\r
-\r
-    /**\r
-     * Creates a new IdPanel object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     * @param parent DOCUMENT ME!\r
-     */\r
-    public IdPanel(AlignViewport av, AlignmentPanel parent)\r
-    {\r
-        this.av = av;\r
-        alignPanel = parent;\r
-        idCanvas = new IdCanvas(av);\r
-        setLayout(new BorderLayout());\r
-        add(idCanvas, BorderLayout.CENTER);\r
-        addMouseListener(this);\r
-        addMouseMotionListener(this);\r
-        ToolTipManager.sharedInstance().registerComponent(this);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseMoved(MouseEvent e)\r
-    {\r
-      int y = e.getY();\r
-\r
-      if (av.getWrapAlignment())\r
-      {\r
-        y = getWrappedY(y);\r
-      }\r
-\r
-      final int seq = av.getIndex(y);\r
-      if(seq!=-1)\r
-      {\r
-        StringBuffer tip = new StringBuffer("<html>");\r
-        tip.append(av.alignment.getSequenceAt(seq).getDisplayId(true));\r
-        if (av.alignment.getSequenceAt(seq).getDescription() != null)\r
-        {\r
-          tip.append("<table width=250 border=0><tr><td><i>");\r
-          tip.append(av.alignment.getSequenceAt(seq).getDescription());\r
-          tip.append("</i></td></tr></table>");\r
-        }\r
-        tip.append("</html>");\r
-        setToolTipText(tip.toString());\r
-      }\r
-\r
-      if(av.hasHiddenRows)\r
-      {\r
-        if(av.adjustForHiddenSeqs(seq) -\r
-           av.adjustForHiddenSeqs(seq-1)>1)\r
-        {\r
-          JPopupMenu pop = new JPopupMenu();\r
-          JMenuItem item = new JMenuItem("Reveal");\r
-          item.addActionListener(new ActionListener()\r
-          {\r
-            public void actionPerformed(ActionEvent e)\r
-            {\r
-              av.showSequence(seq);\r
-              alignPanel.repaint();\r
-              if(alignPanel.overviewPanel!=null)\r
-                alignPanel.overviewPanel.updateOverviewImage();\r
-            }\r
-          });\r
-          pop.add(item);\r
-          pop.show(this, e.getX(), e.getY());\r
-        }\r
-      }\r
-    }\r
-\r
-\r
-    int getWrappedY(int y)\r
-    {\r
-      int hgap = av.charHeight;\r
-      if (av.scaleAboveWrapped)\r
-        hgap += av.charHeight;\r
-\r
-      return y - hgap;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent e)\r
-    {\r
-        mouseDragging = true;\r
-\r
-        int y = e.getY();\r
-\r
-        if (av.getWrapAlignment())\r
-        {\r
-            y = getWrappedY(y);\r
-        }\r
-\r
-        int seq = av.getIndex(y);\r
-\r
-        if (seq < 0)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if (seq < lastid)\r
-        {\r
-            selectSeqs(lastid - 1, seq);\r
-        }\r
-        else if (seq > lastid)\r
-        {\r
-            selectSeqs(lastid + 1, seq);\r
-        }\r
-\r
-        lastid = seq;\r
-        alignPanel.repaint();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseClicked(MouseEvent e)\r
-    {\r
-      if (e.getClickCount() < 2)\r
-        return;\r
-\r
-      java.util.Vector links = Preferences.sequenceURLLinks;\r
-      if (links == null || links.size() < 1)\r
-        return;\r
-\r
-      int y = e.getY();\r
-\r
-      if (av.getWrapAlignment())\r
-      {\r
-         y = getWrappedY(y);\r
-      }\r
-\r
-      //DEFAULT LINK IS FIRST IN THE LINK LIST\r
-      int seq = av.getIndex(y);\r
-      if(seq==-1)\r
-        return;\r
-\r
-      String id = av.getAlignment().getSequenceAt(seq).getName();\r
-      if (id.indexOf("|") > -1)\r
-        id = id.substring(id.lastIndexOf("|") + 1);\r
-\r
-\r
-      String url = links.elementAt(0).toString();\r
-      url = url.substring(url.indexOf("|")+1);\r
-\r
-      int index = url.indexOf("$SEQUENCE_ID$");\r
-      url = url.substring(0, index)+ id + url.substring(index+13);\r
-\r
-      try\r
-      {\r
-        jalview.util.BrowserLauncher.openURL(url);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-       JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-           "Unixers: Couldn't find default web browser."\r
-          +"\nAdd the full path to your browser in Preferences.",\r
-          "Web browser not found", JOptionPane.WARNING_MESSAGE );\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent e)\r
-    {\r
-        if (scrollThread != null)\r
-        {\r
-            scrollThread.running = false;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent e)\r
-    {\r
-        if (av.getWrapAlignment())\r
-        {\r
-            return;\r
-        }\r
-\r
-        if (mouseDragging && (e.getY() < 0) && (av.getStartSeq() > 0))\r
-        {\r
-            scrollThread = new ScrollThread(true);\r
-        }\r
-\r
-        if (mouseDragging && (e.getY() >= getHeight()) &&\r
-                (av.alignment.getHeight() > av.getEndSeq()))\r
-        {\r
-            scrollThread = new ScrollThread(false);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent e)\r
-    {\r
-        if (e.getClickCount() == 2)\r
-        {\r
-            return;\r
-        }\r
-\r
-        int y = e.getY();\r
-\r
-        if (av.getWrapAlignment())\r
-        {\r
-            y = getWrappedY(y);\r
-        }\r
-\r
-        int seq = av.getIndex(y);\r
-\r
-        if (seq == -1)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if (javax.swing.SwingUtilities.isRightMouseButton(e))\r
-        {\r
-            jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(alignPanel,\r
-                    (Sequence) av.getAlignment().getSequenceAt(seq));\r
-            pop.show(this, e.getX(), y);\r
-\r
-            return;\r
-        }\r
-\r
-        if (!e.isControlDown() && !e.isShiftDown() &&\r
-                (av.alignment.findGroup(av.alignment.getSequenceAt(seq)) != null))\r
-        {\r
-            SequenceGroup selection = new SequenceGroup();\r
-            SequenceGroup sg = av.alignment.findGroup(av.alignment.getSequenceAt(\r
-                        seq));\r
-            selection.setStartRes(0);\r
-            selection.setEndRes(av.alignment.getWidth() - 1);\r
-\r
-            for (int i = 0; i < sg.getSize(); i++)\r
-            {\r
-                selection.addSequence(sg.getSequenceAt(i), true);\r
-            }\r
-\r
-            av.setSelectionGroup(selection);\r
-\r
-            return;\r
-        }\r
-\r
-        if ((av.getSelectionGroup() == null) ||\r
-                (!e.isControlDown() && (av.getSelectionGroup() != null)))\r
-        {\r
-            av.setSelectionGroup(new SequenceGroup());\r
-        }\r
-\r
-        av.getSelectionGroup().setStartRes(0);\r
-        av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);\r
-\r
-        if (e.isShiftDown() && (lastid != -1))\r
-        {\r
-            selectSeqs(lastid, seq);\r
-        }\r
-        else\r
-        {\r
-            selectSeq(seq);\r
-        }\r
-\r
-        alignPanel.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    void selectSeq(int seq)\r
-    {\r
-        lastid = seq;\r
-\r
-        SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);\r
-        av.getSelectionGroup().addOrRemove(pickedSeq, true);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     */\r
-    void selectSeqs(int start, int end)\r
-    {\r
-      if(av.getSelectionGroup()==null)\r
-            return;\r
-\r
-        lastid = start;\r
-\r
-        if (end < start)\r
-        {\r
-            int tmp = start;\r
-            start = end;\r
-            end = tmp;\r
-            lastid = end;\r
-        }\r
-\r
-        for (int i = start; i <= end; i++)\r
-        {\r
-          av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i),\r
-                true);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent e)\r
-    {\r
-        if (scrollThread != null)\r
-        {\r
-            scrollThread.running = false;\r
-        }\r
-\r
-        mouseDragging = false;\r
-        PaintRefresher.Refresh(av.alignment);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param found DOCUMENT ME!\r
-     */\r
-    public void highlightSearchResults(java.util.Vector found)\r
-    {\r
-        idCanvas.setHighlighted(found);\r
-\r
-        if (found == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        int index = av.alignment.findIndex((SequenceI) found.get(0));\r
-\r
-        // do we need to scroll the panel?\r
-        if ((av.getStartSeq() > index) || (av.getEndSeq() < index))\r
-        {\r
-            alignPanel.setScrollValues(av.getStartRes(), index);\r
-        }\r
-    }\r
-\r
-    // this class allows scrolling off the bottom of the visible alignment\r
-    class ScrollThread extends Thread\r
-    {\r
-        boolean running = false;\r
-        boolean up = true;\r
-\r
-        public ScrollThread(boolean up)\r
-        {\r
-            this.up = up;\r
-            start();\r
-        }\r
-\r
-        public void stopScrolling()\r
-        {\r
-            running = false;\r
-        }\r
-\r
-        public void run()\r
-        {\r
-            running = true;\r
-\r
-            while (running)\r
-            {\r
-                if (alignPanel.scrollUp(up))\r
-                {\r
-                    // scroll was ok, so add new sequence to selection\r
-                    int seq = av.getStartSeq();\r
-\r
-                    if (!up)\r
-                    {\r
-                        seq = av.getEndSeq();\r
-                    }\r
-\r
-                    if (seq < lastid)\r
-                    {\r
-                        selectSeqs(lastid - 1, seq);\r
-                    }\r
-                    else if (seq > lastid)\r
-                    {\r
-                        selectSeqs(lastid + 1, seq);\r
-                    }\r
-\r
-                    lastid = seq;\r
-                }\r
-                else\r
-                {\r
-                    running = false;\r
-                }\r
-\r
-                alignPanel.repaint();\r
-\r
-                try\r
-                {\r
-                    Thread.sleep(100);\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdPanel extends JPanel implements MouseListener,
+    MouseMotionListener
+{
+    protected IdCanvas idCanvas;
+    protected AlignViewport av;
+    protected AlignmentPanel alignPanel;
+    ScrollThread scrollThread = null;
+    int offy;
+    int width;
+    int lastid = -1;
+    boolean mouseDragging = false;
+
+    /**
+     * Creates a new IdPanel object.
+     *
+     * @param av DOCUMENT ME!
+     * @param parent DOCUMENT ME!
+     */
+    public IdPanel(AlignViewport av, AlignmentPanel parent)
+    {
+        this.av = av;
+        alignPanel = parent;
+        idCanvas = new IdCanvas(av);
+        setLayout(new BorderLayout());
+        add(idCanvas, BorderLayout.CENTER);
+        addMouseListener(this);
+        addMouseMotionListener(this);
+        ToolTipManager.sharedInstance().registerComponent(this);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));
+      if(seq>-1 && seq<av.alignment.getHeight())
+      {
+        SequenceI sequence = av.alignment.getSequenceAt(seq);
+        StringBuffer tip = new StringBuffer("<html>");
+        tip.append(sequence.getDisplayId(true));
+        if (av.alignment.getSequenceAt(seq).getDescription() != null)
+        {
+          tip.append("<table width=250 border=0><tr><td><i>");
+          tip.append(av.alignment.getSequenceAt(seq).getDescription());
+
+          //ADD NON POSITIONAL SEQUENCE INFO
+          SequenceFeature [] features = sequence.getDatasetSequence().getSequenceFeatures();
+          if(features!=null)
+          {
+            for(int i=0; i<features.length; i++)
+            {
+              if(features[i].begin == 0 && features[i].end ==0)
+              {
+                tip.append("<br>"+features[i].featureGroup
+                          +" "+ features[i].getType()+" "+features[i].description);
+              }
+            }
+          }
+          tip.append("</i></td></tr></table>");
+        }
+
+        DBRefEntry[] dbrefs = sequence.getDatasetSequence().getDBRef();
+        if (dbrefs != null)
+        {
+          tip.append("<i>");
+          for (int i = 0; i < dbrefs.length; i++)
+          {
+            tip.append("<br>");
+            tip.append(dbrefs[i].getSource() + " "
+                       + dbrefs[i].getAccessionId());
+          }
+          tip.append("</i>");
+        }
+
+        tip.append("</html>");
+        setToolTipText(tip.toString());
+      }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+        mouseDragging = true;
+
+        int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));
+
+        if (seq < lastid)
+        {
+            selectSeqs(lastid - 1, seq);
+        }
+        else if (seq > lastid)
+        {
+            selectSeqs(lastid + 1, seq);
+        }
+
+        lastid = seq;
+        alignPanel.repaint();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      if (e.getClickCount() < 2)
+        return;
+
+      java.util.Vector links = Preferences.sequenceURLLinks;
+      if (links == null || links.size() < 1)
+        return;
+
+      int seq = alignPanel.seqPanel.findSeq(e);
+
+      //DEFAULT LINK IS FIRST IN THE LINK LIST
+
+      String id = av.getAlignment().getSequenceAt(seq).getName();
+      if (id.indexOf("|") > -1)
+        id = id.substring(id.lastIndexOf("|") + 1);
+
+
+      String url = links.elementAt(0).toString();
+      url = url.substring(url.indexOf("|")+1);
+
+      int index = url.indexOf("$SEQUENCE_ID$");
+      url = url.substring(0, index)+ id + url.substring(index+13);
+
+      try
+      {
+        jalview.util.BrowserLauncher.openURL(url);
+      }
+      catch (Exception ex)
+      {
+       JOptionPane.showInternalMessageDialog(Desktop.desktop,
+           "Unixers: Couldn't find default web browser."
+          +"\nAdd the full path to your browser in Preferences.",
+          "Web browser not found", JOptionPane.WARNING_MESSAGE );
+        ex.printStackTrace();
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+        if (scrollThread != null)
+        {
+            scrollThread.running = false;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent e)
+    {
+        if (av.getWrapAlignment())
+        {
+            return;
+        }
+
+        if (mouseDragging && (e.getY() < 0) && (av.getStartSeq() > 0))
+        {
+            scrollThread = new ScrollThread(true);
+        }
+
+        if (mouseDragging && (e.getY() >= getHeight()) &&
+                (av.alignment.getHeight() > av.getEndSeq()))
+        {
+            scrollThread = new ScrollThread(false);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent e)
+    {
+        if (e.getClickCount() == 2)
+        {
+            return;
+        }
+
+        int seq = alignPanel.seqPanel.findSeq(e);
+
+
+        if (javax.swing.SwingUtilities.isRightMouseButton(e))
+        {
+            jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(alignPanel,
+                    (Sequence) av.getAlignment().getSequenceAt(seq),
+                    Preferences.sequenceURLLinks);
+            pop.show(this, e.getX(), e.getY());
+
+            return;
+        }
+
+
+
+        if ((av.getSelectionGroup() == null) ||
+                ((!e.isControlDown() && !e.isShiftDown()) && av.getSelectionGroup() != null))
+        {
+          av.setSelectionGroup(new SequenceGroup());
+          av.getSelectionGroup().setStartRes(0);
+          av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);
+        }
+
+
+        if (e.isShiftDown() && (lastid != -1))
+        {
+            selectSeqs(lastid, seq);
+        }
+        else
+        {
+            selectSeq(seq);
+        }
+
+        alignPanel.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     */
+    void selectSeq(int seq)
+    {
+        lastid = seq;
+
+        SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);
+        av.getSelectionGroup().addOrRemove(pickedSeq, true);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     */
+    void selectSeqs(int start, int end)
+    {
+      if(av.getSelectionGroup()==null)
+            return;
+
+        lastid = start;
+
+        if (end < start)
+        {
+            int tmp = start;
+            start = end;
+            end = tmp;
+            lastid = end;
+        }
+
+        for (int i = start; i <= end; i++)
+        {
+          av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i),
+                true);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+        if (scrollThread != null)
+        {
+            scrollThread.running = false;
+        }
+
+        mouseDragging = false;
+        PaintRefresher.Refresh(av.alignment);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param found DOCUMENT ME!
+     */
+    public void highlightSearchResults(java.util.Vector found)
+    {
+        idCanvas.setHighlighted(found);
+
+        if (found == null)
+        {
+            return;
+        }
+
+        int index = av.alignment.findIndex((SequenceI) found.get(0));
+
+        // do we need to scroll the panel?
+        if ((av.getStartSeq() > index) || (av.getEndSeq() < index))
+        {
+            alignPanel.setScrollValues(av.getStartRes(), index);
+        }
+    }
+
+    // this class allows scrolling off the bottom of the visible alignment
+    class ScrollThread extends Thread
+    {
+        boolean running = false;
+        boolean up = true;
+
+        public ScrollThread(boolean up)
+        {
+            this.up = up;
+            start();
+        }
+
+        public void stopScrolling()
+        {
+            running = false;
+        }
+
+        public void run()
+        {
+            running = true;
+
+            while (running)
+            {
+                if (alignPanel.scrollUp(up))
+                {
+                    // scroll was ok, so add new sequence to selection
+                    int seq = av.getStartSeq();
+
+                    if (!up)
+                    {
+                        seq = av.getEndSeq();
+                    }
+
+                    if (seq < lastid)
+                    {
+                        selectSeqs(lastid - 1, seq);
+                    }
+                    else if (seq > lastid)
+                    {
+                        selectSeqs(lastid + 1, seq);
+                    }
+
+                    lastid = seq;
+                }
+                else
+                {
+                    running = false;
+                }
+
+                alignPanel.repaint();
+
+                try
+                {
+                    Thread.sleep(100);
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+        }
+    }
+}
index 1fc524a..de9f2fc 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class IdwidthAdjuster extends JPanel implements MouseListener,\r
-    MouseMotionListener\r
-{\r
-    boolean active = false;\r
-    int oldX = 0;\r
-    Image image;\r
-    AlignmentPanel ap;\r
-\r
-    /**\r
-     * Creates a new IdwidthAdjuster object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     */\r
-    public IdwidthAdjuster(AlignmentPanel ap)\r
-    {\r
-        this.ap = ap;\r
-\r
-        java.net.URL url = getClass().getResource("/images/idwidth.gif");\r
-\r
-        if (url != null)\r
-        {\r
-            image = java.awt.Toolkit.getDefaultToolkit().createImage(url);\r
-        }\r
-\r
-        addMouseListener(this);\r
-        addMouseMotionListener(this);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent evt)\r
-    {\r
-        oldX = evt.getX();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-        active = false;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent evt)\r
-    {\r
-        active = true;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent evt)\r
-    {\r
-        active = false;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-        active = true;\r
-\r
-        Dimension d = ap.idPanel.idCanvas.getPreferredSize();\r
-        int dif = evt.getX() - oldX;\r
-\r
-        if (((d.width + dif) > 20) || (dif > 0))\r
-        {\r
-            ap.idPanel.idCanvas.setPreferredSize(new Dimension(d.width + dif,\r
-                    d.height));\r
-            ap.repaint();\r
-        }\r
-\r
-        oldX = evt.getX();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseMoved(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseClicked(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        g.setColor(Color.white);\r
-        g.fillRect(0, 0, getWidth(), getHeight());\r
-\r
-        if (active)\r
-        {\r
-            if (image != null)\r
-            {\r
-                g.drawImage(image, getWidth() - 20, 2, this);\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdwidthAdjuster extends JPanel implements MouseListener,
+    MouseMotionListener
+{
+    boolean active = false;
+    int oldX = 0;
+    Image image;
+    AlignmentPanel ap;
+
+    /**
+     * Creates a new IdwidthAdjuster object.
+     *
+     * @param ap DOCUMENT ME!
+     */
+    public IdwidthAdjuster(AlignmentPanel ap)
+    {
+        this.ap = ap;
+
+        java.net.URL url = getClass().getResource("/images/idwidth.gif");
+
+        if (url != null)
+        {
+            image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
+        }
+
+        addMouseListener(this);
+        addMouseMotionListener(this);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent evt)
+    {
+        oldX = evt.getX();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent evt)
+    {
+        active = false;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent evt)
+    {
+        active = true;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent evt)
+    {
+        active = false;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent evt)
+    {
+        active = true;
+
+        Dimension d = ap.idPanel.idCanvas.getPreferredSize();
+        int dif = evt.getX() - oldX;
+
+        if (((d.width + dif) > 20) || (dif > 0))
+        {
+            ap.idPanel.idCanvas.setPreferredSize(new Dimension(d.width + dif,
+                    d.height));
+            ap.repaint();
+        }
+
+        oldX = evt.getX();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseMoved(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseClicked(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+        g.setColor(Color.white);
+        g.fillRect(0, 0, getWidth(), getHeight());
+
+        if (active)
+        {
+            if (image != null)
+            {
+                g.drawImage(image, getWidth() - 20, 2, this);
+            }
+        }
+    }
+}
index 893846c..be03a9c 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.io.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.io.*;\r
-\r
-import java.net.*;\r
-\r
-import java.util.*;\r
-\r
-import java.util.jar.*;\r
-\r
-import javax.swing.*;\r
-\r
-import jalview.binding.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Jalview2XML\r
-{\r
-    // SAVES SEVERAL ALIGNEMENT WINDOWS TO SAME JARFILE\r
-    public static void SaveState(File statefile)\r
-    {\r
-        long creation = System.currentTimeMillis();\r
-        JInternalFrame[] frames = Desktop.desktop.getAllFrames();\r
-\r
-        if (frames == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        try\r
-        {\r
-            FileOutputStream fos = new FileOutputStream(statefile);\r
-            JarOutputStream jout = new JarOutputStream(fos);\r
-\r
-            //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS\r
-            ////////////////////////////////////////////////////\r
-            PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,\r
-                        "UTF-8"));\r
-\r
-            Vector shortNames = new Vector();\r
-\r
-            //REVERSE ORDER\r
-            for (int i = frames.length - 1; i > -1; i--)\r
-            {\r
-                if (frames[i] instanceof AlignFrame)\r
-                {\r
-                    AlignFrame af = (AlignFrame) frames[i];\r
-\r
-                    String shortName = af.getTitle();\r
-\r
-                    if (shortName.indexOf(File.separatorChar) > -1)\r
-                    {\r
-                        shortName = shortName.substring(shortName.lastIndexOf(\r
-                                    File.separatorChar) + 1);\r
-                    }\r
-\r
-                    int count = 1;\r
-\r
-                    while (shortNames.contains(shortName))\r
-                    {\r
-                        if (shortName.endsWith("_" + (count - 1)))\r
-                        {\r
-                            shortName = shortName.substring(0,\r
-                                    shortName.lastIndexOf("_"));\r
-                        }\r
-\r
-                        shortName = shortName.concat("_" + count);\r
-                        count++;\r
-                    }\r
-\r
-                    shortNames.addElement(shortName);\r
-\r
-                    if (!shortName.endsWith(".xml"))\r
-                    {\r
-                        shortName = shortName + ".xml";\r
-                    }\r
-\r
-                    SaveState(af, creation, shortName, jout, out);\r
-                }\r
-            }\r
-\r
-            out.close();\r
-            jout.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW\r
-    public static void SaveAlignment(AlignFrame af, String jarFile,\r
-        String fileName)\r
-    {\r
-        try\r
-        {\r
-            FileOutputStream fos = new FileOutputStream(jarFile);\r
-            JarOutputStream jout = new JarOutputStream(fos);\r
-\r
-            //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS\r
-            ////////////////////////////////////////////////////\r
-            PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,\r
-                        "UTF-8"));\r
-\r
-            SaveState(af, System.currentTimeMillis(), fileName, jout, out);\r
-            out.close();\r
-            jout.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param af DOCUMENT ME!\r
-     * @param timeStamp DOCUMENT ME!\r
-     * @param fileName DOCUMENT ME!\r
-     * @param jout DOCUMENT ME!\r
-     * @param out DOCUMENT ME!\r
-     */\r
-    public static void SaveState(AlignFrame af, long timeStamp,\r
-        String fileName, JarOutputStream jout, PrintWriter out)\r
-    {\r
-        Vector seqids = new Vector();\r
-        Vector userColours = new Vector();\r
-\r
-        AlignViewport av = af.viewport;\r
-\r
-        JalviewModel object = new JalviewModel();\r
-        object.setVamsasModel(new jalview.binding.VamsasModel());\r
-\r
-        object.setCreationDate(new java.util.Date(timeStamp));\r
-        object.setVersion(jalview.bin.Cache.getProperty("VERSION"));\r
-\r
-        jalview.datamodel.AlignmentI jal = af.viewport.alignment;\r
-\r
-        SequenceSet vamsasSet = new SequenceSet();\r
-        Sequence vamsasSeq;\r
-        JalviewModelSequence jms = new JalviewModelSequence();\r
-\r
-        vamsasSet.setGapChar(jal.getGapCharacter() + "");\r
-\r
-        JSeq jseq;\r
-\r
-        //SAVE SEQUENCES\r
-        int id = 0;\r
-\r
-        for (int i = 0; i < jal.getHeight(); i++)\r
-        {\r
-            seqids.add(jal.getSequenceAt(i));\r
-\r
-            vamsasSeq = new Sequence();\r
-            vamsasSeq.setId(id + "");\r
-            vamsasSeq.setName(jal.getSequenceAt(i).getName());\r
-            vamsasSeq.setSequence(jal.getSequenceAt(i).getSequence());\r
-            vamsasSeq.setDescription(jal.getSequenceAt(i).getDescription());\r
-\r
-            jseq = new JSeq();\r
-            jseq.setStart(jal.getSequenceAt(i).getStart());\r
-            jseq.setEnd(jal.getSequenceAt(i).getEnd());\r
-\r
-            jseq.setColour(jal.getSequenceAt(i).getColor().getRGB());\r
-\r
-            jseq.setId(id);\r
-\r
-            if(jal.getSequenceAt(i).getDatasetSequence().getSequenceFeatures()!=null)\r
-            {\r
-              jalview.datamodel.SequenceFeature[] sf\r
-                  = jal.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
-              int index = 0;\r
-              while(index < sf.length)\r
-              {\r
-                Features features = new Features();\r
-\r
-                features.setBegin(sf[index].getBegin());\r
-                features.setEnd(sf[index].getEnd());\r
-                features.setDescription(sf[index].getDescription());\r
-                features.setStatus(sf[index].getStatus());\r
-                features.setType(sf[index].getType());\r
-                features.setFeatureGroup(sf[index].getFeatureGroup());\r
-                jseq.addFeatures(features);\r
-                index ++;\r
-              }\r
-            }\r
-\r
-            if(jal.getSequenceAt(i).getDatasetSequence().getPDBId()!=null)\r
-            {\r
-              Enumeration en = jal.getSequenceAt(i).getDatasetSequence().getPDBId().elements();\r
-              while(en.hasMoreElements())\r
-              {\r
-                Pdbids pdb = new Pdbids();\r
-                jalview.datamodel.PDBEntry entry\r
-                   = (jalview.datamodel.PDBEntry)en.nextElement();\r
-\r
-                pdb.setId(entry.getId());\r
-                pdb.setType(entry.getType());\r
-\r
-                if(entry.getProperty()!=null)\r
-                {\r
-                  PdbentryItem item = new PdbentryItem();\r
-                  Hashtable properties = entry.getProperty();\r
-                  Enumeration en2 = properties.keys();\r
-                  while(en2.hasMoreElements())\r
-                  {\r
-                    Property prop = new Property();\r
-                    String key = en2.nextElement().toString();\r
-                    prop.setName(key);\r
-                    prop.setValue( properties.get(key).toString() );\r
-                    item.addProperty(prop);\r
-                  }\r
-                  pdb.addPdbentryItem(item);\r
-                }\r
-\r
-                jseq.addPdbids(pdb);\r
-              }\r
-            }\r
-\r
-            jms.addJSeq(jseq);\r
-            vamsasSet.addSequence(vamsasSeq);\r
-            id++;\r
-        }\r
-\r
-        //SAVE TREES\r
-        ///////////////////////////////////\r
-        if (af.viewport.currentTree != null)\r
-        {\r
-          // FIND ANY ASSOCIATED TREES\r
-          // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT\r
-          if (Desktop.desktop != null)\r
-          {\r
-            JInternalFrame[] frames = Desktop.desktop.getAllFrames();\r
-\r
-            for (int t = 0; t < frames.length; t++)\r
-            {\r
-              if (frames[t] instanceof TreePanel)\r
-              {\r
-                TreePanel tp = (TreePanel) frames[t];\r
-\r
-                if (tp.treeCanvas.av.alignment == jal)\r
-                {\r
-                  Tree tree = new Tree();\r
-                  tree.setTitle(tp.getTitle());\r
-                  tree.setCurrentTree( (af.viewport.currentTree == tp.getTree()));\r
-                  tree.setNewick(tp.getTree().toString());\r
-                  tree.setThreshold(tp.treeCanvas.threshold);\r
-\r
-                  tree.setFitToWindow(tp.fitToWindow.getState());\r
-                  tree.setFontName(tp.getTreeFont().getName());\r
-                  tree.setFontSize(tp.getTreeFont().getSize());\r
-                  tree.setFontStyle(tp.getTreeFont().getStyle());\r
-                  tree.setMarkUnlinked(tp.placeholdersMenu.getState());\r
-\r
-                  tree.setShowBootstrap(tp.bootstrapMenu.getState());\r
-                  tree.setShowDistances(tp.distanceMenu.getState());\r
-\r
-                  tree.setHeight(tp.getHeight());\r
-                  tree.setWidth(tp.getWidth());\r
-                  tree.setXpos(tp.getX());\r
-                  tree.setYpos(tp.getY());\r
-\r
-                  jms.addTree(tree);\r
-                }\r
-              }\r
-            }\r
-          }\r
-        }\r
-\r
-        //SAVE ANNOTATIONS\r
-        if (jal.getAlignmentAnnotation() != null)\r
-        {\r
-            jalview.datamodel.AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();\r
-\r
-            for (int i = 0; i < aa.length; i++)\r
-            {\r
-                if (aa[i].label.equals("Quality") ||\r
-                        aa[i].label.equals("Conservation") ||\r
-                        aa[i].label.equals("Consensus"))\r
-                {\r
-                    continue;\r
-                }\r
-\r
-                Annotation an = new Annotation();\r
-                an.setDescription(aa[i].description);\r
-                if(aa[i].graph>0)\r
-                {\r
-                  an.setGraph(true);\r
-                  an.setGraphType(aa[i].graph);\r
-                }\r
-                an.setLabel(aa[i].label);\r
-\r
-                AnnotationElement ae;\r
-\r
-                for (int a = 0; a < aa[i].annotations.length; a++)\r
-                {\r
-                    if ((aa[i] == null) || (aa[i].annotations[a] == null))\r
-                    {\r
-                        continue;\r
-                    }\r
-\r
-                    ae = new AnnotationElement();\r
-                    ae.setDescription(aa[i].annotations[a].description);\r
-                    ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);\r
-                    ae.setValue(aa[i].annotations[a].value);\r
-                    ae.setPosition(a);\r
-                    ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure +\r
-                        "");\r
-                    an.addAnnotationElement(ae);\r
-                }\r
-\r
-                vamsasSet.addAnnotation(an);\r
-            }\r
-        }\r
-\r
-        //SAVE GROUPS\r
-        if (jal.getGroups() != null)\r
-        {\r
-            JGroup[] groups = new JGroup[jal.getGroups().size()];\r
-\r
-            for (int i = 0; i < groups.length; i++)\r
-            {\r
-                groups[i] = new JGroup();\r
-\r
-                jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal.getGroups()\r
-                                                                                          .elementAt(i);\r
-                groups[i].setStart(sg.getStartRes());\r
-                groups[i].setEnd(sg.getEndRes());\r
-                groups[i].setName(sg.getName());\r
-                if(sg.cs!=null)\r
-                {\r
-                  if (sg.cs.conservationApplied())\r
-                  {\r
-                    groups[i].setConsThreshold(sg.cs.getConservationInc());\r
-\r
-                    if (sg.cs instanceof jalview.schemes.UserColourScheme)\r
-                    {\r
-                      groups[i].setColour(SetUserColourScheme(sg.cs,\r
-                          userColours,\r
-                          jms));\r
-                    }\r
-                    else\r
-                    {\r
-                      groups[i].setColour(ColourSchemeProperty.getColourName(sg.\r
-                          cs));\r
-                    }\r
-                  }\r
-                  else if (sg.cs instanceof jalview.schemes.UserColourScheme)\r
-                  {\r
-                    groups[i].setColour(SetUserColourScheme(sg.cs, userColours,\r
-                        jms));\r
-                  }\r
-                  else\r
-                  {\r
-                    groups[i].setColour(ColourSchemeProperty.getColourName(\r
-                        sg.cs));\r
-                  }\r
-\r
-                  groups[i].setPidThreshold(sg.cs.getThreshold());\r
-                }\r
-\r
-                groups[i].setOutlineColour(sg.getOutlineColour().getRGB());\r
-                groups[i].setDisplayBoxes(sg.getDisplayBoxes());\r
-                groups[i].setDisplayText(sg.getDisplayText());\r
-                groups[i].setColourText(sg.getColourText());\r
-\r
-                for (int s = 0; s < sg.getSize(); s++)\r
-                {\r
-                    jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg.getSequenceAt(s);\r
-                    int index = seqids.indexOf(seq);\r
-                    groups[i].addSeq(index);\r
-                }\r
-            }\r
-\r
-            jms.setJGroup(groups);\r
-        }\r
-\r
-\r
-        ///////////SAVE VIEWPORT\r
-        Viewport view = new Viewport();\r
-        view.setTitle(af.getTitle());\r
-        view.setXpos(af.getX());\r
-        view.setYpos(af.getY());\r
-        view.setWidth(af.getWidth());\r
-        view.setHeight(af.getHeight());\r
-        view.setStartRes(av.startRes);\r
-        view.setStartSeq(av.startSeq);\r
-\r
-        if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)\r
-        {\r
-            view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),\r
-                    userColours, jms));\r
-        }\r
-        else\r
-        {\r
-            view.setBgColour(ColourSchemeProperty.getColourName(\r
-                    av.getGlobalColourScheme()));\r
-        }\r
-\r
-        ColourSchemeI cs = av.getGlobalColourScheme();\r
-\r
-        if(cs!=null)\r
-        {\r
-          if (cs.conservationApplied())\r
-          {\r
-            view.setConsThreshold(cs.getConservationInc());\r
-            if (cs instanceof jalview.schemes.UserColourScheme)\r
-              view.setBgColour(SetUserColourScheme(cs, userColours, jms));\r
-          }\r
-\r
-          if (cs instanceof ResidueColourScheme)\r
-          {\r
-            view.setPidThreshold(cs.getThreshold());\r
-          }\r
-        }\r
-\r
-        view.setConservationSelected(av.getConservationSelected());\r
-        view.setPidSelected(av.getAbovePIDThreshold());\r
-        view.setFontName(av.font.getName());\r
-        view.setFontSize(av.font.getSize());\r
-        view.setFontStyle(av.font.getStyle());\r
-        view.setRenderGaps(av.renderGaps);\r
-        view.setShowAnnotation(av.getShowAnnotation());\r
-        view.setShowBoxes(av.getShowBoxes());\r
-        view.setShowColourText(av.getColourText());\r
-        view.setShowConservation(av.showConservation);\r
-        view.setShowFullId(av.getShowJVSuffix());\r
-        view.setShowIdentity(av.showIdentity);\r
-        view.setShowQuality(av.showQuality);\r
-        view.setShowSequenceFeatures(av.showSequenceFeatures);\r
-        view.setShowText(av.getShowText());\r
-        view.setWrapAlignment(av.getWrapAlignment());\r
-\r
-        if(av.featuresDisplayed!=null)\r
-        {\r
-          jalview.binding.FeatureSettings fs = new jalview.binding.FeatureSettings();\r
-\r
-          Enumeration e = af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureColours.keys();\r
-          while (e.hasMoreElements())\r
-          {\r
-            String type = e.nextElement().toString();\r
-            Setting setting = new Setting();\r
-            setting.setType(type);\r
-            setting.setColour(\r
-                af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().getColour(type).getRGB()\r
-                );\r
-\r
-            setting.setDisplay(\r
-                av.featuresDisplayed.containsKey(type)\r
-                );\r
-\r
-            fs.addSetting(setting);\r
-\r
-          }\r
-          jms.setFeatureSettings(fs);\r
-\r
-        }\r
-\r
-        jms.addViewport(view);\r
-\r
-\r
-        object.setJalviewModelSequence(jms);\r
-        object.getVamsasModel().addSequenceSet(vamsasSet);\r
-\r
-        try\r
-        {\r
-            if (!fileName.endsWith(".xml"))\r
-            {\r
-                fileName = fileName + ".xml";\r
-            }\r
-\r
-            JarEntry entry = new JarEntry(fileName);\r
-            jout.putNextEntry(entry);\r
-\r
-            object.marshal(out);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    static String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,\r
-        Vector userColours, JalviewModelSequence jms)\r
-    {\r
-        String id = null;\r
-        jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;\r
-\r
-        if (!userColours.contains(ucs))\r
-        {\r
-            userColours.add(ucs);\r
-\r
-            java.awt.Color[] colours = ucs.getColours();\r
-            jalview.binding.UserColours uc = new jalview.binding.UserColours();\r
-            jalview.binding.UserColourScheme jbucs = new jalview.binding.UserColourScheme();\r
-\r
-            for (int i = 0; i < colours.length; i++)\r
-            {\r
-                jalview.binding.Colour col = new jalview.binding.Colour();\r
-                col.setRGB(jalview.util.Format.getHexString(colours[i]));\r
-                jbucs.addColour(col);\r
-            }\r
-\r
-            id = "ucs" + userColours.indexOf(ucs);\r
-            uc.setId(id);\r
-            uc.setUserColourScheme(jbucs);\r
-            jms.addUserColours(uc);\r
-        }\r
-\r
-        return id;\r
-    }\r
-\r
-    static jalview.schemes.UserColourScheme GetUserColourScheme(\r
-        JalviewModelSequence jms, String id)\r
-    {\r
-        UserColours[] uc = jms.getUserColours();\r
-        UserColours colours = null;\r
-\r
-        for (int i = 0; i < uc.length; i++)\r
-        {\r
-            if (uc[i].getId().equals(id))\r
-            {\r
-                colours = uc[i];\r
-\r
-                break;\r
-            }\r
-        }\r
-\r
-        int csize = colours.getUserColourScheme().getColourCount();\r
-        java.awt.Color[] newColours = new java.awt.Color[csize];\r
-\r
-        for (int i = 0; i < csize; i++)\r
-        {\r
-            newColours[i] = new java.awt.Color(Integer.parseInt(\r
-                        colours.getUserColourScheme().getColour(i).getRGB(), 16));\r
-        }\r
-\r
-        return new jalview.schemes.UserColourScheme(newColours);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param file DOCUMENT ME!\r
-     */\r
-    public static AlignFrame LoadJalviewAlign(String file)\r
-    {\r
-        JalviewModel object = new JalviewModel();\r
-        jalview.gui.AlignFrame af = null;\r
-\r
-        try\r
-        {\r
-            //UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING\r
-            URL url = null;\r
-\r
-            if (file.startsWith("http://"))\r
-            {\r
-                url = new URL(file);\r
-            }\r
-\r
-            JarInputStream jin = null;\r
-            JarEntry jarentry = null;\r
-            int entryCount = 1;\r
-\r
-            do\r
-            {\r
-                if (url != null)\r
-                {\r
-                    jin = new JarInputStream(url.openStream());\r
-                }\r
-                else\r
-                {\r
-                    jin = new JarInputStream(new FileInputStream(file));\r
-                }\r
-\r
-                for (int i = 0; i < entryCount; i++)\r
-                {\r
-                    jarentry = jin.getNextJarEntry();\r
-                }\r
-\r
-                if (jarentry != null)\r
-                {\r
-                    InputStreamReader in = new InputStreamReader(jin, "UTF-8");\r
-                    object = (JalviewModel) object.unmarshal(in);\r
-                    af = LoadFromObject(object);\r
-                    entryCount++;\r
-                }\r
-            }\r
-            while (jarentry != null);\r
-        }\r
-        catch(java.net.UnknownHostException ex)\r
-        {\r
-          ex.printStackTrace();\r
-          System.err.println("Couldn't locate Jalview XML file : " +\r
-              ex + "\n");\r
-           JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                    "Couldn't locate " + file,\r
-                                    "URL not found",\r
-                                    JOptionPane.WARNING_MESSAGE);\r
-\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          ex.printStackTrace();\r
-            System.err.println("Exception whilst loading jalview XML file : " +\r
-                ex + "\n");\r
-             JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                      "Error loading  " + file,\r
-                                      "Error loading Jalview file",\r
-                                      JOptionPane.WARNING_MESSAGE);\r
-\r
-        }\r
-\r
-        return af;\r
-    }\r
-\r
-    static AlignFrame LoadFromObject(JalviewModel object)\r
-    {\r
-        Vector seqids = new Vector();\r
-        SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);\r
-        Sequence[] vamsasSeq = vamsasSet.getSequence();\r
-\r
-        JalviewModelSequence jms = object.getJalviewModelSequence();\r
-\r
-        //////////////////////////////////\r
-        //LOAD SEQUENCES\r
-        jalview.datamodel.Sequence[] jseqs = new jalview.datamodel.Sequence[vamsasSeq.length];\r
-        JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();\r
-        for (int i = 0; i < vamsasSeq.length; i++)\r
-        {\r
-            jseqs[i] = new jalview.datamodel.Sequence(vamsasSeq[i].getName(),\r
-                    vamsasSeq[i].getSequence());\r
-            jseqs[i].setDescription( vamsasSeq[i].getDescription() );\r
-\r
-            jseqs[i].setStart(JSEQ[i].getStart());\r
-            jseqs[i].setEnd(JSEQ[i].getEnd());\r
-            jseqs[i].setColor(new java.awt.Color(JSEQ[i].getColour()));\r
-            seqids.add(jseqs[i]);\r
-        }\r
-\r
-        ///SequenceFeatures are added to the DatasetSequence,\r
-        // so we must create the dataset before loading features\r
-        /////////////////////////////////\r
-        jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(jseqs);\r
-        al.setDataset(null);\r
-        /////////////////////////////////\r
-\r
-        for (int i = 0; i < vamsasSeq.length; i++)\r
-        {\r
-          if (JSEQ[i].getFeaturesCount() > 0)\r
-          {\r
-            Features[] features = JSEQ[i].getFeatures();\r
-            for (int f = 0; f < features.length; f++)\r
-            {\r
-              jalview.datamodel.SequenceFeature sf\r
-                  = new jalview.datamodel.SequenceFeature(features[f].getType(),\r
-                  features[f].getDescription(), features[f].getStatus(),\r
-                  features[f].getBegin(), features[f].getEnd(),\r
-                  features[f].getFeatureGroup());\r
-\r
-              al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);\r
-            }\r
-          }\r
-          if (JSEQ[i].getPdbidsCount() > 0)\r
-          {\r
-            Pdbids[] ids = JSEQ[i].getPdbids();\r
-            for (int p = 0; p < ids.length; p++)\r
-            {\r
-              jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();\r
-              entry.setId(ids[p].getId());\r
-              entry.setType(ids[p].getType());\r
-              al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);\r
-            }\r
-\r
-          }\r
-        }\r
-\r
-         /////////////////////////////////\r
-        //////////////////////////////////\r
-        //LOAD ANNOTATIONS\r
-        if (vamsasSet.getAnnotation() != null)\r
-        {\r
-            Annotation[] an = vamsasSet.getAnnotation();\r
-\r
-            for (int i = 0; i < an.length; i++)\r
-            {\r
-                AnnotationElement[] ae = an[i].getAnnotationElement();\r
-                jalview.datamodel.Annotation[] anot = new jalview.datamodel.Annotation[al.getWidth()];\r
-\r
-                for (int aa = 0; aa < ae.length; aa++)\r
-                {\r
-                    anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(ae[aa].getDisplayCharacter(),\r
-                            ae[aa].getDescription(),\r
-                            ae[aa].getSecondaryStructure().charAt(0),\r
-                            ae[aa].getValue());\r
-                }\r
-\r
-                jalview.datamodel.AlignmentAnnotation jaa = null;\r
-\r
-                if (an[i].getGraph())\r
-                {\r
-                    jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),\r
-                            an[i].getDescription(), anot, 0, 0,\r
-                            an[i].getGraphType());\r
-                }\r
-                else\r
-                {\r
-                    jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),\r
-                            an[i].getDescription(), anot);\r
-                }\r
-\r
-                al.addAnnotation(jaa);\r
-            }\r
-        }\r
-\r
-\r
-        /////////////////////////////////\r
-        // LOAD VIEWPORT\r
-        Viewport[] views = jms.getViewport();\r
-        Viewport view = views[0]; // DEAL WITH MULTIPLE VIEWPORTS LATER\r
-\r
-        AlignFrame af = new AlignFrame(al);\r
-\r
-\r
-        //  af.changeColour() );\r
-        /////////////////////////\r
-        //LOAD GROUPS\r
-        if (jms.getJGroupCount() > 0)\r
-        {\r
-            JGroup[] groups = jms.getJGroup();\r
-\r
-            for (int i = 0; i < groups.length; i++)\r
-            {\r
-                ColourSchemeI cs = null;\r
-\r
-                if (groups[i].getColour() != null)\r
-                {\r
-                    if (groups[i].getColour().startsWith("ucs"))\r
-                    {\r
-                        cs = GetUserColourScheme(jms, groups[i].getColour());\r
-                    }\r
-                    else\r
-                    {\r
-                        cs = ColourSchemeProperty.getColour(al,\r
-                                groups[i].getColour());\r
-                    }\r
-\r
-                    cs.setThreshold(groups[i].getPidThreshold(), true);\r
-                }\r
-\r
-                Vector seqs = new Vector();\r
-                int[] ids = groups[i].getSeq();\r
-\r
-                for (int s = 0; s < ids.length; s++)\r
-                {\r
-                    seqs.addElement((jalview.datamodel.SequenceI) seqids.elementAt(\r
-                            ids[s]));\r
-                }\r
-\r
-                jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(seqs,\r
-                        groups[i].getName(), cs, groups[i].getDisplayBoxes(),\r
-                        groups[i].getDisplayText(), groups[i].getColourText(),\r
-                        groups[i].getStart(), groups[i].getEnd());\r
-\r
-                sg.setOutlineColour(new java.awt.Color(\r
-                        groups[i].getOutlineColour()));\r
-\r
-                if (groups[i].getConsThreshold() != 0)\r
-                {\r
-                    jalview.analysis.Conservation c = new jalview.analysis.Conservation("All",\r
-                            ResidueProperties.propHash, 3, sg.sequences, 0,\r
-                            sg.getWidth() - 1);\r
-                    c.calculate();\r
-                    c.verdict(false, 25);\r
-                    sg.cs.setConservation(c);\r
-                }\r
-\r
-                al.addGroup(sg);\r
-            }\r
-        }\r
-\r
-\r
-\r
-        af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),\r
-            view.getHeight());\r
-        af.viewport.setStartRes(view.getStartRes());\r
-        af.viewport.setStartSeq(view.getStartSeq());\r
-        af.viewport.setShowAnnotation(view.getShowAnnotation());\r
-        af.viewport.showConservation = view.getShowConservation();\r
-        af.viewport.showQuality = view.getShowQuality();\r
-        af.viewport.showIdentity = view.getShowIdentity();\r
-        af.viewport.setAbovePIDThreshold(view.getPidSelected());\r
-        af.abovePIDThreshold.setSelected(view.getPidSelected());\r
-        af.viewport.setColourText(view.getShowColourText());\r
-        af.colourTextMenuItem.setSelected(view.getShowColourText());\r
-        af.viewport.setConservationSelected(view.getConservationSelected());\r
-        af.conservationMenuItem.setSelected(view.getConservationSelected());\r
-\r
-        af.viewport.setShowJVSuffix(view.getShowFullId());\r
-        af.seqLimits.setSelected(view.getShowFullId());\r
-\r
-        af.viewport.setFont(new java.awt.Font(view.getFontName(),\r
-                view.getFontStyle(), view.getFontSize()));\r
-        af.alignPanel.fontChanged();\r
-\r
-        af.viewport.setRenderGaps(view.getRenderGaps());\r
-        af.renderGapsMenuItem.setSelected(view.getRenderGaps());\r
-\r
-        af.viewport.setWrapAlignment(view.getWrapAlignment());\r
-        af.wrapMenuItem.setSelected(view.getWrapAlignment());\r
-\r
-        if (view.getWrapAlignment())\r
-        {\r
-            af.alignPanel.setWrapAlignment(view.getWrapAlignment());\r
-        }\r
-        else\r
-        {\r
-            af.annotationPanelMenuItem.setState(view.getShowAnnotation());\r
-            af.viewport.setShowAnnotation(view.getShowAnnotation());\r
-            af.alignPanel.setAnnotationVisible(view.getShowAnnotation());\r
-        }\r
-\r
-        af.viewport.setShowBoxes(view.getShowBoxes());\r
-        af.viewBoxesMenuItem.setSelected(view.getShowBoxes());\r
-        af.viewport.setShowText(view.getShowText());\r
-        af.viewTextMenuItem.setSelected(view.getShowText());\r
-\r
-        ColourSchemeI cs = null;\r
-\r
-        if (view.getBgColour() != null)\r
-        {\r
-            if (view.getBgColour().startsWith("ucs"))\r
-            {\r
-                cs = GetUserColourScheme(jms, view.getBgColour());\r
-            }\r
-            else\r
-            {\r
-                cs = ColourSchemeProperty.getColour(al, view.getBgColour());\r
-            }\r
-\r
-            if(cs!=null)\r
-            {\r
-              cs.setThreshold(view.getPidThreshold(), true);\r
-              cs.setConsensus(af.viewport.vconsensus);\r
-            }\r
-        }\r
-\r
-        af.setColourSelected(view.getBgColour());\r
-        af.viewport.setGlobalColourScheme(cs);\r
-        af.viewport.setColourAppliesToAllGroups(false);\r
-        af.changeColour(cs);\r
-        if (view.getConservationSelected() && cs!=null)\r
-        {\r
-          cs.setConservationInc(view.getConsThreshold());\r
-        }\r
-\r
-        af.viewport.setColourAppliesToAllGroups(true);\r
-\r
-        if (view.getShowSequenceFeatures())\r
-        {\r
-           af.viewport.showSequenceFeatures = true;\r
-           af.showSeqFeatures.setSelected(true);\r
-        }\r
-\r
-        if(jms.getFeatureSettings()!=null)\r
-        {\r
-          af.viewport.featuresDisplayed = new Hashtable();\r
-          String [] renderOrder = new String[jms.getFeatureSettings().getSettingCount()];\r
-         for(int fs=0; fs<jms.getFeatureSettings().getSettingCount(); fs++)\r
-         {\r
-           Setting setting = jms.getFeatureSettings().getSetting(fs);\r
-\r
-           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(setting.getType(),\r
-               new java.awt.Color(setting.getColour()));\r
-\r
-           renderOrder[fs] = setting.getType();\r
-\r
-           if(setting.getDisplay())\r
-             af.viewport.featuresDisplayed.put(\r
-                 setting.getType(), new Integer(setting.getColour()));\r
-         }\r
-         af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;\r
-        }\r
-\r
-\r
-        Desktop.addInternalFrame(af, view.getTitle(),\r
-             view.getWidth(), view.getHeight());\r
-\r
-        //LOAD TREES\r
-        ///////////////////////////////////////\r
-        if (jms.getTreeCount() > 0)\r
-        {\r
-            try\r
-            {\r
-                for (int t = 0; t < jms.getTreeCount(); t++)\r
-                {\r
-\r
-                    Tree tree = jms.getTree(t);\r
-\r
-                    TreePanel tp = af.ShowNewickTree(new jalview.io.NewickFile(\r
-                                tree.getNewick()), tree.getTitle(),\r
-                                tree.getWidth(), tree.getHeight(),\r
-                                tree.getXpos(), tree.getYpos());\r
-\r
-                    tp.fitToWindow.setState(tree.getFitToWindow());\r
-                    tp.fitToWindow_actionPerformed(null);\r
-\r
-                    if(tree.getFontName()!=null)\r
-                      tp.setTreeFont(new java.awt.Font(tree.getFontName(),\r
-                                          tree.getFontStyle(),\r
-                                          tree.getFontSize()));\r
-                    else\r
-                      tp.setTreeFont(new java.awt.Font(view.getFontName(),\r
-                                            view.getFontStyle(),\r
-                                            tree.getFontSize()));\r
-\r
-                    tp.showPlaceholders(tree.getMarkUnlinked());\r
-                    tp.showBootstrap(tree.getShowBootstrap());\r
-                    tp.showDistances(tree.getShowDistances());\r
-\r
-                    tp.treeCanvas.threshold = tree.getThreshold();\r
-\r
-                    if (tree.getCurrentTree())\r
-                      af.viewport.setCurrentTree(tp.getTree());\r
-                }\r
-\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                ex.printStackTrace();\r
-            }\r
-\r
-        }\r
-\r
-        return af;\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+
+import jalview.schemes.*;
+
+import jalview.gui.*;
+
+import java.io.*;
+
+import java.net.*;
+
+import java.util.*;
+
+import java.util.jar.*;
+
+import javax.swing.*;
+
+import org.exolab.castor.xml.*;
+
+import jalview.schemabinding.version2.*;
+
+
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Jalview2XML
+{
+    // SAVES SEVERAL ALIGNEMENT WINDOWS TO SAME JARFILE
+    public void SaveState(File statefile)
+    {
+        long creation = System.currentTimeMillis();
+        JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+
+        if (frames == null)
+        {
+            return;
+        }
+
+        try
+        {
+            FileOutputStream fos = new FileOutputStream(statefile);
+            JarOutputStream jout = new JarOutputStream(fos);
+
+            //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
+            ////////////////////////////////////////////////////
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,
+                        "UTF-8"));
+
+            Vector shortNames = new Vector();
+
+            //REVERSE ORDER
+            for (int i = frames.length - 1; i > -1; i--)
+            {
+                if (frames[i] instanceof AlignFrame)
+                {
+                    AlignFrame af = (AlignFrame) frames[i];
+
+                    String shortName = af.getTitle();
+
+                    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(0,
+                                    shortName.lastIndexOf("_"));
+                        }
+
+                        shortName = shortName.concat("_" + count);
+                        count++;
+                    }
+
+                    shortNames.addElement(shortName);
+
+                    if (!shortName.endsWith(".xml"))
+                    {
+                        shortName = shortName + ".xml";
+                    }
+
+                    SaveState(af, creation, shortName, jout, out);
+                }
+            }
+
+            out.close();
+            jout.close();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
+    public void SaveAlignment(AlignFrame af, String jarFile,
+        String fileName)
+    {
+        try
+        {
+            FileOutputStream fos = new FileOutputStream(jarFile);
+            JarOutputStream jout = new JarOutputStream(fos);
+
+            //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
+            ////////////////////////////////////////////////////
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,
+                        "UTF-8"));
+
+            SaveState(af, System.currentTimeMillis(), fileName, jout, out);
+            out.close();
+            jout.close();
+        }
+        catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param af DOCUMENT ME!
+     * @param timeStamp DOCUMENT ME!
+     * @param fileName DOCUMENT ME!
+     * @param jout DOCUMENT ME!
+     * @param out DOCUMENT ME!
+     */
+    public void SaveState(AlignFrame af, long timeStamp,
+        String fileName, JarOutputStream jout, PrintWriter out)
+    {
+        Vector seqids = new Vector();
+        Vector userColours = new Vector();
+
+        AlignViewport av = af.viewport;
+
+        JalviewModel object = new JalviewModel();
+        object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
+
+        object.setCreationDate(new java.util.Date(timeStamp));
+        object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
+
+        jalview.datamodel.AlignmentI jal = af.viewport.alignment;
+        jalview.datamodel.AlignmentI jalhidden = null;
+
+        if(av.hasHiddenRows)
+        {
+          jalhidden = jal;
+          jal = jal.getHiddenSequences().getFullAlignment();
+        }
+
+
+        SequenceSet vamsasSet = new SequenceSet();
+        Sequence vamsasSeq;
+        JalviewModelSequence jms = new JalviewModelSequence();
+
+        vamsasSet.setGapChar(jal.getGapCharacter() + "");
+
+        JSeq jseq;
+        Vector pdbfiles = null;
+
+        //SAVE SEQUENCES
+        int id = 0;
+        for (int i = 0; i < jal.getHeight(); i++)
+        {
+            seqids.add(jal.getSequenceAt(i));
+            vamsasSeq = new Sequence();
+            vamsasSeq.setId(id + "");
+            vamsasSeq.setName(jal.getSequenceAt(i).getName());
+            vamsasSeq.setSequence(jal.getSequenceAt(i).getSequence());
+            vamsasSeq.setDescription(jal.getSequenceAt(i).getDescription());
+
+            if(jal.getSequenceAt(i).getDatasetSequence().getDBRef()!=null)
+            {
+              jalview.datamodel.DBRefEntry [] dbrefs =
+                  jal.getSequenceAt(i).getDatasetSequence().getDBRef();
+
+              for(int d=0; d<dbrefs.length; d++)
+              {
+                DBRef dbref = new DBRef();
+                dbref.setSource( dbrefs[d].getSource() );
+                dbref.setVersion( dbrefs[d].getVersion());
+                dbref.setAccessionId(dbrefs[d].getAccessionId());
+                vamsasSeq.addDBRef(dbref);
+              }
+            }
+
+            jseq = new JSeq();
+            jseq.setStart(jal.getSequenceAt(i).getStart());
+            jseq.setEnd(jal.getSequenceAt(i).getEnd());
+            jseq.setColour(jal.getSequenceAt(i).getColor().getRGB());
+
+            jseq.setId(id);
+
+            if (av.hasHiddenRows)
+            {
+              jseq.setHidden(jalhidden.getHiddenSequences().isHidden(
+                  jal.getSequenceAt(i)));
+
+              if(jal.getSequenceAt(i).getHiddenSequences()!=null)
+              {
+                jalview.datamodel.SequenceI [] reps =
+                    jal.getSequenceAt(i).getHiddenSequences().getSequencesInOrder(jal);
+
+                for(int h=0; h<reps.length; h++)
+                {
+                  jseq.addHiddenSequences(
+                      jal.findIndex(reps[h])
+                      );
+                }
+              }
+            }
+
+
+            if(jal.getSequenceAt(i).getDatasetSequence().getSequenceFeatures()!=null)
+            {
+              jalview.datamodel.SequenceFeature[] sf
+                  = jal.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();
+              int index = 0;
+              while(index < sf.length)
+              {
+                Features features = new Features();
+
+                features.setBegin(sf[index].getBegin());
+                features.setEnd(sf[index].getEnd());
+                features.setDescription(sf[index].getDescription());
+                features.setType(sf[index].getType());
+                features.setFeatureGroup(sf[index].getFeatureGroup());
+                features.setScore(sf[index].getScore());
+                if(sf[index].links!=null)
+                {
+                  for(int l=0; l<sf[index].links.size(); l++)
+                  {
+                    OtherData keyValue = new OtherData();
+                    keyValue.setKey("LINK_"+l);
+                    keyValue.setValue(sf[index].links.elementAt(l).toString());
+                    features.addOtherData(keyValue);
+                  }
+                }
+                if(sf[index].otherDetails!=null)
+                {
+                  String key;
+                  Enumeration keys = sf[index].otherDetails.keys();
+                  while(keys.hasMoreElements())
+                  {
+                    key = keys.nextElement().toString();
+                    OtherData keyValue = new OtherData();
+                    keyValue.setKey( key );
+                    keyValue.setValue(
+                        sf[index].otherDetails.get(key).toString());
+                    features.addOtherData(keyValue);
+                  }
+                }
+
+                jseq.addFeatures(features);
+                index ++;
+              }
+            }
+
+            if(jal.getSequenceAt(i).getDatasetSequence().getPDBId()!=null)
+            {
+              Enumeration en = jal.getSequenceAt(i).getDatasetSequence().getPDBId().elements();
+              while(en.hasMoreElements())
+              {
+                Pdbids pdb = new Pdbids();
+                jalview.datamodel.PDBEntry entry
+                   = (jalview.datamodel.PDBEntry)en.nextElement();
+
+                pdb.setId(entry.getId());
+                pdb.setType(entry.getType());
+
+                if(entry.getFile()!=null)
+                {
+                  if(pdbfiles==null)
+                    pdbfiles = new Vector();
+
+
+                  if(!pdbfiles.contains(entry.getId()))
+                  {
+                    pdbfiles.addElement(entry.getId());
+                    try
+                    {
+                      File file = new File(entry.getFile());
+                      if(file.exists())
+                      {
+                        byte[] data = new byte[ (int) file.length()];
+                        jout.putNextEntry(new JarEntry(entry.getId()));
+                        DataInputStream dis = new DataInputStream(new
+                            FileInputStream(file));
+                        dis.readFully(data);
+
+                        DataOutputStream dout = new DataOutputStream(jout);
+                        dout.write(data, 0, data.length);
+                        jout.closeEntry();
+                      }
+                    }
+                    catch (Exception ex)
+                    {
+                      ex.printStackTrace();
+                    }
+                  }
+                }
+
+
+                if(entry.getProperty()!=null)
+                {
+                  PdbentryItem item = new PdbentryItem();
+                  Hashtable properties = entry.getProperty();
+                  Enumeration en2 = properties.keys();
+                  while(en2.hasMoreElements())
+                  {
+                    Property prop = new Property();
+                    String key = en2.nextElement().toString();
+                    prop.setName(key);
+                    prop.setValue( properties.get(key).toString() );
+                    item.addProperty(prop);
+                  }
+                  pdb.addPdbentryItem(item);
+                }
+
+                jseq.addPdbids(pdb);
+              }
+            }
+
+            jms.addJSeq(jseq);
+            vamsasSet.addSequence(vamsasSeq);
+            id++;
+        }
+
+        //SAVE TREES
+        ///////////////////////////////////
+        if (af.viewport.currentTree != null)
+        {
+          // FIND ANY ASSOCIATED TREES
+          // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
+          if (Desktop.desktop != null)
+          {
+            JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+
+            for (int t = 0; t < frames.length; t++)
+            {
+              if (frames[t] instanceof TreePanel)
+              {
+                TreePanel tp = (TreePanel) frames[t];
+
+                if (tp.treeCanvas.av.alignment == jal)
+                {
+                  Tree tree = new Tree();
+                  tree.setTitle(tp.getTitle());
+                  tree.setCurrentTree( (af.viewport.currentTree == tp.getTree()));
+                  tree.setNewick(tp.getTree().toString());
+                  tree.setThreshold(tp.treeCanvas.threshold);
+
+                  tree.setFitToWindow(tp.fitToWindow.getState());
+                  tree.setFontName(tp.getTreeFont().getName());
+                  tree.setFontSize(tp.getTreeFont().getSize());
+                  tree.setFontStyle(tp.getTreeFont().getStyle());
+                  tree.setMarkUnlinked(tp.placeholdersMenu.getState());
+
+                  tree.setShowBootstrap(tp.bootstrapMenu.getState());
+                  tree.setShowDistances(tp.distanceMenu.getState());
+
+                  tree.setHeight(tp.getHeight());
+                  tree.setWidth(tp.getWidth());
+                  tree.setXpos(tp.getX());
+                  tree.setYpos(tp.getY());
+
+                  jms.addTree(tree);
+                }
+              }
+            }
+          }
+        }
+
+        //SAVE ANNOTATIONS
+        if (jal.getAlignmentAnnotation() != null)
+        {
+            jalview.datamodel.AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
+
+            for (int i = 0; i < aa.length; i++)
+            {
+                Annotation an = new Annotation();
+
+                if (aa[i].label.equals("Quality") ||
+                        aa[i].label.equals("Conservation") ||
+                        aa[i].label.equals("Consensus"))
+                {
+                    an.setLabel(aa[i].label);
+                    an.setGraph(true);
+                    vamsasSet.addAnnotation(an);
+                    continue;
+                }
+
+
+                an.setDescription(aa[i].description);
+
+                if(aa[i].sequenceRef!=null)
+                 {
+                   an.setSequenceRef(aa[i].sequenceRef.getName());
+                 }
+
+                if(aa[i].graph>0)
+                {
+                  an.setGraph(true);
+                  an.setGraphType(aa[i].graph);
+                  an.setGraphGroup(aa[i].graphGroup);
+                  if(aa[i].getThreshold()!=null)
+                  {
+                    ThresholdLine line = new ThresholdLine();
+                    line.setLabel(aa[i].getThreshold().label);
+                    line.setValue(aa[i].getThreshold().value);
+                    line.setColour(aa[i].getThreshold().colour.getRGB());
+                    an.setThresholdLine(line);
+                  }
+                }
+                else
+                  an.setGraph(false);
+
+                an.setLabel(aa[i].label);
+
+                AnnotationElement ae;
+
+                for (int a = 0; a < aa[i].annotations.length; a++)
+                {
+                    if ((aa[i] == null) || (aa[i].annotations[a] == null))
+                    {
+                        continue;
+                    }
+
+                    ae = new AnnotationElement();
+                    ae.setDescription(aa[i].annotations[a].description);
+                    ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
+                    ae.setValue(aa[i].annotations[a].value);
+                    ae.setPosition(a);
+                    ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure +
+                        "");
+
+                    if(aa[i].annotations[a].colour!=java.awt.Color.black)
+                      ae.setColour(aa[i].annotations[a].colour.getRGB());
+
+                    an.addAnnotationElement(ae);
+                }
+
+                vamsasSet.addAnnotation(an);
+            }
+        }
+
+        //SAVE GROUPS
+        if (jal.getGroups() != null)
+        {
+            JGroup[] groups = new JGroup[jal.getGroups().size()];
+
+            for (int i = 0; i < groups.length; i++)
+            {
+                groups[i] = new JGroup();
+
+                jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal.getGroups()
+                                                                                          .elementAt(i);
+                groups[i].setStart(sg.getStartRes());
+                groups[i].setEnd(sg.getEndRes());
+                groups[i].setName(sg.getName());
+                if(sg.cs!=null)
+                {
+                  if (sg.cs.conservationApplied())
+                  {
+                    groups[i].setConsThreshold(sg.cs.getConservationInc());
+
+                    if (sg.cs instanceof jalview.schemes.UserColourScheme)
+                    {
+                      groups[i].setColour(SetUserColourScheme(sg.cs,
+                          userColours,
+                          jms));
+                    }
+                    else
+                    {
+                      groups[i].setColour(ColourSchemeProperty.getColourName(sg.
+                          cs));
+                    }
+                  }
+                  else if(sg.cs instanceof jalview.schemes.AnnotationColourGradient)
+                  {
+                    groups[i].setColour(
+                        ColourSchemeProperty.getColourName(
+                      ( (jalview.schemes.AnnotationColourGradient) sg.cs).getBaseColour()));
+                  }
+                  else if (sg.cs instanceof jalview.schemes.UserColourScheme)
+                  {
+                    groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
+                        jms));
+                  }
+                  else
+                  {
+                    groups[i].setColour(ColourSchemeProperty.getColourName(
+                        sg.cs));
+                  }
+
+                  groups[i].setPidThreshold(sg.cs.getThreshold());
+                }
+
+                groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
+                groups[i].setDisplayBoxes(sg.getDisplayBoxes());
+                groups[i].setDisplayText(sg.getDisplayText());
+                groups[i].setColourText(sg.getColourText());
+
+                for (int s = 0; s < sg.getSize(false); s++)
+                {
+                    jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg.getSequenceAt(s);
+                    int index = seqids.indexOf(seq);
+                    groups[i].addSeq(index);
+                }
+            }
+
+            jms.setJGroup(groups);
+        }
+
+
+        ///////////SAVE VIEWPORT
+        Viewport view = new Viewport();
+        view.setTitle(af.getTitle());
+        view.setXpos(af.getX());
+        view.setYpos(af.getY());
+        view.setWidth(af.getWidth());
+        view.setHeight(af.getHeight());
+        view.setStartRes(av.startRes);
+        view.setStartSeq(av.startSeq);
+
+        if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
+        {
+            view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
+                    userColours, jms));
+        }
+        else if(av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
+        {
+           jalview.schemes.AnnotationColourGradient acg
+              = (jalview.schemes.AnnotationColourGradient)av.getGlobalColourScheme();
+
+            AnnotationColours ac = new AnnotationColours();
+            ac.setAboveThreshold(acg.getAboveThreshold());
+            ac.setThreshold(acg.getAnnotationThreshold());
+            ac.setAnnotation(acg.getAnnotation());
+            if(acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
+              ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
+                    userColours, jms));
+            else
+              ac.setColourScheme(ColourSchemeProperty.getColourName(acg.getBaseColour()));
+
+            ac.setMaxColour(acg.getMaxColour().getRGB());
+            ac.setMinColour(acg.getMinColour().getRGB());
+            view.setAnnotationColours(ac);
+            view.setBgColour("AnnotationColourGradient");
+        }
+        else
+        {
+            view.setBgColour(ColourSchemeProperty.getColourName(
+                    av.getGlobalColourScheme()));
+        }
+
+        ColourSchemeI cs = av.getGlobalColourScheme();
+
+        if(cs!=null)
+        {
+          if (cs.conservationApplied())
+          {
+            view.setConsThreshold(cs.getConservationInc());
+            if (cs instanceof jalview.schemes.UserColourScheme)
+              view.setBgColour(SetUserColourScheme(cs, userColours, jms));
+          }
+
+          if (cs instanceof ResidueColourScheme)
+          {
+            view.setPidThreshold(cs.getThreshold());
+          }
+        }
+
+        view.setConservationSelected(av.getConservationSelected());
+        view.setPidSelected(av.getAbovePIDThreshold());
+        view.setFontName(av.font.getName());
+        view.setFontSize(av.font.getSize());
+        view.setFontStyle(av.font.getStyle());
+        view.setRenderGaps(av.renderGaps);
+        view.setShowAnnotation(av.getShowAnnotation());
+        view.setShowBoxes(av.getShowBoxes());
+        view.setShowColourText(av.getColourText());
+        view.setShowConservation(av.showConservation);
+        view.setShowFullId(av.getShowJVSuffix());
+        view.setShowIdentity(av.showIdentity);
+        view.setShowQuality(av.showQuality);
+        view.setShowSequenceFeatures(av.showSequenceFeatures);
+        view.setShowText(av.getShowText());
+        view.setWrapAlignment(av.getWrapAlignment());
+
+        if(av.featuresDisplayed!=null)
+        {
+          jalview.schemabinding.version2.FeatureSettings fs
+              = new jalview.schemabinding.version2.FeatureSettings();
+
+          String [] renderOrder =
+              af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
+
+          Vector settingsAdded = new Vector();
+          for(int ro=0; ro<renderOrder.length; ro++)
+          {
+            Setting setting = new Setting();
+            setting.setType(renderOrder[ro]);
+            setting.setColour(
+                af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().getColour(renderOrder[ro]).getRGB()
+                );
+
+            setting.setDisplay(
+                av.featuresDisplayed.containsKey(renderOrder[ro])
+                );
+
+            fs.addSetting(setting);
+            settingsAdded.addElement(renderOrder[ro]);
+          }
+
+          //Make sure we save none displayed feature settings
+          Enumeration en =
+              af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureColours.keys();
+          while(en.hasMoreElements())
+          {
+            String key = en.nextElement().toString();
+            if(settingsAdded.contains(key))
+              continue;
+
+            Setting setting = new Setting();
+            setting.setType(key);
+            setting.setColour(
+                af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().getColour(key).getRGB()
+                );
+
+            setting.setDisplay(false);
+
+            fs.addSetting(setting);
+            settingsAdded.addElement(key);
+          }
+
+          jms.setFeatureSettings(fs);
+
+        }
+
+        if(av.hasHiddenColumns)
+        {
+          for(int c=0; c<av.getColumnSelection().getHiddenColumns().size(); c++)
+          {
+            int [] region = (int[]) av.getColumnSelection().getHiddenColumns().elementAt(c);
+            HiddenColumns hc = new HiddenColumns();
+            hc.setStart(region[0]);
+            hc.setEnd(region[1]);
+            view.addHiddenColumns(hc);
+          }
+        }
+
+        jms.addViewport(view);
+
+
+        object.setJalviewModelSequence(jms);
+        object.getVamsasModel().addSequenceSet(vamsasSet);
+
+        try
+        {
+            if (!fileName.endsWith(".xml"))
+            {
+                fileName = fileName + ".xml";
+            }
+
+            JarEntry entry = new JarEntry(fileName);
+            jout.putNextEntry(entry);
+
+            object.marshal(out);
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
+        Vector userColours, JalviewModelSequence jms)
+    {
+        String id = null;
+        jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
+
+        if (!userColours.contains(ucs))
+        {
+            userColours.add(ucs);
+
+            java.awt.Color[] colours = ucs.getColours();
+            jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
+            jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
+
+            for (int i = 0; i < colours.length; i++)
+            {
+                jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
+                col.setName(ResidueProperties.aa[i]);
+                col.setRGB(jalview.util.Format.getHexString(colours[i]));
+                jbucs.addColour(col);
+            }
+            if(ucs.getLowerCaseColours()!=null)
+            {
+              colours = ucs.getLowerCaseColours();
+              for (int i = 0; i < colours.length; i++)
+             {
+                 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
+                 col.setName(ResidueProperties.aa[i].toLowerCase());
+                 col.setRGB(jalview.util.Format.getHexString(colours[i]));
+                 jbucs.addColour(col);
+             }
+            }
+
+            id = "ucs" + userColours.indexOf(ucs);
+            uc.setId(id);
+            uc.setUserColourScheme(jbucs);
+            jms.addUserColours(uc);
+        }
+
+        return id;
+    }
+
+   jalview.schemes.UserColourScheme GetUserColourScheme(
+        JalviewModelSequence jms, String id)
+    {
+        UserColours[] uc = jms.getUserColours();
+        UserColours colours = null;
+
+        for (int i = 0; i < uc.length; i++)
+        {
+            if (uc[i].getId().equals(id))
+            {
+                colours = uc[i];
+
+                break;
+            }
+        }
+
+        java.awt.Color[] newColours = new java.awt.Color[24];
+
+        for (int i = 0; i < 24; i++)
+        {
+            newColours[i] = new java.awt.Color(Integer.parseInt(
+                        colours.getUserColourScheme().getColour(i).getRGB(), 16));
+        }
+
+        jalview.schemes.UserColourScheme ucs =
+            new jalview.schemes.UserColourScheme(newColours);
+
+        if (colours.getUserColourScheme().getColourCount() > 24)
+        {
+          newColours = new java.awt.Color[23];
+          for (int i = 0; i < 23; i++)
+          {
+            newColours[i] = new java.awt.Color(Integer.parseInt(
+                colours.getUserColourScheme().getColour(i+24).getRGB(), 16));
+          }
+          ucs.setLowerCaseColours(newColours);
+        }
+
+        return ucs;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param file DOCUMENT ME!
+     */
+    public AlignFrame LoadJalviewAlign(final String file)
+    {
+        jalview.gui.AlignFrame af = null;
+        try
+        {
+            //UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
+            URL url = null;
+
+            if (file.startsWith("http://"))
+            {
+                url = new URL(file);
+            }
+
+            JarInputStream jin = null;
+            JarEntry jarentry = null;
+            int entryCount = 1;
+
+            do
+            {
+                if (url != null)
+                {
+                    jin = new JarInputStream(url.openStream());
+                }
+                else
+                {
+                    jin = new JarInputStream(new FileInputStream(file));
+                }
+
+                for (int i = 0; i < entryCount; i++)
+                {
+                    jarentry = jin.getNextJarEntry();
+                }
+
+                if (jarentry != null && jarentry.getName().endsWith(".xml"))
+                {
+                    InputStreamReader in = new InputStreamReader(jin, "UTF-8");
+                    JalviewModel object = new JalviewModel();
+
+                    Unmarshaller unmar = new Unmarshaller(object);
+                    unmar.setValidation(false);
+                    object = (JalviewModel) unmar.unmarshal( in );
+
+                    af = LoadFromObject(object, file);
+                    entryCount++;
+                }
+                else if (jarentry != null)
+                {
+                  //Some other file here.
+                  entryCount++;
+                }
+            }
+            while (jarentry != null);
+        }
+        catch(java.net.UnknownHostException ex)
+        {
+          ex.printStackTrace();
+          System.err.println("Couldn't locate Jalview XML file : " +
+              ex + "\n");
+
+          javax.swing.SwingUtilities.invokeLater(new Runnable()
+          {
+            public void run()
+            {
+              JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                  "Couldn't locate " + file,
+                  "URL not found",
+                  JOptionPane.WARNING_MESSAGE);
+            }
+          });
+        }
+        catch (Exception ex)
+        {
+
+          //Is Version 1 Jar file?
+          af =  new Jalview2XML_V1().LoadJalviewAlign(file);
+
+          if(af!=null)
+          {
+            System.out.println("Successfully loaded archive file");
+            return af;
+          }
+          ex.printStackTrace();
+            System.err.println("Exception whilst loading jalview XML file : " +
+                ex + "\n");
+            javax.swing.SwingUtilities.invokeLater(new Runnable()
+            {
+              public void run()
+              {
+
+                JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                    "Error loading  " + file,
+                    "Error loading Jalview file",
+                    JOptionPane.WARNING_MESSAGE);
+              }});
+        }
+
+        return af;
+    }
+
+    String loadPDBFile(String file, String pdbId)
+    {
+      System.out.println("load file "+file);
+      try
+      {
+        JarInputStream jin = null;
+
+        if (file.startsWith("http://"))
+        {
+          jin = new JarInputStream(new URL(file).openStream());
+        }
+        else
+        {
+          jin = new JarInputStream(new FileInputStream(file));
+        }
+
+        JarEntry entry = null;
+        do
+        {
+          entry = jin.getNextJarEntry();
+        }
+        while (!entry.getName().equals(pdbId));
+
+        BufferedReader in = new BufferedReader(new InputStreamReader(jin));
+        File outFile = File.createTempFile("jalview_pdb", ".txt");
+        outFile.deleteOnExit();
+        PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
+        String data;
+
+        while ( (data = in.readLine()) != null)
+        {
+          out.println(data);
+        }
+        out.close();
+        return outFile.getAbsolutePath();
+
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+
+      return null;
+    }
+
+
+    AlignFrame LoadFromObject(JalviewModel object, String file)
+    {
+        Vector seqids = new Vector();
+        SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
+        Sequence[] vamsasSeq = vamsasSet.getSequence();
+
+        JalviewModelSequence jms = object.getJalviewModelSequence();
+
+        //////////////////////////////////
+        //LOAD SEQUENCES
+        Vector hiddenSeqs = null;
+        jalview.datamodel.Sequence[] jseqs = new jalview.datamodel.Sequence[vamsasSeq.length];
+        JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
+        for (int i = 0; i < vamsasSeq.length; i++)
+        {
+            jseqs[i] = new jalview.datamodel.Sequence(vamsasSeq[i].getName(),
+                    vamsasSeq[i].getSequence());
+            jseqs[i].setDescription( vamsasSeq[i].getDescription() );
+
+            if(JSEQ[i].getHidden())
+            {
+              if(hiddenSeqs == null)
+                hiddenSeqs = new Vector();
+              hiddenSeqs.addElement(jseqs[i]);
+            }
+            jseqs[i].setStart(JSEQ[i].getStart());
+            jseqs[i].setEnd(JSEQ[i].getEnd());
+            jseqs[i].setColor(new java.awt.Color(JSEQ[i].getColour()));
+            seqids.add(jseqs[i]);
+        }
+
+        ///SequenceFeatures are added to the DatasetSequence,
+        // so we must create the dataset before loading features
+        /////////////////////////////////
+        jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(jseqs);
+        al.setDataset(null);
+        /////////////////////////////////
+
+
+        Hashtable pdbloaded = new Hashtable();
+        for (int i = 0; i < vamsasSeq.length; i++)
+        {
+          if (JSEQ[i].getFeaturesCount() > 0)
+          {
+            Features[] features = JSEQ[i].getFeatures();
+            for (int f = 0; f < features.length; f++)
+            {
+              jalview.datamodel.SequenceFeature sf
+                  = new jalview.datamodel.SequenceFeature(features[f].getType(),
+                  features[f].getDescription(), features[f].getStatus(),
+                  features[f].getBegin(), features[f].getEnd(),
+                  features[f].getFeatureGroup());
+
+              sf.setScore(features[f].getScore());
+              for(int od=0; od<features[f].getOtherDataCount(); od++)
+              {
+                OtherData keyValue = features[f].getOtherData(od);
+                if(keyValue.getKey().startsWith("LINK"))
+                  sf.addLink(keyValue.getValue());
+                else
+                  sf.setValue(keyValue.getKey(), keyValue.getValue());
+
+              }
+
+              al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
+            }
+          }
+          if (JSEQ[i].getPdbidsCount() > 0)
+          {
+            Pdbids[] ids = JSEQ[i].getPdbids();
+            for (int p = 0; p < ids.length; p++)
+            {
+              jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
+              entry.setId(ids[p].getId());
+              entry.setType(ids[p].getType());
+              if (ids[p].getFile() != null)
+              {
+                if (!pdbloaded.containsKey(ids[p].getFile()))
+                {
+                  String tmppdb = loadPDBFile(file, ids[p].getId());
+                  entry.setFile(tmppdb);
+                  pdbloaded.put(ids[p].getId(), tmppdb);
+                }
+                else
+                  entry.setFile(pdbloaded.get(ids[p].getId()).toString());
+              }
+
+              al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
+            }
+          }
+          if(vamsasSeq[i].getDBRefCount()>0)
+          {
+            for(int d=0; d<vamsasSeq[i].getDBRefCount(); d++)
+            {
+              jalview.datamodel.DBRefEntry entry =
+                  new jalview.datamodel.DBRefEntry(
+                      vamsasSeq[i].getDBRef(d).getSource(),
+                      vamsasSeq[i].getDBRef(d).getVersion(),
+                      vamsasSeq[i].getDBRef(d).getAccessionId()
+                      );
+              al.getSequenceAt(i).getDatasetSequence().addDBRef(entry);
+            }
+
+          }
+        }
+
+
+
+         /////////////////////////////////
+        //////////////////////////////////
+        //LOAD ANNOTATIONS
+        boolean hideQuality = true,
+            hideConservation = true,
+            hideConsensus = true;
+
+        if (vamsasSet.getAnnotation() != null)
+        {
+            Annotation[] an = vamsasSet.getAnnotation();
+
+            for (int i = 0; i < an.length; i++)
+            {
+               if (an[i].getLabel().equals("Quality"))
+                {
+                 hideQuality = false;
+                 continue;
+                }
+               else if(an[i].getLabel().equals("Conservation"))
+               {
+                 hideConservation = false;
+                 continue;
+               }
+               else if(an[i].getLabel().equals("Consensus"))
+               {
+                 hideConsensus = false;
+                 continue;
+               }
+
+                AnnotationElement[] ae = an[i].getAnnotationElement();
+                jalview.datamodel.Annotation[] anot = new jalview.datamodel.Annotation[al.getWidth()];
+
+                for (int aa = 0; aa < ae.length; aa++)
+                {
+                    anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(ae[aa].getDisplayCharacter(),
+                            ae[aa].getDescription(),
+                            ae[aa].getSecondaryStructure().length()==0?' ':ae[aa].getSecondaryStructure().charAt(0),
+                            ae[aa].getValue());
+                    anot[ae[aa].getPosition()].colour = new java.awt.Color( ae[aa].getColour() );
+                }
+
+                jalview.datamodel.AlignmentAnnotation jaa = null;
+
+                if (an[i].getGraph())
+                {
+                  jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
+                      an[i].getDescription(), anot, 0, 0,
+                      an[i].getGraphType());
+
+                  jaa.graphGroup = an[i].getGraphGroup();
+
+                  if (an[i].getThresholdLine() != null)
+                  {
+                    jaa.setThreshold(new jalview.datamodel.GraphLine(
+                                  an[i].getThresholdLine().getValue(),
+                                  an[i].getThresholdLine().getLabel(),
+                                new java.awt.Color(an[i].getThresholdLine().getColour()))
+                             );
+
+                  }
+
+                }
+                else
+                {
+                    jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
+                            an[i].getDescription(), anot);
+                }
+
+                if(an[i].getSequenceRef()!=null)
+                {
+                  jaa.createSequenceMapping(
+                      al.findName(an[i].getSequenceRef()), 1, true
+                      );
+                  al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
+                }
+
+                al.addAnnotation(jaa);
+            }
+        }
+
+
+        //  af.changeColour() );
+        /////////////////////////
+        //LOAD GROUPS
+        if (jms.getJGroupCount() > 0)
+        {
+            JGroup[] groups = jms.getJGroup();
+
+            for (int i = 0; i < groups.length; i++)
+            {
+                ColourSchemeI cs = null;
+
+                if (groups[i].getColour() != null)
+                {
+                    if (groups[i].getColour().startsWith("ucs"))
+                    {
+                        cs = GetUserColourScheme(jms, groups[i].getColour());
+                    }
+                    else
+                    {
+                        cs = ColourSchemeProperty.getColour(al,
+                                groups[i].getColour());
+                    }
+
+                    if(cs!=null)
+                      cs.setThreshold(groups[i].getPidThreshold(), true);
+                }
+
+                Vector seqs = new Vector();
+                int[] ids = groups[i].getSeq();
+
+                for (int s = 0; s < ids.length; s++)
+                {
+                    seqs.addElement((jalview.datamodel.SequenceI) seqids.elementAt(
+                            ids[s]));
+                }
+
+                jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(seqs,
+                        groups[i].getName(), cs, groups[i].getDisplayBoxes(),
+                        groups[i].getDisplayText(), groups[i].getColourText(),
+                        groups[i].getStart(), groups[i].getEnd());
+
+                sg.setOutlineColour(new java.awt.Color(
+                        groups[i].getOutlineColour()));
+
+                if (groups[i].getConsThreshold() != 0)
+                {
+                    jalview.analysis.Conservation c = new jalview.analysis.Conservation("All",
+                            ResidueProperties.propHash, 3, sg.getSequences(false), 0,
+                            sg.getWidth() - 1);
+                    c.calculate();
+                    c.verdict(false, 25);
+                    sg.cs.setConservation(c);
+                }
+
+                al.addGroup(sg);
+            }
+        }
+
+
+        /////////////////////////////////
+        // LOAD VIEWPORT
+        Viewport[] views = jms.getViewport();
+        Viewport view = views[0]; // DEAL WITH MULTIPLE VIEWPORTS LATER
+
+
+        AlignFrame af = new AlignFrame(al);
+
+        if(hiddenSeqs!=null)
+        {
+          for(int s=0; s<JSEQ.length; s++)
+          {
+            for(int r=0; r<JSEQ[s].getHiddenSequencesCount(); r++)
+            {
+              al.getSequenceAt(s).addHiddenSequence(
+                  al.getSequenceAt( JSEQ[s].getHiddenSequences(r)  )
+                  );
+            }
+          }
+
+          for(int s=0; s<hiddenSeqs.size(); s++)
+          {
+              af.viewport.hideSequence(
+                (jalview.datamodel.SequenceI)hiddenSeqs.elementAt(s));
+          }
+        }
+
+
+        if(hideConsensus || hideQuality || hideConservation)
+        {
+          int hSize = al.getAlignmentAnnotation().length;
+          for (int h = 0; h < hSize; h++)
+          {
+            if (
+                (hideConsensus &&
+                 al.getAlignmentAnnotation()[h].label.equals("Consensus"))
+                ||
+                (hideQuality &&
+                 al.getAlignmentAnnotation()[h].label.equals("Quality"))
+                ||
+                (hideConservation &&
+                 al.getAlignmentAnnotation()[h].label.equals("Conservation")))
+            {
+              al.deleteAnnotation(al.getAlignmentAnnotation()[h]);
+              hSize--;
+              h--;
+            }
+          }
+          af.alignPanel.adjustAnnotationHeight();
+        }
+
+        af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
+            view.getHeight());
+        af.viewport.setStartRes(view.getStartRes());
+        af.viewport.setStartSeq(view.getStartSeq());
+        af.viewport.setShowAnnotation(view.getShowAnnotation());
+        af.viewport.showConservation = view.getShowConservation();
+        af.viewport.showQuality = view.getShowQuality();
+        af.viewport.showIdentity = view.getShowIdentity();
+        af.viewport.setAbovePIDThreshold(view.getPidSelected());
+        af.abovePIDThreshold.setSelected(view.getPidSelected());
+        af.viewport.setColourText(view.getShowColourText());
+        af.colourTextMenuItem.setSelected(view.getShowColourText());
+        af.viewport.setConservationSelected(view.getConservationSelected());
+        af.conservationMenuItem.setSelected(view.getConservationSelected());
+
+        af.viewport.setShowJVSuffix(view.getShowFullId());
+        af.seqLimits.setSelected(view.getShowFullId());
+
+        af.viewport.setFont(new java.awt.Font(view.getFontName(),
+                view.getFontStyle(), view.getFontSize()));
+        af.alignPanel.fontChanged();
+
+        af.viewport.setRenderGaps(view.getRenderGaps());
+        af.renderGapsMenuItem.setSelected(view.getRenderGaps());
+
+        af.viewport.setWrapAlignment(view.getWrapAlignment());
+        af.wrapMenuItem.setSelected(view.getWrapAlignment());
+
+        af.alignPanel.setWrapAlignment(view.getWrapAlignment());
+
+        af.annotationPanelMenuItem.setState(view.getShowAnnotation());
+        af.viewport.setShowAnnotation(view.getShowAnnotation());
+        af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
+
+        af.viewport.setShowBoxes(view.getShowBoxes());
+        af.viewBoxesMenuItem.setSelected(view.getShowBoxes());
+        af.viewport.setShowText(view.getShowText());
+        af.viewTextMenuItem.setSelected(view.getShowText());
+
+        ColourSchemeI cs = null;
+
+        if (view.getBgColour() != null)
+        {
+            if (view.getBgColour().startsWith("ucs"))
+            {
+                cs = GetUserColourScheme(jms, view.getBgColour());
+            }
+            else if(view.getBgColour().startsWith("Annotation"))
+            {
+              //int find annotation
+              for (int i = 0; i < af.viewport.alignment.getAlignmentAnnotation().length; i++)
+              {
+                if (af.viewport.alignment.getAlignmentAnnotation()[i].label.
+                    equals(view.getAnnotationColours().getAnnotation()))
+                {
+                  if (af.viewport.alignment.getAlignmentAnnotation()[i].
+                      getThreshold() == null)
+                  {
+                    af.viewport.alignment.getAlignmentAnnotation()[i].
+                        setThreshold(
+                            new jalview.datamodel.GraphLine(
+                                view.getAnnotationColours().getThreshold(),
+                                "Threshold", java.awt.Color.black)
+
+                        );
+                  }
+
+
+                  if (view.getAnnotationColours().getColourScheme().equals(
+                      "None"))
+                  {
+                    cs = new AnnotationColourGradient(
+                        af.viewport.alignment.getAlignmentAnnotation()[i],
+                        new java.awt.Color(view.getAnnotationColours().
+                                           getMinColour()),
+                        new java.awt.Color(view.getAnnotationColours().
+                                           getMaxColour()),
+                        view.getAnnotationColours().getAboveThreshold());
+                  }
+                  else if (view.getAnnotationColours().getColourScheme().
+                           startsWith("ucs"))
+                  {
+                     cs = new AnnotationColourGradient(
+                         af.viewport.alignment.getAlignmentAnnotation()[i],
+                         GetUserColourScheme(jms, view.getAnnotationColours().
+                                                        getColourScheme()),
+                         view.getAnnotationColours().getAboveThreshold()
+                         );
+                   }
+                   else
+                   {
+                     cs = new AnnotationColourGradient(
+                         af.viewport.alignment.getAlignmentAnnotation()[i],
+                         ColourSchemeProperty.getColour(al,
+                         view.getAnnotationColours().getColourScheme()),
+                         view.getAnnotationColours().getAboveThreshold()
+                         );
+                   }
+
+                  // Also use these settings for all the groups
+                  if (al.getGroups() != null)
+                    for (int g = 0; g < al.getGroups().size(); g++)
+                    {
+                      jalview.datamodel.SequenceGroup sg
+                          = (jalview.datamodel.SequenceGroup)al.getGroups().elementAt(g);
+
+                      if(sg.cs == null)
+                        continue;
+
+
+                  /*    if (view.getAnnotationColours().getColourScheme().equals("None"))
+                      {
+                        sg.cs = new AnnotationColourGradient(
+                            af.viewport.alignment.getAlignmentAnnotation()[i],
+                            new java.awt.Color(view.getAnnotationColours().
+                                               getMinColour()),
+                            new java.awt.Color(view.getAnnotationColours().
+                                               getMaxColour()),
+                            view.getAnnotationColours().getAboveThreshold());
+                      }
+                      else*/
+                      {
+                        sg.cs = new AnnotationColourGradient(
+                            af.viewport.alignment.getAlignmentAnnotation()[i],
+                            sg.cs,
+                            view.getAnnotationColours().getAboveThreshold()
+                            );
+                      }
+
+                    }
+
+
+                  break;
+                }
+
+              }
+            }
+            else
+            {
+                cs = ColourSchemeProperty.getColour(al, view.getBgColour());
+            }
+
+            if(cs!=null)
+            {
+              cs.setThreshold(view.getPidThreshold(), true);
+              cs.setConsensus(af.viewport.vconsensus);
+            }
+        }
+
+        af.setColourSelected(view.getBgColour());
+        af.viewport.setGlobalColourScheme(cs);
+        af.viewport.setColourAppliesToAllGroups(false);
+        af.changeColour(cs);
+        if (view.getConservationSelected() && cs!=null)
+        {
+          cs.setConservationInc(view.getConsThreshold());
+        }
+
+        af.viewport.setColourAppliesToAllGroups(true);
+
+        if (view.getShowSequenceFeatures())
+        {
+           af.viewport.showSequenceFeatures = true;
+           af.showSeqFeatures.setSelected(true);
+        }
+
+        if(jms.getFeatureSettings()!=null)
+        {
+          af.viewport.featuresDisplayed = new Hashtable();
+          String [] renderOrder = new String[jms.getFeatureSettings().getSettingCount()];
+         for(int fs=0; fs<jms.getFeatureSettings().getSettingCount(); fs++)
+         {
+           Setting setting = jms.getFeatureSettings().getSetting(fs);
+
+           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(setting.getType(),
+               new java.awt.Color(setting.getColour()));
+
+           renderOrder[fs] = setting.getType();
+
+           if(setting.getDisplay())
+             af.viewport.featuresDisplayed.put(
+                 setting.getType(), new Integer(setting.getColour()));
+         }
+         af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
+        }
+
+        if (view.getHiddenColumnsCount() > 0)
+        {
+          for (int c = 0; c < view.getHiddenColumnsCount(); c++)
+          {
+              af.viewport.hideColumns(
+                view.getHiddenColumns(c).getStart(),
+                view.getHiddenColumns(c).getEnd() //+1
+                );
+          }
+        }
+
+
+        Desktop.addInternalFrame(af, view.getTitle(),
+             view.getWidth(), view.getHeight());
+
+        //LOAD TREES
+        ///////////////////////////////////////
+        if (jms.getTreeCount() > 0)
+        {
+            try
+            {
+                for (int t = 0; t < jms.getTreeCount(); t++)
+                {
+
+                    Tree tree = jms.getTree(t);
+
+                    TreePanel tp = af.ShowNewickTree(new jalview.io.NewickFile(
+                                tree.getNewick()), tree.getTitle(),
+                                tree.getWidth(), tree.getHeight(),
+                                tree.getXpos(), tree.getYpos());
+
+                    tp.fitToWindow.setState(tree.getFitToWindow());
+                    tp.fitToWindow_actionPerformed(null);
+
+                    if(tree.getFontName()!=null)
+                      tp.setTreeFont(new java.awt.Font(tree.getFontName(),
+                                          tree.getFontStyle(),
+                                          tree.getFontSize()));
+                    else
+                      tp.setTreeFont(new java.awt.Font(view.getFontName(),
+                                            view.getFontStyle(),
+                                            tree.getFontSize()));
+
+                    tp.showPlaceholders(tree.getMarkUnlinked());
+                    tp.showBootstrap(tree.getShowBootstrap());
+                    tp.showDistances(tree.getShowDistances());
+
+                    tp.treeCanvas.threshold = tree.getThreshold();
+
+                    if (tree.getCurrentTree())
+                      af.viewport.setCurrentTree(tp.getTree());
+                }
+
+            }
+            catch (Exception ex)
+            {
+                ex.printStackTrace();
+            }
+
+        }
+
+        return af;
+    }
+}
+
index d3f513b..ff87630 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.awt.image.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class OverviewPanel extends JPanel implements Runnable\r
-{\r
-    BufferedImage miniMe;\r
-    AlignViewport av;\r
-    AlignmentPanel ap;\r
-    float scalew = 1f;\r
-    float scaleh = 1f;\r
-    int width;\r
-    int sequencesHeight;\r
-    int graphHeight = 20;\r
-    int boxX = -1;\r
-    int boxY = -1;\r
-    int boxWidth = -1;\r
-    int boxHeight = -1;\r
-    boolean resizing = false;\r
-\r
-    // Can set different properties in this seqCanvas than\r
-    // main visible SeqCanvas\r
-    SequenceRenderer sr;\r
-    FeatureRenderer fr;\r
-\r
-    /**\r
-     * Creates a new OverviewPanel object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     */\r
-    public OverviewPanel(AlignmentPanel ap)\r
-    {\r
-        this.av = ap.av;\r
-        this.ap = ap;\r
-        setLayout(null);\r
-\r
-        sr = new SequenceRenderer(av);\r
-        sr.renderGaps = false;\r
-        sr.forOverview = true;\r
-        fr = new FeatureRenderer(av);\r
-\r
-        // scale the initial size of overviewpanel to shape of alignment\r
-        float initialScale = (float) av.alignment.getWidth() / (float) av.alignment.getHeight();\r
-\r
-        if(av.conservation==null)\r
-          graphHeight = 0;\r
-\r
-\r
-        if (av.alignment.getWidth() > av.alignment.getHeight())\r
-        {\r
-            // wider\r
-            width = 400;\r
-            sequencesHeight = (int) (400f / initialScale);\r
-            if(sequencesHeight<40)\r
-              sequencesHeight = 40;\r
-        }\r
-        else\r
-        {\r
-            // taller\r
-            width = (int) (400f * initialScale);\r
-            sequencesHeight = 300;\r
-\r
-            if (width < 120)\r
-            {\r
-                width = 120;\r
-            }\r
-        }\r
-\r
-        addComponentListener(new ComponentAdapter()\r
-            {\r
-                public void componentResized(ComponentEvent evt)\r
-                {\r
-                    if ((getWidth() != width) ||\r
-                            (getHeight() != (sequencesHeight + graphHeight)))\r
-                    {\r
-                        updateOverviewImage();\r
-                    }\r
-                }\r
-            });\r
-\r
-        addMouseMotionListener(new MouseMotionAdapter()\r
-            {\r
-                public void mouseDragged(MouseEvent evt)\r
-                {\r
-                  if(!av.wrapAlignment)\r
-                    doMouseDragged(evt);\r
-                }\r
-            });\r
-\r
-        addMouseListener(new MouseAdapter()\r
-            {\r
-                public void mousePressed(MouseEvent evt)\r
-                {\r
-                  if(!av.wrapAlignment)\r
-                    doMousePressed(evt);\r
-                }\r
-\r
-                public void mouseReleased(MouseEvent evt)\r
-                {\r
-                  if(!av.wrapAlignment)\r
-                    doMouseReleased(evt);\r
-                }\r
-            });\r
-\r
-        updateOverviewImage();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void doMousePressed(MouseEvent evt)\r
-    {\r
-        boxX = evt.getX();\r
-        boxY = evt.getY();\r
-\r
-        checkValid();\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void doMouseReleased(MouseEvent evt)\r
-    {\r
-        boxX = evt.getX();\r
-        boxY = evt.getY();\r
-        checkValid();\r
-\r
-        if(av.hasHiddenColumns)\r
-        {\r
-          int col = (int) ( boxX / scalew / av.getCharWidth());\r
-\r
-          if(av.getColumnSelection().isVisible(col))\r
-          {\r
-            ap.setScrollValues(\r
-                av.getColumnSelection().findColumnPosition(col),\r
-                (int) (boxY / scaleh / av.getCharHeight()));\r
-          }\r
-          else\r
-            System.out.println(col +" not visible");\r
-        }\r
-        else\r
-          ap.setScrollValues( (int) (boxX / scalew / av.getCharWidth()),\r
-                            (int) (boxY / scaleh / av.getCharHeight()));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void doMouseDragged(MouseEvent evt)\r
-    {\r
-        boxX = evt.getX();\r
-        boxY = evt.getY();\r
-        checkValid();\r
-\r
-        if(av.hasHiddenColumns)\r
-        {\r
-          int col = (int) ( boxX / scalew / av.getCharWidth());\r
-\r
-          if(!av.getColumnSelection().isVisible(col))\r
-          {\r
-            return;\r
-          }\r
-\r
-            ap.setScrollValues(\r
-               av.getColumnSelection().findColumnPosition( col ),\r
-                (int) (boxY / scaleh / av.getCharHeight()));\r
-        }\r
-        else\r
-        ap.setScrollValues( (int) (boxX / scalew / av.getCharWidth()),\r
-                            (int) (boxY / scaleh / av.getCharHeight()));\r
-       repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    void checkValid()\r
-    {\r
-        if (boxY < 0)\r
-        {\r
-            boxY = 0;\r
-        }\r
-\r
-        if (boxY > (sequencesHeight - boxHeight))\r
-        {\r
-            boxY = sequencesHeight - boxHeight + 1;\r
-        }\r
-\r
-        if (boxX < 0)\r
-        {\r
-            boxX = 0;\r
-        }\r
-\r
-        if (boxX > (width - boxWidth))\r
-        {\r
-          if(av.hasHiddenColumns)\r
-          {\r
-            //Try smallest possible box\r
-            boxWidth = (int) ( (av.endRes - av.startRes + 1) *\r
-                                   av.getCharWidth() * scalew);\r
-          }\r
-\r
-          boxX = width - boxWidth;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void updateOverviewImage()\r
-    {\r
-        if (resizing)\r
-        {\r
-            resizeAgain = true;\r
-            return;\r
-        }\r
-\r
-        resizing = true;\r
-\r
-        if ( (getWidth() > 0) && (getHeight() > 0))\r
-        {\r
-          width = getWidth();\r
-          sequencesHeight = getHeight() - graphHeight;\r
-        }\r
-\r
-        setPreferredSize(new Dimension(width, sequencesHeight + graphHeight));\r
-\r
-        Thread thread = new Thread(this);\r
-        thread.start();\r
-        repaint();\r
-    }\r
-\r
-    // This is set true if the user resizes whilst\r
-    // the overview is being calculated\r
-    boolean resizeAgain = false;\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void run()\r
-    {\r
-        miniMe = null;\r
-\r
-       if (av.showSequenceFeatures)\r
-       {\r
-         fr.transferSettings( ap.seqPanel.seqCanvas.getFeatureRenderer() );\r
-       }\r
-\r
-        int alwidth = av.alignment.getWidth();\r
-        int alheight = av.alignment.getHeight()\r
-            +av.alignment.getHiddenSequences().getSize();\r
-\r
-        setPreferredSize(new Dimension(width, sequencesHeight + graphHeight));\r
-\r
-        int fullsizeWidth = alwidth * av.getCharWidth();\r
-        int fullsizeHeight = alheight * av.getCharHeight();\r
-\r
-        scalew = (float) width / (float) fullsizeWidth;\r
-        scaleh = (float) sequencesHeight / (float) fullsizeHeight;\r
-\r
-        miniMe = new BufferedImage(width, sequencesHeight + graphHeight,\r
-                BufferedImage.TYPE_INT_RGB);\r
-\r
-\r
-        Graphics mg = miniMe.getGraphics();\r
-        mg.setColor(Color.orange);\r
-        mg.fillRect(0,0,width, miniMe.getHeight());\r
-\r
-        float sampleCol = (float) alwidth / (float) width;\r
-        float sampleRow = (float) alheight / (float) sequencesHeight;\r
-\r
-        int lastcol=-1, lastrow=-1;\r
-        int color = Color.white.getRGB();\r
-        int row, col;\r
-        jalview.datamodel.SequenceI seq;\r
-        boolean hiddenRow = false;\r
-        for (row = 0; row < sequencesHeight; row++)\r
-        {\r
-          if((int)(row*sampleRow)==lastrow)\r
-          {\r
-            //No need to recalculate the colours,\r
-            //Just copy from the row above\r
-            for (col = 0; col < width; col++)\r
-            {\r
-              miniMe.setRGB(col, row, miniMe.getRGB(col, row-1));\r
-            }\r
-            continue;\r
-          }\r
-\r
-          lastrow = (int)(row*sampleRow);\r
-\r
-          hiddenRow = false;\r
-          if (av.hasHiddenRows)\r
-          {\r
-            seq = av.alignment.getHiddenSequences().getHiddenSequence(lastrow);\r
-            if (seq == null)\r
-            {\r
-\r
-              int index =\r
-                 av.alignment.getHiddenSequences().findIndexWithoutHiddenSeqs(lastrow);\r
-\r
-\r
-             seq = av.alignment.getSequenceAt(index);\r
-            }\r
-            else\r
-            {\r
-              hiddenRow = true;\r
-            }\r
-          }\r
-          else\r
-            seq = av.alignment.getSequenceAt(lastrow);\r
-\r
-          if(seq==null)\r
-          {\r
-            System.out.println(lastrow+" null");\r
-            continue;\r
-          }\r
-\r
-            for (col = 0; col < width; col++)\r
-            {\r
-            if((int)(col*sampleCol) == lastcol && (int)(row*sampleRow)==lastrow)\r
-            {\r
-              miniMe.setRGB(col,row,color);\r
-              continue;\r
-            }\r
-\r
-\r
-            lastcol = (int)(col*sampleCol);\r
-\r
-            if (seq.getLength() > lastcol)\r
-            {\r
-              color = sr.getResidueBoxColour(\r
-                  seq, lastcol).getRGB();\r
-\r
-              if (av.showSequenceFeatures)\r
-                color = fr.findFeatureColour(color, lastrow, lastcol);\r
-            }\r
-            else\r
-            {\r
-              color = -1; //White\r
-            }\r
-\r
-            if(hiddenRow ||\r
-               (av.hasHiddenColumns && !av.getColumnSelection().isVisible(lastcol)))\r
-            {\r
-              color = new Color(color).darker().darker().getRGB();\r
-            }\r
-\r
-\r
-            miniMe.setRGB(col,row,color);\r
-\r
-\r
-          }\r
-        }\r
-\r
-        if (av.conservation != null)\r
-        {\r
-          for (col = 0; col < width; col++)\r
-          {\r
-            lastcol = (int) (col * sampleCol);\r
-            {\r
-              mg.translate(col, sequencesHeight);\r
-              ap.annotationPanel.drawGraph(mg, av.conservation,\r
-                                           (int) (sampleCol) + 1,\r
-                                           graphHeight,\r
-                                           (int) (col * sampleCol),\r
-                                           (int) (col * sampleCol) + 1);\r
-              mg.translate( -col, -sequencesHeight);\r
-            }\r
-          }\r
-        }\r
-        System.gc();\r
-\r
-        resizing = false;\r
-\r
-        setBoxPosition();\r
-\r
-        if(resizeAgain)\r
-        {\r
-          resizeAgain = false;\r
-          updateOverviewImage();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void setBoxPosition()\r
-    {\r
-      int fullsizeWidth = av.alignment.getWidth() * av.getCharWidth();\r
-      int fullsizeHeight = (av.alignment.getHeight()\r
-                   +av.alignment.getHiddenSequences().getSize()) * av.getCharHeight();\r
-\r
-      int startRes = av.getStartRes();\r
-      int endRes = av.getEndRes();\r
-\r
-      if(av.hasHiddenColumns)\r
-      {\r
-        startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);\r
-        endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);\r
-      }\r
-\r
-\r
-      scalew = (float) width / (float) fullsizeWidth;\r
-      scaleh = (float) sequencesHeight / (float) fullsizeHeight;\r
-\r
-        boxX = (int) (startRes * av.getCharWidth() * scalew);\r
-        boxY = (int) (av.getStartSeq() * av.getCharHeight() * scaleh);\r
-\r
-        if(av.hasHiddenColumns)\r
-          boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);\r
-        else\r
-          boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);\r
-\r
-        boxHeight = (int) (av.getEndSeq() * av.getCharHeight() * scaleh) -\r
-            boxY;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        if (miniMe != null && !resizing)\r
-        {\r
-          g.drawImage(miniMe, 0, 0, this);\r
-        }\r
-        else\r
-        {\r
-          g.setColor(Color.white);\r
-          g.fillRect(0, 0, getWidth(), getHeight());\r
-          g.setColor(Color.black);\r
-          g.setFont(new Font("Verdana", Font.BOLD, 15));\r
-          g.drawString("Recalculating", 5, sequencesHeight / 2);\r
-          g.drawString("Overview.....", 5, (sequencesHeight / 2) + 20);\r
-        }\r
-\r
-\r
-        g.setColor(Color.red);\r
-        g.drawRect(boxX, boxY, boxWidth, boxHeight);\r
-        g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);\r
-\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class OverviewPanel extends JPanel implements Runnable
+{
+    BufferedImage miniMe;
+    AlignViewport av;
+    AlignmentPanel ap;
+    float scalew = 1f;
+    float scaleh = 1f;
+    int width;
+    int sequencesHeight;
+    int graphHeight = 20;
+    int boxX = -1;
+    int boxY = -1;
+    int boxWidth = -1;
+    int boxHeight = -1;
+    boolean resizing = false;
+
+    // Can set different properties in this seqCanvas than
+    // main visible SeqCanvas
+    SequenceRenderer sr;
+    FeatureRenderer fr;
+
+    /**
+     * Creates a new OverviewPanel object.
+     *
+     * @param ap DOCUMENT ME!
+     */
+    public OverviewPanel(AlignmentPanel ap)
+    {
+        this.av = ap.av;
+        this.ap = ap;
+        setLayout(null);
+
+        sr = new SequenceRenderer(av);
+        sr.renderGaps = false;
+        sr.forOverview = true;
+        fr = new FeatureRenderer(av);
+
+        // scale the initial size of overviewpanel to shape of alignment
+        float initialScale = (float) av.alignment.getWidth() / (float) av.alignment.getHeight();
+
+        if(av.conservation==null)
+          graphHeight = 0;
+
+
+        if (av.alignment.getWidth() > av.alignment.getHeight())
+        {
+            // wider
+            width = 400;
+            sequencesHeight = (int) (400f / initialScale);
+            if(sequencesHeight<40)
+              sequencesHeight = 40;
+        }
+        else
+        {
+            // taller
+            width = (int) (400f * initialScale);
+            sequencesHeight = 300;
+
+            if (width < 120)
+            {
+                width = 120;
+            }
+        }
+
+        addComponentListener(new ComponentAdapter()
+            {
+                public void componentResized(ComponentEvent evt)
+                {
+                    if ((getWidth() != width) ||
+                            (getHeight() != (sequencesHeight + graphHeight)))
+                    {
+                        updateOverviewImage();
+                    }
+                }
+            });
+
+        addMouseMotionListener(new MouseMotionAdapter()
+            {
+                public void mouseDragged(MouseEvent evt)
+                {
+                  if (!av.wrapAlignment)
+                  {
+                    boxX = evt.getX();
+                    boxY = evt.getY();
+                    checkValid();
+                  }
+                }
+            });
+
+        addMouseListener(new MouseAdapter()
+            {
+                public void mousePressed(MouseEvent evt)
+                {
+                  if(!av.wrapAlignment)
+                  {
+                    boxX = evt.getX();
+                    boxY = evt.getY();
+                    checkValid();
+                  }
+                }
+            });
+
+        updateOverviewImage();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     */
+    void checkValid()
+    {
+        if (boxY < 0)
+        {
+            boxY = 0;
+        }
+
+        if (boxY > (sequencesHeight - boxHeight))
+        {
+            boxY = sequencesHeight - boxHeight + 1;
+        }
+
+        if (boxX < 0)
+        {
+            boxX = 0;
+        }
+
+        if (boxX > (width - boxWidth))
+        {
+          if(av.hasHiddenColumns)
+          {
+            //Try smallest possible box
+            boxWidth = (int) ( (av.endRes - av.startRes + 1) *
+                                   av.getCharWidth() * scalew);
+          }
+          boxX = width - boxWidth;
+        }
+
+        int col = (int) (boxX / scalew / av.getCharWidth());
+        int row = (int) (boxY / scaleh / av.getCharHeight());
+
+        if (av.hasHiddenColumns)
+        {
+          if (!av.getColumnSelection().isVisible(col))
+          {
+            return;
+          }
+
+          col = av.getColumnSelection().findColumnPosition(col);
+        }
+
+        if( av.hasHiddenRows )
+        {
+          row = av.alignment.getHiddenSequences().findIndexWithoutHiddenSeqs(row);
+        }
+
+        ap.setScrollValues( col, row );
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void updateOverviewImage()
+    {
+        if (resizing)
+        {
+            resizeAgain = true;
+            return;
+        }
+
+        resizing = true;
+
+        if ( (getWidth() > 0) && (getHeight() > 0))
+        {
+          width = getWidth();
+          sequencesHeight = getHeight() - graphHeight;
+        }
+
+        setPreferredSize(new Dimension(width, sequencesHeight + graphHeight));
+
+        Thread thread = new Thread(this);
+        thread.start();
+        repaint();
+    }
+
+    // This is set true if the user resizes whilst
+    // the overview is being calculated
+    boolean resizeAgain = false;
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void run()
+    {
+        miniMe = null;
+
+       if (av.showSequenceFeatures)
+       {
+         fr.transferSettings( ap.seqPanel.seqCanvas.getFeatureRenderer() );
+       }
+
+        int alwidth = av.alignment.getWidth();
+        int alheight = av.alignment.getHeight()
+            +av.alignment.getHiddenSequences().getSize();
+
+        setPreferredSize(new Dimension(width, sequencesHeight + graphHeight));
+
+        int fullsizeWidth = alwidth * av.getCharWidth();
+        int fullsizeHeight = alheight * av.getCharHeight();
+
+        scalew = (float) width / (float) fullsizeWidth;
+        scaleh = (float) sequencesHeight / (float) fullsizeHeight;
+
+        miniMe = new BufferedImage(width, sequencesHeight + graphHeight,
+                BufferedImage.TYPE_INT_RGB);
+
+
+        Graphics mg = miniMe.getGraphics();
+        mg.setColor(Color.orange);
+        mg.fillRect(0,0,width, miniMe.getHeight());
+
+        float sampleCol = (float) alwidth / (float) width;
+        float sampleRow = (float) alheight / (float) sequencesHeight;
+
+        int lastcol=-1, lastrow=-1;
+        int color = Color.white.getRGB();
+        int row, col;
+        jalview.datamodel.SequenceI seq;
+        boolean hiddenRow = false;
+        for (row = 0; row < sequencesHeight; row++)
+        {
+          if((int)(row*sampleRow)==lastrow)
+          {
+            //No need to recalculate the colours,
+            //Just copy from the row above
+            for (col = 0; col < width; col++)
+            {
+              miniMe.setRGB(col, row, miniMe.getRGB(col, row-1));
+            }
+            continue;
+          }
+
+          lastrow = (int)(row*sampleRow);
+
+          hiddenRow = false;
+          if (av.hasHiddenRows)
+          {
+            seq = av.alignment.getHiddenSequences().getHiddenSequence(lastrow);
+            if (seq == null)
+            {
+              int index =
+                 av.alignment.getHiddenSequences().findIndexWithoutHiddenSeqs(lastrow);
+
+             seq = av.alignment.getSequenceAt(index);
+            }
+            else
+            {
+              hiddenRow = true;
+            }
+          }
+          else
+            seq = av.alignment.getSequenceAt(lastrow);
+
+          if(seq==null)
+          {
+            System.out.println(lastrow+" null");
+            continue;
+          }
+
+            for (col = 0; col < width; col++)
+            {
+            if((int)(col*sampleCol) == lastcol && (int)(row*sampleRow)==lastrow)
+            {
+              miniMe.setRGB(col,row,color);
+              continue;
+            }
+
+
+            lastcol = (int)(col*sampleCol);
+
+            if (seq.getLength() > lastcol)
+            {
+              color = sr.getResidueBoxColour(
+                  seq, lastcol).getRGB();
+
+              if (av.showSequenceFeatures)
+                color = fr.findFeatureColour(color, seq, lastcol);
+            }
+            else
+            {
+              color = -1; //White
+            }
+
+            if(hiddenRow ||
+               (av.hasHiddenColumns && !av.getColumnSelection().isVisible(lastcol)))
+            {
+              color = new Color(color).darker().darker().getRGB();
+            }
+
+
+            miniMe.setRGB(col,row,color);
+
+
+          }
+        }
+
+        if (av.conservation != null)
+        {
+          for (col = 0; col < width; col++)
+          {
+            lastcol = (int) (col * sampleCol);
+            {
+              mg.translate(col, sequencesHeight);
+              ap.annotationPanel.drawGraph(mg, av.conservation,
+                                           (int) (sampleCol) + 1,
+                                           graphHeight,
+                                           (int) (col * sampleCol),
+                                           (int) (col * sampleCol) + 1);
+              mg.translate( -col, -sequencesHeight);
+            }
+          }
+        }
+        System.gc();
+
+        resizing = false;
+
+        setBoxPosition();
+
+        if(resizeAgain)
+        {
+          resizeAgain = false;
+          updateOverviewImage();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void setBoxPosition()
+    {
+      int fullsizeWidth = av.alignment.getWidth() * av.getCharWidth();
+      int fullsizeHeight = (av.alignment.getHeight()
+                   +av.alignment.getHiddenSequences().getSize()) * av.getCharHeight();
+
+      int startRes = av.getStartRes();
+      int endRes = av.getEndRes();
+
+      if(av.hasHiddenColumns)
+      {
+        startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
+        endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
+      }
+
+      int startSeq = av.startSeq;
+      int endSeq = av.endSeq;
+
+      if (av.hasHiddenRows)
+      {
+        startSeq =
+            av.alignment.getHiddenSequences().adjustForHiddenSeqs(startSeq);
+
+        endSeq =
+            av.alignment.getHiddenSequences().adjustForHiddenSeqs(endSeq);
+
+      }
+
+
+      scalew = (float) width / (float) fullsizeWidth;
+      scaleh = (float) sequencesHeight / (float) fullsizeHeight;
+
+        boxX = (int) (startRes * av.getCharWidth() * scalew);
+        boxY = (int) (startSeq * av.getCharHeight() * scaleh);
+
+
+
+        if(av.hasHiddenColumns)
+          boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
+        else
+          boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
+
+
+        boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
+
+
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+        if (miniMe != null && !resizing)
+        {
+          g.drawImage(miniMe, 0, 0, this);
+        }
+        else
+        {
+          g.setColor(Color.white);
+          g.fillRect(0, 0, getWidth(), getHeight());
+          g.setColor(Color.black);
+          g.setFont(new Font("Verdana", Font.BOLD, 15));
+          g.drawString("Recalculating", 5, sequencesHeight / 2);
+          g.drawString("Overview.....", 5, (sequencesHeight / 2) + 20);
+        }
+
+
+        g.setColor(Color.red);
+        g.drawRect(boxX, boxY, boxWidth, boxHeight);
+        g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
+
+    }
+}
index e680dde..49b5f90 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.util.*;\r
-import javax.swing.*;\r
-import java.awt.print.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class PCAPanel extends GPCAPanel implements Runnable\r
-{\r
-    PCA pca;\r
-    int top;\r
-    RotatableCanvas rc;\r
-    AlignViewport av;\r
-    SequenceI [] seqs;\r
-\r
-    /**\r
-     * Creates a new PCAPanel object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     * @param s DOCUMENT ME!\r
-     */\r
-    public PCAPanel(AlignViewport av)\r
-    {\r
-        this.av = av;\r
-\r
-        boolean sameLength = true;\r
-\r
-        if ((av.getSelectionGroup() != null) &&\r
-                (av.getSelectionGroup().getSize() > 3))\r
-        {\r
-            seqs = new Sequence[av.getSelectionGroup().getSize()];\r
-            int length = av.getSelectionGroup().getSequenceAt(0).getLength();\r
-            for (int i = 0; i < av.getSelectionGroup().getSize(); i++)\r
-            {\r
-                seqs[i] = av.getSelectionGroup().getSequenceAt(i);\r
-                if(seqs[i].getLength()!=length)\r
-                {\r
-                  sameLength = false;\r
-                  break;\r
-                }\r
-            }\r
-        }\r
-        else\r
-        {\r
-            seqs = new Sequence[av.getAlignment().getHeight()];\r
-            int length = av.alignment.getSequenceAt(0).getLength();\r
-\r
-            for (int i = 0; i < av.getAlignment().getHeight(); i++)\r
-            {\r
-                seqs[i] = av.getAlignment().getSequenceAt(i);\r
-                if(seqs[i].getLength()!=length)\r
-               {\r
-                 sameLength = false;\r
-                 break;\r
-               }\r
-\r
-            }\r
-        }\r
-\r
-        if (!sameLength)\r
-        {\r
-          JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                        "The sequences must be aligned before calculating PCA.\n" +\r
-                                        "Try using the Pad function in the edit menu,\n" +\r
-                                        "or one of the multiple sequence alignment web services.",\r
-                                        "Sequences not aligned",\r
-                                        JOptionPane.WARNING_MESSAGE);\r
-\r
-          return;\r
-        }\r
-\r
-\r
-        Desktop.addInternalFrame(this, "Principal component analysis",\r
-                               400, 400);\r
-\r
-\r
-        rc = new RotatableCanvas(av);\r
-        this.getContentPane().add(rc, BorderLayout.CENTER);\r
-        Thread worker = new Thread(this);\r
-        worker.start();\r
-    }\r
-\r
-    public void bgcolour_actionPerformed(ActionEvent e)\r
-    {\r
-      Color col = JColorChooser.showDialog(this, "Select Background Colour",\r
-                rc.bgColour);\r
-\r
-      if(col!=null)\r
-        rc.bgColour = col;\r
-      rc.repaint();\r
-    }\r
-\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void run()\r
-    {\r
-      try{\r
-        pca = new PCA(seqs);\r
-        pca.run();\r
-\r
-        // Now find the component coordinates\r
-        int ii = 0;\r
-\r
-        while ( (ii < seqs.length) && (seqs[ii] != null))\r
-        {\r
-          ii++;\r
-        }\r
-\r
-        double[][] comps = new double[ii][ii];\r
-\r
-        for (int i = 0; i < ii; i++)\r
-        {\r
-          if (pca.getEigenvalue(i) > 1e-4)\r
-          {\r
-            comps[i] = pca.component(i);\r
-          }\r
-        }\r
-\r
-        //////////////////\r
-        xCombobox.setSelectedIndex(0);\r
-        yCombobox.setSelectedIndex(1);\r
-        zCombobox.setSelectedIndex(2);\r
-\r
-        top = pca.getM().rows - 1;\r
-\r
-        Vector points = new Vector();\r
-        float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);\r
-\r
-        for (int i = 0; i < pca.getM().rows; i++)\r
-        {\r
-          SequencePoint sp = new SequencePoint(seqs[i], scores[i]);\r
-          points.addElement(sp);\r
-        }\r
-\r
-        rc.setPoints(points, pca.getM().rows);\r
-        rc.repaint();\r
-        seqs = null;\r
-      }\r
-     catch(OutOfMemoryError er)\r
-      { JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                              "Out of memory calculating PCA!!"\r
-                                              +\r
-                                              "\nSee help files for increasing Java Virtual Machine memory."\r
-                                              , "Out of memory",\r
-                                              JOptionPane.WARNING_MESSAGE);\r
-        System.out.println("PCAPanel: "+er);\r
-        System.gc();\r
-\r
-      }\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    void doDimensionChange()\r
-    {\r
-        if (top == 0)\r
-        {\r
-            return;\r
-        }\r
-\r
-        int dim1 = top - xCombobox.getSelectedIndex();\r
-        int dim2 = top - yCombobox.getSelectedIndex();\r
-        int dim3 = top - zCombobox.getSelectedIndex();\r
-\r
-        float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);\r
-\r
-        for (int i = 0; i < pca.getM().rows; i++)\r
-        {\r
-            ((SequencePoint) rc.points.elementAt(i)).coord = scores[i];\r
-        }\r
-\r
-        rc.img = null;\r
-        rc.rotmat.setIdentity();\r
-        rc.initAxes();\r
-        rc.paint(rc.getGraphics());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void xCombobox_actionPerformed(ActionEvent e)\r
-    {\r
-        doDimensionChange();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void yCombobox_actionPerformed(ActionEvent e)\r
-    {\r
-        doDimensionChange();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void zCombobox_actionPerformed(ActionEvent e)\r
-    {\r
-        doDimensionChange();\r
-    }\r
-\r
-\r
-    public void outputValues_actionPerformed(ActionEvent e)\r
-    {\r
-      CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
-      Desktop.addInternalFrame(cap, "PCA details", 500,\r
-                500);\r
-\r
-      cap.setText(pca.getDetails());\r
-     }\r
-\r
-    public void showLabels_actionPerformed(ActionEvent e)\r
-    {\r
-      rc.showLabels(showLabels.getState());\r
-    }\r
-\r
-    public void print_actionPerformed(ActionEvent e)\r
-    {\r
-      PCAPrinter printer = new PCAPrinter();\r
-      printer.start();\r
-    }\r
-\r
-\r
-    class PCAPrinter extends Thread implements Printable\r
-    {\r
-      public void run()\r
-      {\r
-        PrinterJob printJob = PrinterJob.getPrinterJob();\r
-        PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
-\r
-        printJob.setPrintable(this, pf);\r
-\r
-        if (printJob.printDialog())\r
-        {\r
-          try\r
-          {\r
-            printJob.print();\r
-          }\r
-          catch (Exception PrintException)\r
-          {\r
-            PrintException.printStackTrace();\r
-          }\r
-        }\r
-      }\r
-\r
-      public int print(Graphics pg, PageFormat pf, int pi)\r
-          throws PrinterException\r
-      {\r
-        pg.translate( (int) pf.getImageableX(), (int) pf.getImageableY());\r
-\r
-        rc.drawBackground(pg, rc.bgColour);\r
-        rc.drawScene(pg);\r
-        if (rc.drawAxes == true)\r
-        {\r
-          rc.drawAxes(pg);\r
-        }\r
-\r
-        if (pi == 0)\r
-          return Printable.PAGE_EXISTS;\r
-        else\r
-          return Printable.NO_SUCH_PAGE;\r
-      }\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void eps_actionPerformed(ActionEvent e)\r
-    {\r
-      makePCAImage(jalview.util.ImageMaker.EPS);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void png_actionPerformed(ActionEvent e)\r
-    {\r
-       makePCAImage(jalview.util.ImageMaker.PNG);\r
-    }\r
-\r
-    void makePCAImage(int type)\r
-    {\r
-      int width = rc.getWidth();\r
-      int height = rc.getHeight();\r
-\r
-      jalview.util.ImageMaker im;\r
-\r
-      if(type == jalview.util.ImageMaker.PNG)\r
-        im = new jalview.util.ImageMaker(this,\r
-                                         jalview.util.ImageMaker.PNG,\r
-                                         "Make PNG image from PCA",\r
-                                         width, height,\r
-                                         null, null);\r
-        else\r
-          im = new jalview.util.ImageMaker(this,\r
-                                 jalview.util.ImageMaker.EPS,\r
-                                 "Make EPS file from PCA",\r
-                                 width, height,\r
-                                 null, this.getTitle());\r
-\r
-      if(im.getGraphics()!=null)\r
-       {\r
-         rc.drawBackground(im.getGraphics(), Color.black);\r
-         rc.drawScene(im.getGraphics());\r
-         if (rc.drawAxes == true)\r
-         {\r
-           rc.drawAxes(im.getGraphics());\r
-         }\r
-         im.writeImage();\r
-       }\r
-    }\r
-  }\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.analysis.*;
+
+import jalview.datamodel.*;
+
+import jalview.jbgui.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import java.util.*;
+import javax.swing.*;
+import java.awt.print.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class PCAPanel extends GPCAPanel implements Runnable
+{
+    PCA pca;
+    int top;
+    RotatableCanvas rc;
+    AlignViewport av;
+    AlignmentView seqstrings;
+    SequenceI  [] seqs;
+
+    /**
+     * Creates a new PCAPanel object.
+     *
+     * @param av DOCUMENT ME!
+     * @param s DOCUMENT ME!
+     */
+    public PCAPanel(AlignViewport av)
+    {
+        this.av = av;
+
+        boolean sameLength = true;
+
+        seqstrings = av.getAlignmentView(av.getSelectionGroup()!=null);
+        if(av.getSelectionGroup()==null)
+        {
+          seqs = av.alignment.getSequencesArray();
+        }
+        else
+        {
+          seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+        }
+        SeqCigar sq[]=seqstrings.getSequences();
+        int length = sq[0].getWidth();
+
+        for (int i = 0; i < seqs.length; i++)
+        {
+          if (sq[i].getWidth() != length)
+          {
+            sameLength = false;
+            break;
+          }
+        }
+
+        if (!sameLength)
+        {
+          JOptionPane.showMessageDialog(Desktop.desktop,
+                                        "The sequences must be aligned before calculating PCA.\n" +
+                                        "Try using the Pad function in the edit menu,\n" +
+                                        "or one of the multiple sequence alignment web services.",
+                                        "Sequences not aligned",
+                                        JOptionPane.WARNING_MESSAGE);
+
+          return;
+        }
+
+
+        Desktop.addInternalFrame(this, "Principal component analysis",
+                               400, 400);
+
+
+        rc = new RotatableCanvas(av);
+        this.getContentPane().add(rc, BorderLayout.CENTER);
+        Thread worker = new Thread(this);
+        worker.start();
+    }
+
+    public void bgcolour_actionPerformed(ActionEvent e)
+    {
+      Color col = JColorChooser.showDialog(this, "Select Background Colour",
+                rc.bgColour);
+
+      if(col!=null)
+        rc.bgColour = col;
+      rc.repaint();
+    }
+
+
+
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void run()
+    {
+      try{
+        pca = new PCA(seqstrings.getSequenceStrings(' '));
+        pca.run();
+
+        // Now find the component coordinates
+        int ii = 0;
+
+        while ( (ii < seqs.length) && (seqs[ii] != null))
+        {
+          ii++;
+        }
+
+        double[][] comps = new double[ii][ii];
+
+        for (int i = 0; i < ii; i++)
+        {
+          if (pca.getEigenvalue(i) > 1e-4)
+          {
+            comps[i] = pca.component(i);
+          }
+        }
+
+        //////////////////
+        xCombobox.setSelectedIndex(0);
+        yCombobox.setSelectedIndex(1);
+        zCombobox.setSelectedIndex(2);
+
+        top = pca.getM().rows - 1;
+
+        Vector points = new Vector();
+        float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);
+
+        for (int i = 0; i < pca.getM().rows; i++)
+        {
+          SequencePoint sp = new SequencePoint(seqs[i], scores[i]);
+          points.addElement(sp);
+        }
+
+        rc.setPoints(points, pca.getM().rows);
+        rc.repaint();
+      }
+     catch(OutOfMemoryError er)
+      { JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                              "Out of memory calculating PCA!!"
+                                              +
+                                              "\nSee help files for increasing Java Virtual Machine memory."
+                                              , "Out of memory",
+                                              JOptionPane.WARNING_MESSAGE);
+        System.out.println("PCAPanel: "+er);
+        System.gc();
+
+      }
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    void doDimensionChange()
+    {
+        if (top == 0)
+        {
+            return;
+        }
+
+        int dim1 = top - xCombobox.getSelectedIndex();
+        int dim2 = top - yCombobox.getSelectedIndex();
+        int dim3 = top - zCombobox.getSelectedIndex();
+
+        float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);
+
+        for (int i = 0; i < pca.getM().rows; i++)
+        {
+            ((SequencePoint) rc.points.elementAt(i)).coord = scores[i];
+        }
+
+        rc.img = null;
+        rc.rotmat.setIdentity();
+        rc.initAxes();
+        rc.paint(rc.getGraphics());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void xCombobox_actionPerformed(ActionEvent e)
+    {
+        doDimensionChange();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void yCombobox_actionPerformed(ActionEvent e)
+    {
+        doDimensionChange();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void zCombobox_actionPerformed(ActionEvent e)
+    {
+        doDimensionChange();
+    }
+
+
+    public void outputValues_actionPerformed(ActionEvent e)
+    {
+      CutAndPasteTransfer cap = new CutAndPasteTransfer();
+      Desktop.addInternalFrame(cap, "PCA details", 500,
+                500);
+
+      cap.setText(pca.getDetails());
+     }
+
+    public void showLabels_actionPerformed(ActionEvent e)
+    {
+      rc.showLabels(showLabels.getState());
+    }
+
+    public void print_actionPerformed(ActionEvent e)
+    {
+      PCAPrinter printer = new PCAPrinter();
+      printer.start();
+    }
+
+    public void originalSeqData_actionPerformed(ActionEvent e)
+    {
+      // this was cut'n'pasted from the equivalent TreePanel method - we should make this an abstract function of all jalview analysis windows
+      if (seqstrings==null)
+      {
+        jalview.bin.Cache.log.info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
+        return;
+      }
+      // decide if av alignment is sufficiently different to original data to warrant a new window to be created
+      // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)
+      // or create a selection box around columns in alignment view
+      // test Alignment(SeqCigar[])
+      Object[] alAndColsel = seqstrings.getAlignmentAndColumnSelection(av.
+          getGapCharacter());
+
+
+      if (alAndColsel != null && alAndColsel[0]!=null)
+      {
+          // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
+
+          Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
+          Alignment dataset = av.getAlignment().getDataset();
+          if (dataset != null)
+          {
+            al.setDataset(dataset);
+          }
+
+          if (true)
+          {
+              // make a new frame!
+              AlignFrame af = new AlignFrame(al, (ColumnSelection) alAndColsel[1]);
+
+              //>>>This is a fix for the moment, until a better solution is found!!<<<
+              // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
+
+              //           af.addSortByOrderMenuItem(ServiceName + " Ordering",
+              //                                     msaorder);
+
+              Desktop.addInternalFrame(af, "Original Data for " + this.title,
+                                       AlignFrame.NEW_WINDOW_WIDTH,
+                                       AlignFrame.NEW_WINDOW_HEIGHT);
+            }
+          }
+          /*      CutAndPasteTransfer cap = new CutAndPasteTransfer();
+                 for (int i = 0; i < seqs.length; i++)
+                 {
+                   cap.appendText(new jalview.util.Format("%-" + 15 + "s").form(
+            seqs[i].getName()));
+                   cap.appendText(" " + seqstrings[i] + "\n");
+
+                 }
+
+                 Desktop.addInternalFrame(cap, "Original Data",
+                     400, 400);
+           */
+    }
+
+
+
+    class PCAPrinter extends Thread implements Printable
+    {
+      public void run()
+      {
+        PrinterJob printJob = PrinterJob.getPrinterJob();
+        PageFormat pf = printJob.pageDialog(printJob.defaultPage());
+
+        printJob.setPrintable(this, pf);
+
+        if (printJob.printDialog())
+        {
+          try
+          {
+            printJob.print();
+          }
+          catch (Exception PrintException)
+          {
+            PrintException.printStackTrace();
+          }
+        }
+      }
+
+      public int print(Graphics pg, PageFormat pf, int pi)
+          throws PrinterException
+      {
+        pg.translate( (int) pf.getImageableX(), (int) pf.getImageableY());
+
+        rc.drawBackground(pg, rc.bgColour);
+        rc.drawScene(pg);
+        if (rc.drawAxes == true)
+        {
+          rc.drawAxes(pg);
+        }
+
+        if (pi == 0)
+          return Printable.PAGE_EXISTS;
+        else
+          return Printable.NO_SUCH_PAGE;
+      }
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void eps_actionPerformed(ActionEvent e)
+    {
+      makePCAImage(jalview.util.ImageMaker.EPS);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void png_actionPerformed(ActionEvent e)
+    {
+       makePCAImage(jalview.util.ImageMaker.PNG);
+    }
+
+    void makePCAImage(int type)
+    {
+      int width = rc.getWidth();
+      int height = rc.getHeight();
+
+      jalview.util.ImageMaker im;
+
+      if(type == jalview.util.ImageMaker.PNG)
+        im = new jalview.util.ImageMaker(this,
+                                         jalview.util.ImageMaker.PNG,
+                                         "Make PNG image from PCA",
+                                         width, height,
+                                         null, null);
+        else
+          im = new jalview.util.ImageMaker(this,
+                                 jalview.util.ImageMaker.EPS,
+                                 "Make EPS file from PCA",
+                                 width, height,
+                                 null, this.getTitle());
+
+      if(im.getGraphics()!=null)
+       {
+         rc.drawBackground(im.getGraphics(), Color.black);
+         rc.drawScene(im.getGraphics());
+         if (rc.drawAxes == true)
+         {
+           rc.drawAxes(im.getGraphics());
+         }
+         im.writeImage();
+       }
+    }
+  }
index e05f44d..29c71cf 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class PaintRefresher\r
-{\r
-    static Hashtable components = new Hashtable();\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param comp DOCUMENT ME!\r
-     * @param al DOCUMENT ME!\r
-     */\r
-    public static void Register(Component comp, AlignmentI al)\r
-    {\r
-        if (components.containsKey(al))\r
-        {\r
-            Vector comps = (Vector) components.get(al);\r
-            comps.addElement(comp);\r
-        }\r
-        else\r
-        {\r
-            Vector vcoms = new Vector();\r
-            vcoms.addElement(comp);\r
-            components.put(al, vcoms);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param al DOCUMENT ME!\r
-     */\r
-    public static void Refresh(AlignmentI al)\r
-    {\r
-        Refresh(null, al);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     * @param al DOCUMENT ME!\r
-     */\r
-    public static void Refresh(Component c, AlignmentI al)\r
-    {\r
-        Component temp;\r
-        Vector coms = (Vector) components.get(al);\r
-        Enumeration e = coms.elements();\r
-\r
-        while (e.hasMoreElements())\r
-        {\r
-            temp = (Component) e.nextElement();\r
-\r
-            if (!temp.isValid())\r
-            {\r
-                coms.removeElement(temp);\r
-            }\r
-            else if (temp == c)\r
-            {\r
-                continue;\r
-            }\r
-            else\r
-                temp.repaint();\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class PaintRefresher
+{
+    static Hashtable components = new Hashtable();
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param comp DOCUMENT ME!
+     * @param al DOCUMENT ME!
+     */
+    public static void Register(Component comp, AlignmentI al)
+    {
+        if (components.containsKey(al))
+        {
+            Vector comps = (Vector) components.get(al);
+            comps.addElement(comp);
+        }
+        else
+        {
+            Vector vcoms = new Vector();
+            vcoms.addElement(comp);
+            components.put(al, vcoms);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param al DOCUMENT ME!
+     */
+    public static void Refresh(AlignmentI al)
+    {
+        Refresh(null, al);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     * @param al DOCUMENT ME!
+     */
+    public static void Refresh(Component c, AlignmentI al)
+    {
+        Component temp;
+        Vector coms = (Vector) components.get(al);
+        if(coms==null)
+          return;
+
+        Enumeration e = coms.elements();
+
+        while (e.hasMoreElements())
+        {
+            temp = (Component) e.nextElement();
+
+            if (!temp.isValid())
+            {
+                coms.removeElement(temp);
+            }
+            else if (temp == c)
+            {
+                continue;
+            }
+            else
+                temp.repaint();
+        }
+    }
+}
index 31efd84..0076a69 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.event.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class PairwiseAlignPanel extends GPairwiseAlignPanel\r
-{\r
-    Vector sequences = new Vector();\r
-    AlignViewport av;\r
-\r
-    /**\r
-     * Creates a new PairwiseAlignPanel object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     */\r
-    public PairwiseAlignPanel(AlignViewport av)\r
-    {\r
-        super();\r
-        this.av = av;\r
-\r
-        Vector selsubset = new Vector();\r
-\r
-        for (int i = 0, j = av.getSelectionGroup().getSize(); i < j; i++)\r
-        {\r
-            if (av.getAlignment().getSequences().contains(av.getSelectionGroup()\r
-                                                                .getSequenceAt(i)))\r
-            {\r
-                selsubset.add(av.getSelectionGroup().getSequenceAt(i));\r
-            }\r
-        }\r
-\r
-        float[][] scores = new float[selsubset.size()][selsubset.size()];\r
-        double totscore = 0;\r
-        int count = selsubset.size();\r
-\r
-        int acount = 0;\r
-\r
-        for (int i = 1; i < count; i++)\r
-        {\r
-            for (int j = 0; j < i; j++)\r
-            {\r
-                acount++;\r
-\r
-                AlignSeq as = new AlignSeq((SequenceI) selsubset.elementAt(i),\r
-                        (SequenceI) selsubset.elementAt(j), "pep");\r
-                as.calcScoreMatrix();\r
-                as.traceAlignment();\r
-                as.printAlignment(System.out);\r
-                scores[i][j] = (float) as.getMaxScore() / (float) as.getASeq1().length;\r
-                totscore = totscore + scores[i][j];\r
-\r
-                textarea.append(as.getOutput());\r
-                sequences.add(new Sequence(as.getS1().getName(), as.getAStr1()));\r
-                sequences.add(new Sequence(as.getS2().getName(), as.getAStr2()));\r
-            }\r
-        }\r
-\r
-        if (count > 2)\r
-        {\r
-            System.out.println(\r
-                "Pairwise alignment scaled similarity score matrix\n");\r
-\r
-            for (int i = 0; i < count; i++)\r
-            {\r
-                jalview.util.Format.print(System.out, "%s \n",\r
-                    ("" + i) + " " +\r
-                    ((SequenceI) selsubset.elementAt(i)).getName());\r
-            }\r
-\r
-            System.out.println("\n");\r
-\r
-            for (int i = 0; i < count; i++)\r
-            {\r
-                for (int j = 0; j < i; j++)\r
-                {\r
-                    jalview.util.Format.print(System.out, "%7.3f",\r
-                        scores[i][j] / totscore);\r
-                }\r
-            }\r
-\r
-            System.out.println("\n");\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void viewInEditorButton_actionPerformed(ActionEvent e)\r
-    {\r
-        Sequence[] seq = new Sequence[sequences.size()];\r
-\r
-        for (int i = 0; i < sequences.size(); i++)\r
-        {\r
-            seq[i] = (Sequence) sequences.elementAt(i);\r
-        }\r
-\r
-        AlignFrame af = new AlignFrame(new Alignment(seq));\r
-        Desktop.addInternalFrame(af, "Pairwise Aligned Sequences",\r
-            AlignFrame.NEW_WINDOW_WIDTH, AlignFrame.NEW_WINDOW_HEIGHT);\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.analysis.*;
+
+import jalview.datamodel.*;
+
+import jalview.jbgui.*;
+
+import java.awt.event.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class PairwiseAlignPanel extends GPairwiseAlignPanel
+{
+
+    AlignViewport av;
+    Vector sequences;
+
+    /**
+     * Creates a new PairwiseAlignPanel object.
+     *
+     * @param av DOCUMENT ME!
+     */
+    public PairwiseAlignPanel(AlignViewport av)
+    {
+        super();
+        this.av = av;
+
+        sequences = new Vector();
+
+        SequenceI [] seqs;
+        String []  seqStrings = av.getViewAsString(true);
+
+        if(av.getSelectionGroup()==null)
+        {
+          seqs = av.alignment.getSequencesArray();
+        }
+        else
+        {
+          seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+        }
+
+
+        float[][] scores = new float[seqs.length][seqs.length];
+        double totscore = 0;
+        int count = seqs.length;
+
+        Sequence seq;
+
+        for (int i = 1; i < count; i++)
+        {
+            for (int j = 0; j < i; j++)
+            {
+
+                AlignSeq as = new AlignSeq(seqs[i], seqStrings[i],
+                        seqs[j], seqStrings[j], "pep");
+
+                if(as.s1str.length()==0 || as.s2str.length()==0)
+                {
+                  continue;
+                }
+
+                as.calcScoreMatrix();
+                as.traceAlignment();
+
+
+                as.printAlignment(System.out);
+                scores[i][j] = (float) as.getMaxScore() / (float) as.getASeq1().length;
+                totscore = totscore + scores[i][j];
+
+                textarea.append(as.getOutput());
+                seq = new Sequence(as.getS1().getName(),
+                                   as.getAStr1(),
+                                   as.getS1().getStart(),
+                                   as.getS1().getEnd()
+                );
+                sequences.add(seq);
+
+                seq = new Sequence(as.getS2().getName(),
+                                   as.getAStr2(),
+                                   as.getS2().getStart(),
+                                   as.getS2().getEnd() );
+                sequences.add(seq);
+            }
+        }
+
+        if (count > 2)
+        {
+            System.out.println(
+                "Pairwise alignment scaled similarity score matrix\n");
+
+            for (int i = 0; i < count; i++)
+            {
+                jalview.util.Format.print(System.out, "%s \n",
+                    ("" + i) + " " +
+                    seqs[i].getName());
+            }
+
+            System.out.println("\n");
+
+            for (int i = 0; i < count; i++)
+            {
+                for (int j = 0; j < i; j++)
+                {
+                    jalview.util.Format.print(System.out, "%7.3f",
+                        scores[i][j] / totscore);
+                }
+            }
+
+            System.out.println("\n");
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void viewInEditorButton_actionPerformed(ActionEvent e)
+    {
+        Sequence[] seq = new Sequence[sequences.size()];
+
+        for (int i = 0; i < sequences.size(); i++)
+        {
+            seq[i] = (Sequence) sequences.elementAt(i);
+        }
+
+        AlignFrame af = new AlignFrame(new Alignment(seq));
+        Desktop.addInternalFrame(af, "Pairwise Aligned Sequences",
+            AlignFrame.NEW_WINDOW_WIDTH, AlignFrame.NEW_WINDOW_HEIGHT);
+    }
+}
index 14363e1..94c4293 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import MCview.*;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class PopupMenu extends JPopupMenu\r
-{\r
-    JMenu groupMenu = new JMenu();\r
-    JMenuItem groupName = new JMenuItem();\r
-    protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();\r
-    protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();\r
-    protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();\r
-    protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();\r
-    JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();\r
-    protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();\r
-    AlignmentPanel ap;\r
-    JMenu sequenceMenu = new JMenu();\r
-    JMenuItem sequenceName = new JMenuItem();\r
-    Sequence sequence;\r
-    JMenuItem unGroupMenuItem = new JMenuItem();\r
-    JMenuItem outline = new JMenuItem();\r
-    JRadioButtonMenuItem nucleotideMenuItem = new JRadioButtonMenuItem();\r
-    JMenu colourMenu = new JMenu();\r
-    JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();\r
-    JCheckBoxMenuItem showText = new JCheckBoxMenuItem();\r
-    JCheckBoxMenuItem showColourText = new JCheckBoxMenuItem();\r
-\r
-    /**\r
-     * Creates a new PopupMenu object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    public PopupMenu(final AlignmentPanel ap, Sequence seq)\r
-    {\r
-        ///////////////////////////////////////////////////////////\r
-        // If this is activated from the sequence panel, the user may want to\r
-        // edit or annotate a particular residue. Therefore display the residue menu\r
-        //\r
-        // If from the IDPanel, we must display the sequence menu\r
-        //////////////////////////////////////////////////////////\r
-        this.ap = ap;\r
-        sequence = seq;\r
-\r
-        ButtonGroup colours = new ButtonGroup();\r
-        colours.add(noColourmenuItem);\r
-        colours.add(clustalColour);\r
-        colours.add(zappoColour);\r
-        colours.add(taylorColour);\r
-        colours.add(hydrophobicityColour);\r
-        colours.add(helixColour);\r
-        colours.add(strandColour);\r
-        colours.add(turnColour);\r
-        colours.add(buriedColour);\r
-        colours.add(abovePIDColour);\r
-        colours.add(userDefinedColour);\r
-        colours.add(PIDColour);\r
-        colours.add(BLOSUM62Colour);\r
-\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-\r
-\r
-        if (seq != null)\r
-        {\r
-          JMenuItem menuItem;\r
-          if( seq.getDatasetSequence().getPDBId() != null)\r
-          {\r
-            java.util.Enumeration e = seq.getDatasetSequence().getPDBId().\r
-                elements();\r
-            while (e.hasMoreElements())\r
-            {\r
-              final PDBEntry pdb = (PDBEntry) e.nextElement();\r
-\r
-              menuItem = new JMenuItem();\r
-              menuItem.setText("View PDB entry: " + pdb.getId());\r
-              menuItem.addActionListener(new java.awt.event.ActionListener()\r
-              {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                  new PDBViewer(pdb, sequence, ap.seqPanel.seqCanvas);\r
-                }\r
-              });\r
-              sequenceMenu.add(menuItem);\r
-            }\r
-          }\r
-\r
-          menuItem = new JMenuItem("Hide Sequences");\r
-          menuItem.addActionListener(new java.awt.event.ActionListener()\r
-              {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                  hideSequences(false);\r
-                }\r
-              });\r
-          sequenceMenu.add(menuItem);\r
-\r
-          if(ap.av.getSelectionGroup() !=null && ap.av.getSelectionGroup().getSize()>1)\r
-          {\r
-            menuItem = new JMenuItem("Represent Group with " + seq.getName());\r
-            menuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-              public void actionPerformed(ActionEvent e)\r
-              {\r
-                hideSequences(true);\r
-              }\r
-            });\r
-            sequenceMenu.add(menuItem);\r
-          }\r
-\r
-\r
-        }\r
-\r
-\r
-\r
-        SequenceGroup sg = ap.av.getSelectionGroup();\r
-\r
-        if (sg != null)\r
-        {\r
-            groupName.setText(sg.getName());\r
-\r
-            if (sg.cs instanceof ZappoColourScheme)\r
-            {\r
-                zappoColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof TaylorColourScheme)\r
-            {\r
-                taylorColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof PIDColourScheme)\r
-            {\r
-                PIDColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof Blosum62ColourScheme)\r
-            {\r
-                BLOSUM62Colour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof UserColourScheme)\r
-            {\r
-                userDefinedColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof HydrophobicColourScheme)\r
-            {\r
-                hydrophobicityColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof HelixColourScheme)\r
-            {\r
-                helixColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof StrandColourScheme)\r
-            {\r
-                strandColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof TurnColourScheme)\r
-            {\r
-                turnColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof BuriedColourScheme)\r
-            {\r
-                buriedColour.setSelected(true);\r
-            }\r
-            else if (sg.cs instanceof ClustalxColourScheme)\r
-            {\r
-                clustalColour.setSelected(true);\r
-            }\r
-            else\r
-            {\r
-                noColourmenuItem.setSelected(true);\r
-            }\r
-\r
-            if (sg.cs!=null && sg.cs.conservationApplied())\r
-            {\r
-                conservationMenuItem.setSelected(true);\r
-            }\r
-\r
-            showText.setSelected(sg.getDisplayText());\r
-            showColourText.setSelected(sg.getColourText());\r
-            showBoxes.setSelected(sg.getDisplayBoxes());\r
-        }\r
-\r
-        if (!ap.av.alignment.getGroups().contains(sg))\r
-        {\r
-            unGroupMenuItem.setVisible(false);\r
-        }\r
-        else\r
-        {\r
-            groupMenu.insertSeparator(3);\r
-        }\r
-\r
-        if (seq == null)\r
-        {\r
-            sequenceMenu.setVisible(false);\r
-        }\r
-        else\r
-        {\r
-          java.util.Vector links = Preferences.sequenceURLLinks;\r
-\r
-          JMenu linkMenu = new JMenu("Link");\r
-          JMenuItem item;\r
-          for(int i=0; i<links.size(); i++)\r
-          {\r
-            String link = links.elementAt(i).toString();\r
-\r
-            item = new JMenuItem(link.substring(0, link.indexOf("|")));\r
-            String id = sequence.getName();\r
-            if(id.indexOf("|")>-1)\r
-              id = id.substring(id.lastIndexOf("|")+1);\r
-\r
-            final String url = link.substring(link.indexOf("|")+1, link.indexOf("$SEQUENCE_ID$"))\r
-                + id +\r
-                link.substring(link.indexOf("$SEQUENCE_ID$") + 13);\r
-\r
-\r
-            item.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    showLink(url);\r
-                }\r
-            });\r
-\r
-            linkMenu.add(item);\r
-          }\r
-          add(linkMenu);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        groupMenu.setText("Group");\r
-        groupMenu.setText("Define");\r
-        groupName.setText("Name");\r
-        groupName.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    groupName_actionPerformed(e);\r
-                }\r
-            });\r
-        sequenceMenu.setText("Sequence");\r
-        sequenceName.setText("Edit Name/Description");\r
-        sequenceName.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    sequenceName_actionPerformed(e);\r
-                }\r
-            });\r
-        PIDColour.setFocusPainted(false);\r
-        unGroupMenuItem.setText("Remove Group");\r
-        unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    unGroupMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-\r
-        outline.setText("Border colour");\r
-        outline.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    outline_actionPerformed(e);\r
-                }\r
-            });\r
-        nucleotideMenuItem.setText("Nucleotide");\r
-        nucleotideMenuItem.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    nucleotideMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-        colourMenu.setText("Group Colour");\r
-        showBoxes.setText("Boxes");\r
-        showBoxes.setState(true);\r
-        showBoxes.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    showBoxes_actionPerformed(e);\r
-                }\r
-            });\r
-        showText.setText("Text");\r
-        showText.setState(true);\r
-        showText.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    showText_actionPerformed(e);\r
-                }\r
-            });\r
-        showColourText.setText("Colour Text");\r
-        showColourText.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    showColourText_actionPerformed(e);\r
-                }\r
-            });\r
-        add(groupMenu);\r
-        add(sequenceMenu);\r
-        groupMenu.add(groupName);\r
-        groupMenu.addSeparator();\r
-        groupMenu.add(unGroupMenuItem);\r
-        groupMenu.add(colourMenu);\r
-        groupMenu.addSeparator();\r
-        groupMenu.add(showBoxes);\r
-        groupMenu.add(showText);\r
-        groupMenu.add(showColourText);\r
-        groupMenu.addSeparator();\r
-        groupMenu.add(outline);\r
-        sequenceMenu.add(sequenceName);\r
-        colourMenu.add(noColourmenuItem);\r
-        colourMenu.add(clustalColour);\r
-        colourMenu.add(BLOSUM62Colour);\r
-        colourMenu.add(PIDColour);\r
-        colourMenu.add(zappoColour);\r
-        colourMenu.add(taylorColour);\r
-        colourMenu.add(hydrophobicityColour);\r
-        colourMenu.add(helixColour);\r
-        colourMenu.add(strandColour);\r
-        colourMenu.add(turnColour);\r
-        colourMenu.add(buriedColour);\r
-        colourMenu.add(nucleotideMenuItem);\r
-        colourMenu.add(userDefinedColour);\r
-\r
-        if(jalview.gui.UserDefinedColours.getUserColourSchemes()!=null)\r
-        {\r
-          java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
-              getUserColourSchemes().keys();\r
-\r
-          while (userColours.hasMoreElements())\r
-          {\r
-            JMenuItem item = new JMenuItem(userColours.\r
-                nextElement().toString());\r
-            item.addActionListener(new ActionListener()\r
-            {\r
-              public void actionPerformed(ActionEvent evt)\r
-              {\r
-                userDefinedColour_actionPerformed(evt);\r
-              }\r
-            });\r
-            colourMenu.add(item);\r
-          }\r
-        }\r
-\r
-\r
-        colourMenu.addSeparator();\r
-        colourMenu.add(abovePIDColour);\r
-        colourMenu.add(conservationMenuItem);\r
-        noColourmenuItem.setText("None");\r
-        noColourmenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    noColourmenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-\r
-        clustalColour.setText("Clustalx colours");\r
-        clustalColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    clustalColour_actionPerformed(e);\r
-                }\r
-            });\r
-        zappoColour.setText("Zappo");\r
-        zappoColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    zappoColour_actionPerformed(e);\r
-                }\r
-            });\r
-        taylorColour.setText("Taylor");\r
-        taylorColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    taylorColour_actionPerformed(e);\r
-                }\r
-            });\r
-        hydrophobicityColour.setText("Hydrophobicity");\r
-        hydrophobicityColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    hydrophobicityColour_actionPerformed(e);\r
-                }\r
-            });\r
-        helixColour.setText("Helix propensity");\r
-        helixColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    helixColour_actionPerformed(e);\r
-                }\r
-            });\r
-        strandColour.setText("Strand propensity");\r
-        strandColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    strandColour_actionPerformed(e);\r
-                }\r
-            });\r
-        turnColour.setText("Turn propensity");\r
-        turnColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    turnColour_actionPerformed(e);\r
-                }\r
-            });\r
-        buriedColour.setText("Buried Index");\r
-        buriedColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    buriedColour_actionPerformed(e);\r
-                }\r
-            });\r
-        abovePIDColour.setText("Above % Identity");\r
-        abovePIDColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    abovePIDColour_actionPerformed(e);\r
-                }\r
-            });\r
-        userDefinedColour.setText("User Defined...");\r
-        userDefinedColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    userDefinedColour_actionPerformed(e);\r
-                }\r
-            });\r
-        PIDColour.setText("Percentage Identity");\r
-        PIDColour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    PIDColour_actionPerformed(e);\r
-                }\r
-            });\r
-        BLOSUM62Colour.setText("BLOSUM62");\r
-        BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    BLOSUM62Colour_actionPerformed(e);\r
-                }\r
-            });\r
-        conservationMenuItem.setText("Conservation");\r
-        conservationMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    conservationMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    void refresh()\r
-    {\r
-        if (ap.overviewPanel != null)\r
-          ap.overviewPanel.updateOverviewImage();\r
-\r
-        ap.seqPanel.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void clustalColour_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-        sg.cs = new ClustalxColourScheme(sg.sequences,\r
-                ap.av.alignment.getWidth());\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void zappoColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new ZappoColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void taylorColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new TaylorColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void hydrophobicityColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new HydrophobicColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void helixColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new HelixColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void strandColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new StrandColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void turnColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new TurnColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void buriedColour_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new BuriedColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void nucleotideMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = new NucleotideColourScheme();\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void abovePIDColour_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-        if(sg.cs==null)\r
-          return;\r
-\r
-        if (abovePIDColour.isSelected())\r
-        {\r
-            sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-                    ap.av.alignment.getWidth()));\r
-\r
-            int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,\r
-                    getGroup().getName());\r
-\r
-           sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());\r
-\r
-            SliderPanel.showPIDSlider();\r
-        }\r
-        else // remove PIDColouring\r
-        {\r
-            sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
-        }\r
-\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void userDefinedColour_actionPerformed(ActionEvent e)\r
-    {\r
-       SequenceGroup sg = getGroup();\r
-\r
-       if (e.getActionCommand().equals("User Defined..."))\r
-         new UserDefinedColours(ap, sg);\r
-       else\r
-       {\r
-         UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
-             getUserColourSchemes().get(e.getActionCommand());\r
-\r
-         sg.cs = udc;\r
-       }\r
-     }\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void PIDColour_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-        sg.cs = new PIDColourScheme();\r
-        sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-                ap.av.alignment.getWidth()));\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-\r
-        sg.cs = new Blosum62ColourScheme();\r
-\r
-        sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
-                ap.av.alignment.getWidth()));\r
-\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().cs = null;\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-        if(sg.cs==null)\r
-          return;\r
-\r
-        if (conservationMenuItem.isSelected())\r
-        {\r
-            Conservation c = new Conservation("Group",\r
-                    ResidueProperties.propHash, 3, sg.sequences, 0,\r
-                    ap.av.alignment.getWidth());\r
-\r
-            c.calculate();\r
-            c.verdict(false, ap.av.ConsPercGaps);\r
-\r
-            sg.cs.setConservation(c);\r
-\r
-            SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());\r
-            SliderPanel.showConservationSlider();\r
-        }\r
-        else // remove ConservationColouring\r
-        {\r
-            sg.cs.setConservation(null);\r
-        }\r
-\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void groupName_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-        String reply = JOptionPane.showInternalInputDialog(Desktop.desktop,\r
-                "Enter new group name", "Edit group name",\r
-                JOptionPane.QUESTION_MESSAGE);\r
-\r
-        if (reply == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        sg.setName(reply);\r
-        groupName.setText(reply);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void analyze_actionPerformed(ActionEvent e)\r
-    {\r
-        CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
-        JInternalFrame frame = new JInternalFrame();\r
-        frame.setContentPane(cap);\r
-        Desktop.addInternalFrame(frame, "Analyze this - ", 400, 300);\r
-\r
-        SequenceGroup sg = getGroup();\r
-        StringBuffer sb = new StringBuffer();\r
-\r
-        for (int i = 0; i < sg.sequences.size(); i++)\r
-        {\r
-            Sequence tmp = (Sequence) sg.sequences.get(i);\r
-            sb.append(tmp.getSequence(sg.getStartRes(), sg.getEndRes() + 1));\r
-            sb.append("\n");\r
-        }\r
-\r
-        sb.append("Something amazing will happen soon");\r
-        cap.setText(sb.toString());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    SequenceGroup getGroup()\r
-    {\r
-        SequenceGroup sg = ap.av.getSelectionGroup();\r
-      // this method won't add a new group if it already exists\r
-        if(sg!=null)\r
-          ap.av.alignment.addGroup(sg);\r
-\r
-        return sg;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    void sequenceName_actionPerformed(ActionEvent e)\r
-    {\r
-      JLabel idlabel = new JLabel(  "       Sequence Name ");\r
-      JLabel desclabel = new JLabel("Sequence Description ");\r
-      idlabel.setFont(new Font("Courier", Font.PLAIN, 12));\r
-      desclabel.setFont(new Font("Courier", Font.PLAIN, 12));\r
-      JTextField id = new JTextField(sequence.getName(), 40);\r
-      JTextField description = new JTextField(sequence.getDescription(), 40);\r
-      JPanel panel = new JPanel(new BorderLayout());\r
-      JPanel panel2 = new JPanel(new BorderLayout());\r
-      panel2.add(idlabel, BorderLayout.WEST);\r
-      panel2.add(id, BorderLayout.CENTER);\r
-      panel.add(panel2, BorderLayout.NORTH);\r
-      panel2 = new JPanel(new BorderLayout());\r
-      panel2.add(desclabel, BorderLayout.WEST);\r
-      panel2.add(description, BorderLayout.CENTER);\r
-      panel.add(panel2, BorderLayout.SOUTH);\r
-\r
-\r
-       int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
-          panel, "Edit Sequence Name/Description",\r
-          JOptionPane.OK_CANCEL_OPTION );\r
-\r
-\r
-        if (reply != JOptionPane.OK_OPTION )\r
-        {\r
-            return;\r
-        }\r
-\r
-        String s = id.getText();\r
-\r
-        if (s != null)\r
-        {\r
-            if (s.indexOf(" ") > -1)\r
-            {\r
-                JOptionPane.showMessageDialog(ap,\r
-                    "Spaces have been converted to \"_\"",\r
-                    "No spaces allowed in Sequence Name",\r
-                    JOptionPane.WARNING_MESSAGE);\r
-            }\r
-\r
-            s = s.replace(' ', '_');\r
-            sequence.getDatasetSequence().setName(s);\r
-            sequence.setName(s);\r
-            ap.repaint();\r
-        }\r
-\r
-        sequence.getDatasetSequence().setDescription(description.getText());\r
-        sequence.setDescription(description.getText());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    void unGroupMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = ap.av.getSelectionGroup();\r
-        ap.av.alignment.deleteGroup(sg);\r
-        ap.av.setSelectionGroup(null);\r
-        refresh();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void outline_actionPerformed(ActionEvent e)\r
-    {\r
-        SequenceGroup sg = getGroup();\r
-        Color col = JColorChooser.showDialog(this, "Select Outline Colour",\r
-                Color.BLUE);\r
-\r
-        if (col != null)\r
-        {\r
-            sg.setOutlineColour(col);\r
-        }\r
-\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void showBoxes_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().setDisplayBoxes(showBoxes.isSelected());\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void showText_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().setDisplayText(showText.isSelected());\r
-        refresh();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void showColourText_actionPerformed(ActionEvent e)\r
-    {\r
-        getGroup().setColourText(showColourText.isSelected());\r
-        refresh();\r
-    }\r
-\r
-    public void showLink(String url)\r
-    {\r
-      try\r
-      {\r
-        jalview.util.BrowserLauncher.openURL(url);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-            "Unixers: Couldn't find default web browser."\r
-           +"\nAdd the full path to your browser in Preferences.",\r
-           "Web browser not found", JOptionPane.WARNING_MESSAGE );\r
-\r
-\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-\r
-    void hideSequences(boolean representGroup)\r
-    {\r
-      SequenceGroup sg = ap.av.getSelectionGroup();\r
-      if(sg==null || sg.getSize()<1)\r
-      {\r
-        ap.av.hideSequence(sequence);\r
-        return;\r
-      }\r
-\r
-        int index = 0;\r
-        while(index < sg.sequences.size())\r
-        {\r
-          if(representGroup && sg.getSequenceAt(index)!=sequence)\r
-          {\r
-            sequence.addHiddenSequence(sg.getSequenceAt(index));\r
-            ap.av.hideSequence(sg.getSequenceAt(index));\r
-          }\r
-          else if(!representGroup)\r
-          {\r
-            ap.av.hideSequence(sg.getSequenceAt(index));\r
-          }\r
-          index ++;\r
-        }\r
-\r
-        ap.av.setSelectionGroup(null);\r
-        refresh();\r
-    }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import MCview.*;
+
+import jalview.analysis.*;
+
+import jalview.datamodel.*;
+
+
+import jalview.schemes.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import java.util.Vector;
+import jalview.io.FormatAdapter;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class PopupMenu extends JPopupMenu
+{
+    JMenu groupMenu = new JMenu();
+    JMenuItem groupName = new JMenuItem();
+    protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
+    protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();
+    protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
+    protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
+    JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
+    protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
+    AlignmentPanel ap;
+    JMenu sequenceMenu = new JMenu();
+    JMenuItem sequenceName = new JMenuItem();
+    Sequence sequence;
+    JMenuItem unGroupMenuItem = new JMenuItem();
+    JMenuItem outline = new JMenuItem();
+    JRadioButtonMenuItem nucleotideMenuItem = new JRadioButtonMenuItem();
+    JMenu colourMenu = new JMenu();
+    JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
+    JCheckBoxMenuItem showText = new JCheckBoxMenuItem();
+    JCheckBoxMenuItem showColourText = new JCheckBoxMenuItem();
+  JMenu editMenu = new JMenu();
+  JMenuItem cut = new JMenuItem();
+  JMenuItem copy = new JMenuItem();
+  JMenuItem upperCase = new JMenuItem();
+  JMenuItem lowerCase = new JMenuItem();
+  JMenuItem toggle = new JMenuItem();
+  JMenu pdbMenu = new JMenu();
+  JMenuItem pdbFromFile = new JMenuItem();
+  JMenuItem enterPDB = new JMenuItem();
+  JMenuItem discoverPDB = new JMenuItem();
+  JMenu outputMenu = new JMenu();
+
+  /**
+     * Creates a new PopupMenu object.
+     *
+     * @param ap DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     */
+    public PopupMenu(final AlignmentPanel ap, Sequence seq, Vector links)
+    {
+        ///////////////////////////////////////////////////////////
+        // If this is activated from the sequence panel, the user may want to
+        // edit or annotate a particular residue. Therefore display the residue menu
+        //
+        // If from the IDPanel, we must display the sequence menu
+        //////////////////////////////////////////////////////////
+        this.ap = ap;
+        sequence = seq;
+
+        ButtonGroup colours = new ButtonGroup();
+        colours.add(noColourmenuItem);
+        colours.add(clustalColour);
+        colours.add(zappoColour);
+        colours.add(taylorColour);
+        colours.add(hydrophobicityColour);
+        colours.add(helixColour);
+        colours.add(strandColour);
+        colours.add(turnColour);
+        colours.add(buriedColour);
+        colours.add(abovePIDColour);
+        colours.add(userDefinedColour);
+        colours.add(PIDColour);
+        colours.add(BLOSUM62Colour);
+
+        for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
+        {
+          JMenuItem item = new JMenuItem( jalview.io.FormatAdapter.WRITEABLE_FORMATS[i] );
+
+          item.addActionListener(new java.awt.event.ActionListener()
+          {
+            public void actionPerformed(ActionEvent e)
+            {
+              outputText_actionPerformed(e);
+            }
+          });
+
+          outputMenu.add(item);
+        }
+
+
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+
+        if (seq != null)
+        {
+          int start = Math.max(sequence.getName().length()-15, 0);
+          sequenceMenu.setText(sequence.getName().substring(start));
+
+          JMenuItem menuItem;
+          if( seq.getDatasetSequence().getPDBId() != null)
+          {
+            java.util.Enumeration e = seq.getDatasetSequence().getPDBId().
+                elements();
+
+            while (e.hasMoreElements())
+            {
+              final PDBEntry pdb = (PDBEntry) e.nextElement();
+
+              menuItem = new JMenuItem();
+              menuItem.setText("View PDB entry: " + pdb.getId());
+              menuItem.addActionListener(new java.awt.event.ActionListener()
+              {
+                public void actionPerformed(ActionEvent e)
+                {
+                  new PDBViewer(pdb, sequence, ap.seqPanel.seqCanvas);
+                }
+              });
+              sequenceMenu.add(menuItem);
+            }
+          }
+
+          menuItem = new JMenuItem("Hide Sequences");
+          menuItem.addActionListener(new java.awt.event.ActionListener()
+              {
+                public void actionPerformed(ActionEvent e)
+                {
+                  hideSequences(false);
+                }
+              });
+          add(menuItem);
+
+          if(ap.av.getSelectionGroup() !=null
+             && ap.av.getSelectionGroup().getSize(false)>1)
+          {
+            menuItem = new JMenuItem("Represent Group with " + seq.getName());
+            menuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+              public void actionPerformed(ActionEvent e)
+              {
+                hideSequences(true);
+              }
+            });
+            sequenceMenu.add(menuItem);
+          }
+
+          if (ap.av.hasHiddenRows)
+          {
+            final int index = ap.av.alignment.findIndex(seq);
+
+            if (ap.av.adjustForHiddenSeqs(index) -
+                ap.av.adjustForHiddenSeqs(index - 1) > 1)
+            {
+              menuItem = new JMenuItem("Reveal Sequences");
+              menuItem.addActionListener(new ActionListener()
+              {
+                public void actionPerformed(ActionEvent e)
+                {
+                  ap.av.showSequence(index);
+                  if (ap.overviewPanel != null)
+                    ap.overviewPanel.updateOverviewImage();
+                }
+              });
+              add(menuItem);
+            }
+
+            menuItem = new JMenuItem("Reveal All");
+            menuItem.addActionListener(new ActionListener()
+                {
+                  public void actionPerformed(ActionEvent e)
+                  {
+                    ap.av.showAllHiddenSeqs();
+                    if (ap.overviewPanel != null)
+                      ap.overviewPanel.updateOverviewImage();
+                    }
+                });
+
+            add(menuItem);
+          }
+
+
+        }
+
+
+
+        SequenceGroup sg = ap.av.getSelectionGroup();
+
+        if (sg != null)
+        {
+            groupName.setText(sg.getName());
+
+            if (sg.cs instanceof ZappoColourScheme)
+            {
+                zappoColour.setSelected(true);
+            }
+            else if (sg.cs instanceof TaylorColourScheme)
+            {
+                taylorColour.setSelected(true);
+            }
+            else if (sg.cs instanceof PIDColourScheme)
+            {
+                PIDColour.setSelected(true);
+            }
+            else if (sg.cs instanceof Blosum62ColourScheme)
+            {
+                BLOSUM62Colour.setSelected(true);
+            }
+            else if (sg.cs instanceof UserColourScheme)
+            {
+                userDefinedColour.setSelected(true);
+            }
+            else if (sg.cs instanceof HydrophobicColourScheme)
+            {
+                hydrophobicityColour.setSelected(true);
+            }
+            else if (sg.cs instanceof HelixColourScheme)
+            {
+                helixColour.setSelected(true);
+            }
+            else if (sg.cs instanceof StrandColourScheme)
+            {
+                strandColour.setSelected(true);
+            }
+            else if (sg.cs instanceof TurnColourScheme)
+            {
+                turnColour.setSelected(true);
+            }
+            else if (sg.cs instanceof BuriedColourScheme)
+            {
+                buriedColour.setSelected(true);
+            }
+            else if (sg.cs instanceof ClustalxColourScheme)
+            {
+                clustalColour.setSelected(true);
+            }
+            else
+            {
+                noColourmenuItem.setSelected(true);
+            }
+
+            if (sg.cs!=null && sg.cs.conservationApplied())
+            {
+                conservationMenuItem.setSelected(true);
+            }
+
+            showText.setSelected(sg.getDisplayText());
+            showColourText.setSelected(sg.getColourText());
+            showBoxes.setSelected(sg.getDisplayBoxes());
+        }
+        else
+        {
+          groupMenu.setVisible(false);
+          editMenu.setVisible(false);
+        }
+
+        if (!ap.av.alignment.getGroups().contains(sg))
+        {
+            unGroupMenuItem.setVisible(false);
+        }
+
+
+        if (seq == null)
+        {
+            sequenceMenu.setVisible(false);
+            pdbMenu.setVisible(false);
+        }
+
+        if(links != null && links.size()>0)
+        {
+          JMenu linkMenu = new JMenu("Link");
+          JMenuItem item;
+          for(int i=0; i<links.size(); i++)
+          {
+            String link = links.elementAt(i).toString();
+            final String label = link.substring(0, link.indexOf("|"));
+            item = new JMenuItem(label);
+            final String url;
+
+            if (link.indexOf("$SEQUENCE_ID$") > -1)
+            {
+              String id = seq.getName();
+              if (id.indexOf("|") > -1)
+                id = id.substring(id.lastIndexOf("|") + 1);
+
+              url = link.substring(link.indexOf("|") + 1,
+                                   link.indexOf("$SEQUENCE_ID$"))
+                  + id +
+                  link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
+            }
+            else
+              url = link.substring(link.lastIndexOf("|")+1);
+
+
+            item.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    showLink(url);
+                }
+            });
+
+            linkMenu.add(item);
+          }
+          if(sequence!=null)
+            sequenceMenu.add(linkMenu);
+          else
+            add(linkMenu);
+        }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        groupMenu.setText("Group");
+        groupMenu.setText("Selection");
+        groupName.setText("Name");
+        groupName.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    groupName_actionPerformed(e);
+                }
+            });
+        sequenceMenu.setText("Sequence");
+        sequenceName.setText("Edit Name/Description");
+        sequenceName.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    sequenceName_actionPerformed(e);
+                }
+            });
+        PIDColour.setFocusPainted(false);
+        unGroupMenuItem.setText("Remove Group");
+        unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    unGroupMenuItem_actionPerformed(e);
+                }
+            });
+
+        outline.setText("Border colour");
+        outline.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    outline_actionPerformed(e);
+                }
+            });
+        nucleotideMenuItem.setText("Nucleotide");
+        nucleotideMenuItem.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    nucleotideMenuItem_actionPerformed(e);
+                }
+            });
+        colourMenu.setText("Group Colour");
+        showBoxes.setText("Boxes");
+        showBoxes.setState(true);
+        showBoxes.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    showBoxes_actionPerformed(e);
+                }
+            });
+        showText.setText("Text");
+        showText.setState(true);
+        showText.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    showText_actionPerformed(e);
+                }
+            });
+        showColourText.setText("Colour Text");
+        showColourText.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    showColourText_actionPerformed(e);
+                }
+            });
+    editMenu.setText("Edit");
+    cut.setText("Cut");
+    cut.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        cut_actionPerformed(e);
+      }
+    });
+    upperCase.setText("To Upper Case");
+    upperCase.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        upperCase_actionPerformed(e);
+      }
+    });
+    copy.setText("Copy");
+    copy.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        copy_actionPerformed(e);
+      }
+    });
+    lowerCase.setText("To Lower Case");
+    lowerCase.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        lowerCase_actionPerformed(e);
+      }
+    });
+    toggle.setText("Toggle Case");
+    toggle.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        toggle_actionPerformed(e);
+      }
+    });
+    pdbMenu.setText("Associate Structure with Sequence");
+    pdbFromFile.setText("From File");
+    pdbFromFile.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        pdbFromFile_actionPerformed(e);
+      }
+    });
+    enterPDB.setText("Enter PDB Id");
+    enterPDB.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        enterPDB_actionPerformed(e);
+      }
+    });
+    discoverPDB.setText("Discover PDB ids");
+    discoverPDB.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        discoverPDB_actionPerformed(e);
+      }
+    });
+    outputMenu.setText("Output to Textbox...");
+    add(groupMenu);
+
+    add(sequenceMenu);
+    groupMenu.add(editMenu);
+    groupMenu.add(outputMenu);
+    groupMenu.addSeparator();
+    groupMenu.add(groupName);
+    groupMenu.add(unGroupMenuItem);
+        groupMenu.add(colourMenu);
+    groupMenu.add(showBoxes);
+        groupMenu.add(showText);
+        groupMenu.add(showColourText);
+    groupMenu.add(outline);
+        sequenceMenu.add(sequenceName);
+    sequenceMenu.add(pdbMenu);
+    colourMenu.add(noColourmenuItem);
+        colourMenu.add(clustalColour);
+        colourMenu.add(BLOSUM62Colour);
+        colourMenu.add(PIDColour);
+        colourMenu.add(zappoColour);
+        colourMenu.add(taylorColour);
+        colourMenu.add(hydrophobicityColour);
+        colourMenu.add(helixColour);
+        colourMenu.add(strandColour);
+        colourMenu.add(turnColour);
+        colourMenu.add(buriedColour);
+        colourMenu.add(nucleotideMenuItem);
+        colourMenu.add(userDefinedColour);
+
+        if(jalview.gui.UserDefinedColours.getUserColourSchemes()!=null)
+        {
+          java.util.Enumeration userColours = jalview.gui.UserDefinedColours.
+              getUserColourSchemes().keys();
+
+          while (userColours.hasMoreElements())
+          {
+            JMenuItem item = new JMenuItem(userColours.
+                nextElement().toString());
+            item.addActionListener(new ActionListener()
+            {
+              public void actionPerformed(ActionEvent evt)
+              {
+                userDefinedColour_actionPerformed(evt);
+              }
+            });
+            colourMenu.add(item);
+          }
+        }
+
+
+        colourMenu.addSeparator();
+        colourMenu.add(abovePIDColour);
+        colourMenu.add(conservationMenuItem);
+    editMenu.add(copy);
+    editMenu.add(cut);
+    editMenu.add(upperCase);
+    editMenu.add(lowerCase);
+    editMenu.add(toggle);
+    pdbMenu.add(pdbFromFile);
+    pdbMenu.add(enterPDB);
+    pdbMenu.add(discoverPDB);
+    noColourmenuItem.setText("None");
+        noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    noColourmenuItem_actionPerformed(e);
+                }
+            });
+
+        clustalColour.setText("Clustalx colours");
+        clustalColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    clustalColour_actionPerformed(e);
+                }
+            });
+        zappoColour.setText("Zappo");
+        zappoColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    zappoColour_actionPerformed(e);
+                }
+            });
+        taylorColour.setText("Taylor");
+        taylorColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    taylorColour_actionPerformed(e);
+                }
+            });
+        hydrophobicityColour.setText("Hydrophobicity");
+        hydrophobicityColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    hydrophobicityColour_actionPerformed(e);
+                }
+            });
+        helixColour.setText("Helix propensity");
+        helixColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    helixColour_actionPerformed(e);
+                }
+            });
+        strandColour.setText("Strand propensity");
+        strandColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    strandColour_actionPerformed(e);
+                }
+            });
+        turnColour.setText("Turn propensity");
+        turnColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    turnColour_actionPerformed(e);
+                }
+            });
+        buriedColour.setText("Buried Index");
+        buriedColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    buriedColour_actionPerformed(e);
+                }
+            });
+        abovePIDColour.setText("Above % Identity");
+        abovePIDColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    abovePIDColour_actionPerformed(e);
+                }
+            });
+        userDefinedColour.setText("User Defined...");
+        userDefinedColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    userDefinedColour_actionPerformed(e);
+                }
+            });
+        PIDColour.setText("Percentage Identity");
+        PIDColour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    PIDColour_actionPerformed(e);
+                }
+            });
+        BLOSUM62Colour.setText("BLOSUM62");
+        BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    BLOSUM62Colour_actionPerformed(e);
+                }
+            });
+        conservationMenuItem.setText("Conservation");
+        conservationMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    conservationMenuItem_actionPerformed(e);
+                }
+            });
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    void refresh()
+    {
+        if (ap.overviewPanel != null)
+          ap.overviewPanel.updateOverviewImage();
+
+        ap.seqPanel.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void clustalColour_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+        sg.cs = new ClustalxColourScheme(sg.getSequences(true),
+                ap.av.alignment.getWidth());
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void zappoColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new ZappoColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void taylorColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new TaylorColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void hydrophobicityColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new HydrophobicColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void helixColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new HelixColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void strandColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new StrandColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void turnColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new TurnColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void buriedColour_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new BuriedColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void nucleotideMenuItem_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = new NucleotideColourScheme();
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void abovePIDColour_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+        if(sg.cs==null)
+          return;
+
+        if (abovePIDColour.isSelected())
+        {
+            sg.cs.setConsensus(AAFrequency.calculate(
+                    sg.getSequences(true), 0,
+                    ap.av.alignment.getWidth()));
+
+            int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,
+                    getGroup().getName());
+
+           sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
+
+            SliderPanel.showPIDSlider();
+        }
+        else // remove PIDColouring
+        {
+            sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
+        }
+
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void userDefinedColour_actionPerformed(ActionEvent e)
+    {
+       SequenceGroup sg = getGroup();
+
+       if (e.getActionCommand().equals("User Defined..."))
+         new UserDefinedColours(ap, sg);
+       else
+       {
+         UserColourScheme udc = (UserColourScheme) UserDefinedColours.
+             getUserColourSchemes().get(e.getActionCommand());
+
+         sg.cs = udc;
+       }
+     }
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void PIDColour_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+        sg.cs = new PIDColourScheme();
+        sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,
+                ap.av.alignment.getWidth()));
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void BLOSUM62Colour_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+
+        sg.cs = new Blosum62ColourScheme();
+
+        sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,
+                ap.av.alignment.getWidth()));
+
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void noColourmenuItem_actionPerformed(ActionEvent e)
+    {
+        getGroup().cs = null;
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void conservationMenuItem_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+        if(sg.cs==null)
+          return;
+
+        if (conservationMenuItem.isSelected())
+        {
+            Conservation c = new Conservation("Group",
+                    ResidueProperties.propHash, 3,
+                    sg.getSequences(true), 0,
+                    ap.av.alignment.getWidth());
+
+            c.calculate();
+            c.verdict(false, ap.av.ConsPercGaps);
+
+            sg.cs.setConservation(c);
+
+            SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
+            SliderPanel.showConservationSlider();
+        }
+        else // remove ConservationColouring
+        {
+            sg.cs.setConservation(null);
+        }
+
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void groupName_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+        String reply = JOptionPane.showInternalInputDialog(Desktop.desktop,
+                "Enter new group name", "Edit group name",
+                JOptionPane.QUESTION_MESSAGE);
+
+        if (reply == null)
+        {
+            return;
+        }
+
+        sg.setName(reply);
+        groupName.setText(reply);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void analyze_actionPerformed(ActionEvent e)
+    {
+        CutAndPasteTransfer cap = new CutAndPasteTransfer();
+        JInternalFrame frame = new JInternalFrame();
+        frame.setContentPane(cap);
+        Desktop.addInternalFrame(frame, "Analyze this - ", 400, 300);
+
+        SequenceGroup sg = getGroup();
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < sg.getSize(false); i++)
+        {
+            Sequence tmp = (Sequence) sg.getSequences(false).elementAt(i);
+            sb.append(tmp.getSequence(sg.getStartRes(), sg.getEndRes() + 1));
+            sb.append("\n");
+        }
+
+        sb.append("Something amazing will happen soon");
+        cap.setText(sb.toString());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    SequenceGroup getGroup()
+    {
+        SequenceGroup sg = ap.av.getSelectionGroup();
+      // this method won't add a new group if it already exists
+        if(sg!=null)
+          ap.av.alignment.addGroup(sg);
+
+        return sg;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    void sequenceName_actionPerformed(ActionEvent e)
+    {
+      JLabel idlabel = new JLabel(  "       Sequence Name ");
+      JLabel desclabel = new JLabel("Sequence Description ");
+      idlabel.setFont(new Font("Courier", Font.PLAIN, 12));
+      desclabel.setFont(new Font("Courier", Font.PLAIN, 12));
+      JTextField id = new JTextField(sequence.getName(), 40);
+      JTextField description = new JTextField(sequence.getDescription(), 40);
+      JPanel panel = new JPanel(new BorderLayout());
+      JPanel panel2 = new JPanel(new BorderLayout());
+      panel2.add(idlabel, BorderLayout.WEST);
+      panel2.add(id, BorderLayout.CENTER);
+      panel.add(panel2, BorderLayout.NORTH);
+      panel2 = new JPanel(new BorderLayout());
+      panel2.add(desclabel, BorderLayout.WEST);
+      panel2.add(description, BorderLayout.CENTER);
+      panel.add(panel2, BorderLayout.SOUTH);
+
+
+       int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+          panel, "Edit Sequence Name/Description",
+          JOptionPane.OK_CANCEL_OPTION );
+
+
+        if (reply != JOptionPane.OK_OPTION )
+        {
+            return;
+        }
+
+        String s = id.getText();
+
+        if (s != null)
+        {
+            if (s.indexOf(" ") > -1)
+            {
+                JOptionPane.showMessageDialog(ap,
+                    "Spaces have been converted to \"_\"",
+                    "No spaces allowed in Sequence Name",
+                    JOptionPane.WARNING_MESSAGE);
+            }
+
+            s = s.replace(' ', '_');
+            sequence.getDatasetSequence().setName(s);
+            sequence.setName(s);
+            ap.repaint();
+        }
+
+        sequence.getDatasetSequence().setDescription(description.getText());
+        sequence.setDescription(description.getText());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    void unGroupMenuItem_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = ap.av.getSelectionGroup();
+        ap.av.alignment.deleteGroup(sg);
+        ap.av.setSelectionGroup(null);
+        refresh();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void outline_actionPerformed(ActionEvent e)
+    {
+        SequenceGroup sg = getGroup();
+        Color col = JColorChooser.showDialog(this, "Select Outline Colour",
+                Color.BLUE);
+
+        if (col != null)
+        {
+            sg.setOutlineColour(col);
+        }
+
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void showBoxes_actionPerformed(ActionEvent e)
+    {
+        getGroup().setDisplayBoxes(showBoxes.isSelected());
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void showText_actionPerformed(ActionEvent e)
+    {
+        getGroup().setDisplayText(showText.isSelected());
+        refresh();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void showColourText_actionPerformed(ActionEvent e)
+    {
+        getGroup().setColourText(showColourText.isSelected());
+        refresh();
+    }
+
+    public void showLink(String url)
+    {
+      try
+      {
+        jalview.util.BrowserLauncher.openURL(url);
+      }
+      catch (Exception ex)
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+            "Unixers: Couldn't find default web browser."
+           +"\nAdd the full path to your browser in Preferences.",
+           "Web browser not found", JOptionPane.WARNING_MESSAGE );
+
+
+        ex.printStackTrace();
+      }
+    }
+
+    void hideSequences(boolean representGroup)
+    {
+      SequenceGroup sg = ap.av.getSelectionGroup();
+      if(sg==null || sg.getSize(false)<1)
+      {
+        ap.av.hideSequence(sequence);
+        return;
+      }
+
+        int index = 0;
+        while(index < sg.getSize(false))
+        {
+          if(representGroup && sg.getSequenceAt(index)!=sequence)
+          {
+            sequence.addHiddenSequence(sg.getSequenceAt(index));
+            ap.av.hideSequence(sg.getSequenceAt(index));
+          }
+          else if(!representGroup)
+          {
+            ap.av.hideSequence(sg.getSequenceAt(index));
+          }
+          index ++;
+        }
+
+        ap.av.setSelectionGroup(null);
+    }
+
+  public void copy_actionPerformed(ActionEvent e)
+  {
+    ap.alignFrame.copy_actionPerformed(null);
+  }
+
+  public void cut_actionPerformed(ActionEvent e)
+  {
+    ap.alignFrame.cut_actionPerformed(null);
+  }
+
+  public void upperCase_actionPerformed(ActionEvent e)
+  {
+    changeCase(e.getSource());
+  }
+
+  public void lowerCase_actionPerformed(ActionEvent e)
+  {
+    changeCase(e.getSource());
+  }
+
+  public void toggle_actionPerformed(ActionEvent e)
+  {
+    changeCase(e.getSource());
+  }
+
+  void changeCase(Object source)
+  {
+    SequenceGroup sg = ap.av.getSelectionGroup();
+    if (sg != null)
+    {
+      for (int g = 0; g < sg.getSize(true); g++)
+      {
+        int start = sg.getStartRes();
+        int end = sg.getEndRes() + 1;
+
+        do
+        {
+          if (ap.av.hasHiddenColumns)
+          {
+            end = ap.av.colSel.getHiddenBoundaryRight(start);
+            if (start == end)
+              end = sg.getEndRes() + 1;
+            if (end > sg.getEndRes())
+              end = sg.getEndRes() + 1;
+          }
+
+          if (source == toggle)
+            ( (SequenceI) sg.getSequences(true).elementAt(g))
+                .toggleCase(start, end);
+          else
+            ( (SequenceI) sg.getSequences(true).elementAt(g))
+                .changeCase(source == upperCase, start, end);
+
+          if (ap.av.hasHiddenColumns)
+          {
+            start = ap.av.colSel.adjustForHiddenColumns(end);
+            start = ap.av.colSel.getHiddenBoundaryLeft(start) + 1;
+          }
+
+        }
+        while (end < sg.getEndRes());
+      }
+      ap.repaint();
+    }
+  }
+
+  public void outputText_actionPerformed(ActionEvent e)
+  {
+    CutAndPasteTransfer cap = new CutAndPasteTransfer();
+    Desktop.addInternalFrame(cap,
+                             "Alignment output - " + e.getActionCommand(), 600,
+                             500);
+
+    String [] omitHidden = null;
+
+    if(ap.av.hasHiddenColumns)
+    {
+      System.out.println("PROMPT USER HERE");
+      omitHidden = ap.av.getViewAsString(true);
+    }
+
+    cap.setText(new FormatAdapter().formatSequences(
+        e.getActionCommand(),
+        ap.av.getSelectionAsNewSequence(),
+        omitHidden));
+  }
+
+
+  public void pdbFromFile_actionPerformed(ActionEvent e)
+  {
+     jalview.io.JalviewFileChooser chooser
+         = new jalview.io.JalviewFileChooser(jalview.bin.Cache.
+         getProperty(
+             "LAST_DIRECTORY"));
+     chooser.setFileView(new jalview.io.JalviewFileView());
+     chooser.setDialogTitle("Select a PDB file");
+     chooser.setToolTipText("Load a PDB file");
+
+     int value = chooser.showOpenDialog(null);
+
+     if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
+     {
+       PDBEntry entry = new PDBEntry();
+       String choice = chooser.getSelectedFile().getPath();
+       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
+       try
+       {
+         MCview.PDBfile pdbfile = new MCview.PDBfile(choice,
+                                       jalview.io.AppletFormatAdapter.FILE);
+
+         if (pdbfile.id == null)
+         {
+           String reply = JOptionPane.showInternalInputDialog(
+               Desktop.desktop,
+               "Couldn't find a PDB id in the file supplied."
+               + "Please enter an Id to identify this structure.",
+               "No PDB Id in File", JOptionPane.QUESTION_MESSAGE);
+           if (reply == null)
+             return;
+
+           entry.setId(reply);
+         }
+         else
+           entry.setId(pdbfile.id);
+       }
+       catch (java.io.IOException ex)
+       {
+         ex.printStackTrace();
+       }
+
+       entry.setFile(choice);
+       sequence.getDatasetSequence().addPDBId(entry);
+     }
+
+  }
+
+  public void enterPDB_actionPerformed(ActionEvent e)
+  {
+    String id = JOptionPane.showInternalInputDialog(Desktop.desktop,
+        "Enter PDB Id", "Enter PDB Id", JOptionPane.QUESTION_MESSAGE);
+
+    if (id != null && id.length() > 0)
+    {
+      PDBEntry entry = new PDBEntry();
+      entry.setId(id);
+      sequence.getDatasetSequence()
+          .addPDBId(entry);
+    }
+  }
+
+  public void discoverPDB_actionPerformed(ActionEvent e)
+  {
+    new jalview.io.DBRefFetcher(
+             ap.av.getAlignment(), ap.alignFrame).fetchDBRefs(false);
+  }
+}
index f322daa..524c71c 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.io.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-import java.util.*;\r
-\r
-import jalview.bin.Cache;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Preferences extends GPreferences\r
-{\r
-    /** Holds name and link separated with | character. Sequence ID must be $SEQUENCE_ID$ */\r
-    public static Vector sequenceURLLinks;\r
-    static\r
-    {\r
-      String string = Cache.getDefault("SEQUENCE_LINKS",\r
-                                       "SRS|http://srs.ebi.ac.uk/srs7bin/cgi-bin/wgetz?-e+[uniprot-all:$SEQUENCE_ID$]+-vn+2");\r
-      sequenceURLLinks = new Vector();\r
-\r
-      try\r
-      {\r
-        StringTokenizer st = new StringTokenizer(string, "|");\r
-        while (st.hasMoreElements())\r
-        {\r
-          sequenceURLLinks.addElement(st.nextToken() + "|" + st.nextToken());\r
-        }\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        System.out.println(ex + "\nError parsing sequence links");\r
-      }\r
-    }\r
-    Vector nameLinks, urlLinks;\r
-\r
-    JInternalFrame frame;\r
-\r
-\r
-    /**\r
-     * Creates a new Preferences object.\r
-     */\r
-    public Preferences()\r
-    {\r
-\r
-        frame = new JInternalFrame();\r
-        frame.setContentPane(this);\r
-        Desktop.addInternalFrame(frame, "Preferences", 480, 395);\r
-        frame.setMinimumSize(new Dimension(480,395));\r
-\r
-        seqLimit.setSelected(    Cache.getDefault("SHOW_JVSUFFIX", true));\r
-        fullScreen.setSelected(  Cache.getDefault("SHOW_FULLSCREEN", false));\r
-        annotations.setSelected( Cache.getDefault("SHOW_ANNOTATIONS", true));\r
-\r
-        conservation.setEnabled( Cache.getDefault("SHOW_ANNOTATIONS", true));\r
-        quality.setEnabled(Cache.getDefault("SHOW_ANNOTATIONS", true));\r
-        identity.setEnabled(Cache.getDefault("SHOW_ANNOTATIONS", true));\r
-\r
-        conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));\r
-        quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));\r
-        identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));\r
-\r
-        for (int i = 0; i < 13; i++)\r
-        {\r
-            colour.addItem(ColourSchemeProperty.getColourName(i));\r
-        }\r
-\r
-        String string = Cache.getDefault("DEFAULT_COLOUR", "None");\r
-\r
-        colour.setSelectedItem(string);\r
-\r
-        String[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()\r
-                                                     .getAvailableFontFamilyNames();\r
-\r
-        for (int i = 0; i < fonts.length; i++)\r
-        {\r
-            fontNameCB.addItem(fonts[i]);\r
-        }\r
-\r
-        for (int i = 1; i < 31; i++)\r
-        {\r
-            fontSizeCB.addItem(i + "");\r
-        }\r
-\r
-        fontStyleCB.addItem("plain");\r
-        fontStyleCB.addItem("bold");\r
-        fontStyleCB.addItem("italic");\r
-\r
-        fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));\r
-        fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));\r
-        fontStyleCB.setSelectedItem(Cache.getDefault("FONT_STYLE", Font.PLAIN + "") );\r
-\r
-        smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", false));\r
-\r
-        gapSymbolCB.addItem("-");\r
-        gapSymbolCB.addItem(".");\r
-\r
-        gapSymbolCB.setSelectedItem( Cache.getDefault("GAP_SYMBOL", "-"));\r
-\r
-        startupCheckbox.setSelected( Cache.getDefault("SHOW_STARTUP_FILE", true) );\r
-        startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",\r
-         "http://www.jalview.org/examples/exampleFile.jar"));\r
-\r
-        sortby.addItem("No sort");\r
-        sortby.addItem("Id");\r
-        sortby.addItem("Pairwise Identity");\r
-        sortby.setSelectedItem( Cache.getDefault("SORT_ALIGNMENT", "No sort") );\r
-\r
-        epsRendering.addItem("Prompt each time");\r
-        epsRendering.addItem("Lineart");\r
-        epsRendering.addItem("Text");\r
-        epsRendering.setSelectedItem( Cache.getDefault("EPS_RENDERING", "Prompt each time"));\r
-\r
-        blcjv.setSelected( Cache.getDefault("BLC_JVSUFFIX", true) );\r
-        clustaljv.setSelected( Cache.getDefault("CLUSTAL_JVSUFFIX", true) );\r
-        fastajv.setSelected( Cache.getDefault("FASTA_JVSUFFIX", true) );\r
-        msfjv.setSelected( Cache.getDefault("MSF_JVSUFFIX", true) );\r
-        pfamjv.setSelected( Cache.getDefault("PFAM_JVSUFFIX", true) );\r
-        pileupjv.setSelected( Cache.getDefault("PILEUP_JVSUFFIX", true) );\r
-        pirjv.setSelected( Cache.getDefault("PIR_JVSUFFIX", true) );\r
-\r
-  /****************************************************\r
-   * Set up Connections\r
-   */\r
-        nameLinks = new Vector();\r
-        urlLinks = new Vector();\r
-        for(int i=0; i<sequenceURLLinks.size(); i++)\r
-        {\r
-          String link = sequenceURLLinks.elementAt(i).toString();\r
-          nameLinks.addElement(link.substring(0, link.indexOf("|")) );\r
-          urlLinks.addElement(link.substring(link.indexOf("|")+1));\r
-        }\r
-\r
-        updateLinkData();\r
-\r
-        useProxy.setSelected( Cache.getDefault("USE_PROXY", false));\r
-        proxyServerTB.setEnabled(useProxy.isSelected());\r
-        proxyPortTB.setEnabled(useProxy.isSelected());\r
-        proxyServerTB.setText( Cache.getDefault("PROXY_SERVER", ""));\r
-        proxyPortTB.setText(Cache.getDefault("PROXY_PORT", ""));\r
-\r
-        defaultBrowser.setText( Cache.getDefault("DEFAULT_BROWSER",""));\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-  }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void ok_actionPerformed(ActionEvent e)\r
-    {\r
-\r
-      Cache.applicationProperties.setProperty("SHOW_JVSUFFIX", Boolean.toString(seqLimit.isSelected()));\r
-      Cache.applicationProperties.setProperty("SHOW_FULLSCREEN", Boolean.toString(fullScreen.isSelected()));\r
-\r
-      Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", Boolean.toString(annotations.isSelected()));\r
-      Cache.applicationProperties.setProperty("SHOW_CONSERVATION", Boolean.toString(conservation.isSelected()));\r
-      Cache.applicationProperties.setProperty("SHOW_QUALITY", Boolean.toString(quality.isSelected()));\r
-      Cache.applicationProperties.setProperty("SHOW_IDENTITY", Boolean.toString(identity.isSelected()));\r
-\r
-      Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour.getSelectedItem().toString());\r
-      Cache.applicationProperties.setProperty("GAP_SYMBOL", gapSymbolCB.getSelectedItem().toString());\r
-\r
-      Cache.applicationProperties.setProperty("FONT_NAME", fontNameCB.getSelectedItem().toString());\r
-      Cache.applicationProperties.setProperty("FONT_STYLE", fontStyleCB.getSelectedItem().toString());\r
-      Cache.applicationProperties.setProperty("FONT_SIZE", fontSizeCB.getSelectedItem().toString());\r
-\r
-      Cache.applicationProperties.setProperty("ANTI_ALIAS", Boolean.toString(smoothFont.isSelected()));\r
-\r
-      Cache.applicationProperties.setProperty("STARTUP_FILE", startupFileTextfield.getText());\r
-      Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",  Boolean.toString(startupCheckbox.isSelected()));\r
-\r
-      Cache.applicationProperties.setProperty("SORT_ALIGNMENT", sortby.getSelectedItem().toString() );\r
-\r
-      if(epsRendering.getSelectedItem().equals("Prompt each time"))\r
-        Cache.applicationProperties.remove("EPS_RENDERING");\r
-      else\r
-        Cache.applicationProperties.setProperty("EPS_RENDERING", epsRendering.getSelectedItem().toString());\r
-\r
-      if(defaultBrowser.getText().trim().length()<1)\r
-        Cache.applicationProperties.remove("DEFAULT_BROWSER");\r
-      else\r
-        Cache.applicationProperties.setProperty("DEFAULT_BROWSER",\r
-                                                defaultBrowser.getText());\r
-\r
-        jalview.util.BrowserLauncher.resetBrowser();\r
-\r
-        if(nameLinks.size()>0)\r
-        {\r
-          StringBuffer links = new StringBuffer();\r
-          sequenceURLLinks = new Vector();\r
-          for (int i = 0; i < nameLinks.size(); i++)\r
-          {\r
-            sequenceURLLinks.addElement(nameLinks.elementAt(i)+"|"+urlLinks.elementAt(i));\r
-            links.append(sequenceURLLinks.elementAt(i).toString());\r
-            links.append("|");\r
-          }\r
-          // remove last "|"\r
-          links.setLength( links.length()-1 );\r
-          Cache.applicationProperties.setProperty("SEQUENCE_LINKS", links.toString());\r
-        }\r
-        else\r
-          Cache.applicationProperties.remove("SEQUENCE_LINKS");\r
-\r
-\r
-        Cache.applicationProperties.setProperty("USE_PROXY", Boolean.toString(useProxy.isSelected()));\r
-\r
-        if (proxyServerTB.getText().trim().length() < 1)\r
-          Cache.applicationProperties.remove("PROXY_SERVER");\r
-        else\r
-          Cache.applicationProperties.setProperty("PROXY_SERVER",\r
-                                                  proxyServerTB.getText());\r
-\r
-        if (proxyPortTB.getText().trim().length() < 1)\r
-          Cache.applicationProperties.remove("PROXY_PORT");\r
-        else\r
-          Cache.applicationProperties.setProperty("PROXY_PORT", proxyPortTB.getText());\r
-\r
-        if(useProxy.isSelected())\r
-        {\r
-          System.setProperty("http.proxyHost", proxyServerTB.getText());\r
-          System.setProperty("http.proxyPort", proxyPortTB.getText());\r
-        }\r
-        else\r
-        {\r
-          System.setProperty("http.proxyHost","");\r
-          System.setProperty("http.proxyPort","");\r
-        }\r
-\r
-\r
-        Cache.applicationProperties.setProperty("BLC_JVSUFFIX", Boolean.toString(blcjv.isSelected()) );\r
-        Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX", Boolean.toString(clustaljv.isSelected()) );\r
-        Cache.applicationProperties.setProperty("FASTA_JVSUFFIX", Boolean.toString(fastajv.isSelected()) );\r
-        Cache.applicationProperties.setProperty("MSF_JVSUFFIX", Boolean.toString(msfjv.isSelected()) );\r
-        Cache.applicationProperties.setProperty("PFAM_JVSUFFIX", Boolean.toString(pfamjv.isSelected()) );\r
-        Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX", Boolean.toString(pileupjv.isSelected()) );\r
-        Cache.applicationProperties.setProperty("PIR_JVSUFFIX", Boolean.toString(pirjv.isSelected()) );\r
-\r
-\r
-        Cache.saveProperties();\r
-        try\r
-        {\r
-            frame.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void startupFileTextfield_mouseClicked()\r
-    {\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"),\r
-                new String[]\r
-                {\r
-                    "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
-                    "jar"\r
-                },\r
-                new String[]\r
-                {\r
-                    "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
-                }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));\r
-        chooser.setFileView(new JalviewFileView());\r
-        chooser.setDialogTitle("Select startup file");\r
-\r
-        int value = chooser.showOpenDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            jalview.bin.Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",\r
-                chooser.getSelectedFormat());\r
-            startupFileTextfield.setText(chooser.getSelectedFile()\r
-                                                .getAbsolutePath());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-        try\r
-        {\r
-            frame.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void annotations_actionPerformed(ActionEvent e)\r
-    {\r
-        conservation.setEnabled(annotations.isSelected());\r
-        quality.setEnabled(annotations.isSelected());\r
-        identity.setEnabled(annotations.isSelected());\r
-    }\r
-\r
-\r
-    public void newLink_actionPerformed(ActionEvent e) {\r
-\r
-      GSequenceLink link = new GSequenceLink();\r
-      boolean valid = false;\r
-      while( !valid )\r
-      {\r
-        if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,\r
-                                                  "New sequence URL link",\r
-                                                  JOptionPane.OK_CANCEL_OPTION\r
-                                                  ,-1, null)\r
-            == JOptionPane.OK_OPTION)\r
-        {\r
-          if (link.checkValid())\r
-          {\r
-            nameLinks.addElement(link.getName());\r
-            urlLinks.addElement(link.getURL());\r
-            updateLinkData();\r
-            valid = true;\r
-          }\r
-        }\r
-        else\r
-          break;\r
-      }\r
-    }\r
-\r
-    public void editLink_actionPerformed(ActionEvent e) {\r
-      GSequenceLink link = new GSequenceLink();\r
-\r
-      int index = linkNameList.getSelectedIndex();\r
-      if(index==-1)\r
-      {\r
-        JOptionPane.showInternalMessageDialog(Desktop.desktop, "No link selected!"\r
-            ,"No link selected", JOptionPane.WARNING_MESSAGE);\r
-        return;\r
-      }\r
-\r
-      link.setName( nameLinks.elementAt(index).toString() );\r
-      link.setURL( urlLinks.elementAt(index).toString() );\r
-\r
-      boolean valid = false;\r
-      while (!valid)\r
-      {\r
-\r
-        if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,\r
-                                                  "New sequence URL link",\r
-                                                  JOptionPane.OK_CANCEL_OPTION\r
-                                                  ,-1, null)\r
-            == JOptionPane.OK_OPTION)\r
-        {\r
-          if (link.checkValid())\r
-          {\r
-            nameLinks.setElementAt(link.getName(), index);\r
-            urlLinks.setElementAt(link.getURL(), index);\r
-            updateLinkData();\r
-            valid = true;\r
-          }\r
-        }\r
-\r
-        else\r
-          break;\r
-      }\r
-    }\r
-\r
-    public void deleteLink_actionPerformed(ActionEvent e) {\r
-      int index = linkNameList.getSelectedIndex();\r
-      if(index==-1)\r
-      {\r
-        JOptionPane.showInternalMessageDialog(Desktop.desktop, "No link selected!"\r
-            ,"No link selected", JOptionPane.WARNING_MESSAGE);\r
-        return;\r
-      }\r
-      nameLinks.removeElementAt(index);\r
-      urlLinks.removeElementAt(index);\r
-      updateLinkData();\r
-    }\r
-\r
-    void updateLinkData()\r
-    {\r
-      linkNameList.setListData(nameLinks);\r
-      linkURLList.setListData(urlLinks);\r
-    }\r
-\r
-    public void defaultBrowser_mouseClicked(MouseEvent e)\r
-    {\r
-      JFileChooser chooser = new JFileChooser(".");\r
-      chooser.setDialogTitle("Select default web browser");\r
-\r
-      int value = chooser.showOpenDialog(this);\r
-\r
-      if (value == JFileChooser.APPROVE_OPTION)\r
-      {\r
-        defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());\r
-      }\r
-\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.io.*;
+
+import jalview.jbgui.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import java.util.*;
+
+import jalview.bin.Cache;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Preferences extends GPreferences
+{
+    /** Holds name and link separated with | character. Sequence ID must be $SEQUENCE_ID$ */
+    public static Vector sequenceURLLinks;
+    static
+    {
+      String string = Cache.getDefault("SEQUENCE_LINKS",
+                                       "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+      sequenceURLLinks = new Vector();
+
+      try
+      {
+        StringTokenizer st = new StringTokenizer(string, "|");
+        while (st.hasMoreElements())
+        {
+          sequenceURLLinks.addElement(st.nextToken() + "|" + st.nextToken());
+        }
+      }
+      catch (Exception ex)
+      {
+        System.out.println(ex + "\nError parsing sequence links");
+      }
+    }
+    Vector nameLinks, urlLinks;
+
+    JInternalFrame frame;
+
+    DasSourceBrowser dasSource;
+
+
+    /**
+     * Creates a new Preferences object.
+     */
+    public Preferences()
+    {
+
+        frame = new JInternalFrame();
+        frame.setContentPane(this);
+        dasSource = new DasSourceBrowser();
+        dasPanel.add(dasSource, BorderLayout.CENTER);
+
+        int width = 500, height = 420;
+        if(System.getProperty("os.name").startsWith("Mac"))
+        {
+          width = 570;
+          height = 460;
+        }
+
+        Desktop.addInternalFrame(frame, "Preferences", width, height);
+        frame.setMinimumSize(new Dimension(width, height));
+
+        seqLimit.setSelected(    Cache.getDefault("SHOW_JVSUFFIX", true));
+        fullScreen.setSelected(  Cache.getDefault("SHOW_FULLSCREEN", false));
+        annotations.setSelected( Cache.getDefault("SHOW_ANNOTATIONS", true));
+
+        conservation.setEnabled( Cache.getDefault("SHOW_ANNOTATIONS", true));
+        quality.setEnabled(Cache.getDefault("SHOW_ANNOTATIONS", true));
+        identity.setEnabled(Cache.getDefault("SHOW_ANNOTATIONS", true));
+
+        conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
+        quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
+        identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
+
+        for (int i = 0; i < 13; i++)
+        {
+            colour.addItem(ColourSchemeProperty.getColourName(i));
+        }
+
+        String string = Cache.getDefault("DEFAULT_COLOUR", "None");
+
+        colour.setSelectedItem(string);
+
+        String[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
+                                                     .getAvailableFontFamilyNames();
+
+        for (int i = 0; i < fonts.length; i++)
+        {
+            fontNameCB.addItem(fonts[i]);
+        }
+
+        for (int i = 1; i < 31; i++)
+        {
+            fontSizeCB.addItem(i + "");
+        }
+
+        fontStyleCB.addItem("plain");
+        fontStyleCB.addItem("bold");
+        fontStyleCB.addItem("italic");
+
+        fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
+        fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
+        fontStyleCB.setSelectedItem(Cache.getDefault("FONT_STYLE", Font.PLAIN + "") );
+
+        smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", false));
+
+        wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
+
+        gapSymbolCB.addItem("-");
+        gapSymbolCB.addItem(".");
+
+        gapSymbolCB.setSelectedItem( Cache.getDefault("GAP_SYMBOL", "-"));
+
+        startupCheckbox.setSelected( Cache.getDefault("SHOW_STARTUP_FILE", true) );
+        startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
+         "http://www.jalview.org/examples/exampleFile.jar"));
+
+        sortby.addItem("No sort");
+        sortby.addItem("Id");
+        sortby.addItem("Pairwise Identity");
+        sortby.setSelectedItem( Cache.getDefault("SORT_ALIGNMENT", "No sort") );
+
+        epsRendering.addItem("Prompt each time");
+        epsRendering.addItem("Lineart");
+        epsRendering.addItem("Text");
+        epsRendering.setSelectedItem( Cache.getDefault("EPS_RENDERING", "Prompt each time"));
+
+        blcjv.setSelected( Cache.getDefault("BLC_JVSUFFIX", true) );
+        clustaljv.setSelected( Cache.getDefault("CLUSTAL_JVSUFFIX", true) );
+        fastajv.setSelected( Cache.getDefault("FASTA_JVSUFFIX", true) );
+        msfjv.setSelected( Cache.getDefault("MSF_JVSUFFIX", true) );
+        pfamjv.setSelected( Cache.getDefault("PFAM_JVSUFFIX", true) );
+        pileupjv.setSelected( Cache.getDefault("PILEUP_JVSUFFIX", true) );
+        pirjv.setSelected( Cache.getDefault("PIR_JVSUFFIX", true) );
+
+        modellerOutput.setSelected( Cache.getDefault("PIR_MODELLER", false));
+
+        autoCalculateConsCheck.setSelected( Cache.getDefault("AUTO_CALC_CONSENSUS", true));
+        padGaps.setSelected( Cache.getDefault("PAD_GAPS", false));
+
+  /****************************************************
+   * Set up Connections
+   */
+        nameLinks = new Vector();
+        urlLinks = new Vector();
+        for(int i=0; i<sequenceURLLinks.size(); i++)
+        {
+          String link = sequenceURLLinks.elementAt(i).toString();
+          nameLinks.addElement(link.substring(0, link.indexOf("|")) );
+          urlLinks.addElement(link.substring(link.indexOf("|")+1));
+        }
+
+        updateLinkData();
+
+        useProxy.setSelected( Cache.getDefault("USE_PROXY", false));
+        proxyServerTB.setEnabled(useProxy.isSelected());
+        proxyPortTB.setEnabled(useProxy.isSelected());
+        proxyServerTB.setText( Cache.getDefault("PROXY_SERVER", ""));
+        proxyPortTB.setText(Cache.getDefault("PROXY_PORT", ""));
+
+        defaultBrowser.setText( Cache.getDefault("DEFAULT_BROWSER",""));
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+  }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void ok_actionPerformed(ActionEvent e)
+    {
+
+      Cache.applicationProperties.setProperty("SHOW_JVSUFFIX", Boolean.toString(seqLimit.isSelected()));
+      Cache.applicationProperties.setProperty("SHOW_FULLSCREEN", Boolean.toString(fullScreen.isSelected()));
+
+      Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", Boolean.toString(annotations.isSelected()));
+      Cache.applicationProperties.setProperty("SHOW_CONSERVATION", Boolean.toString(conservation.isSelected()));
+      Cache.applicationProperties.setProperty("SHOW_QUALITY", Boolean.toString(quality.isSelected()));
+      Cache.applicationProperties.setProperty("SHOW_IDENTITY", Boolean.toString(identity.isSelected()));
+
+      Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour.getSelectedItem().toString());
+      Cache.applicationProperties.setProperty("GAP_SYMBOL", gapSymbolCB.getSelectedItem().toString());
+
+      Cache.applicationProperties.setProperty("FONT_NAME", fontNameCB.getSelectedItem().toString());
+      Cache.applicationProperties.setProperty("FONT_STYLE", fontStyleCB.getSelectedItem().toString());
+      Cache.applicationProperties.setProperty("FONT_SIZE", fontSizeCB.getSelectedItem().toString());
+
+      Cache.applicationProperties.setProperty("ANTI_ALIAS", Boolean.toString(smoothFont.isSelected()));
+
+      Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", Boolean.toString(wrap.isSelected()));
+
+      Cache.applicationProperties.setProperty("STARTUP_FILE", startupFileTextfield.getText());
+      Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",  Boolean.toString(startupCheckbox.isSelected()));
+
+      Cache.applicationProperties.setProperty("SORT_ALIGNMENT", sortby.getSelectedItem().toString() );
+
+      if(epsRendering.getSelectedItem().equals("Prompt each time"))
+        Cache.applicationProperties.remove("EPS_RENDERING");
+      else
+        Cache.applicationProperties.setProperty("EPS_RENDERING", epsRendering.getSelectedItem().toString());
+
+      if(defaultBrowser.getText().trim().length()<1)
+        Cache.applicationProperties.remove("DEFAULT_BROWSER");
+      else
+        Cache.applicationProperties.setProperty("DEFAULT_BROWSER",
+                                                defaultBrowser.getText());
+
+        jalview.util.BrowserLauncher.resetBrowser();
+
+        if(nameLinks.size()>0)
+        {
+          StringBuffer links = new StringBuffer();
+          sequenceURLLinks = new Vector();
+          for (int i = 0; i < nameLinks.size(); i++)
+          {
+            sequenceURLLinks.addElement(nameLinks.elementAt(i)+"|"+urlLinks.elementAt(i));
+            links.append(sequenceURLLinks.elementAt(i).toString());
+            links.append("|");
+          }
+          // remove last "|"
+          links.setLength( links.length()-1 );
+          Cache.applicationProperties.setProperty("SEQUENCE_LINKS", links.toString());
+        }
+        else
+          Cache.applicationProperties.remove("SEQUENCE_LINKS");
+
+
+        Cache.applicationProperties.setProperty("USE_PROXY", Boolean.toString(useProxy.isSelected()));
+
+        if (proxyServerTB.getText().trim().length() < 1)
+          Cache.applicationProperties.remove("PROXY_SERVER");
+        else
+          Cache.applicationProperties.setProperty("PROXY_SERVER",
+                                                  proxyServerTB.getText());
+
+        if (proxyPortTB.getText().trim().length() < 1)
+          Cache.applicationProperties.remove("PROXY_PORT");
+        else
+          Cache.applicationProperties.setProperty("PROXY_PORT", proxyPortTB.getText());
+
+        if(useProxy.isSelected())
+        {
+          System.setProperty("http.proxyHost", proxyServerTB.getText());
+          System.setProperty("http.proxyPort", proxyPortTB.getText());
+        }
+        else
+        {
+          System.setProperty("http.proxyHost","");
+          System.setProperty("http.proxyPort","");
+        }
+
+
+        Cache.applicationProperties.setProperty("BLC_JVSUFFIX", Boolean.toString(blcjv.isSelected()) );
+        Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX", Boolean.toString(clustaljv.isSelected()) );
+        Cache.applicationProperties.setProperty("FASTA_JVSUFFIX", Boolean.toString(fastajv.isSelected()) );
+        Cache.applicationProperties.setProperty("MSF_JVSUFFIX", Boolean.toString(msfjv.isSelected()) );
+        Cache.applicationProperties.setProperty("PFAM_JVSUFFIX", Boolean.toString(pfamjv.isSelected()) );
+        Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX", Boolean.toString(pileupjv.isSelected()) );
+        Cache.applicationProperties.setProperty("PIR_JVSUFFIX", Boolean.toString(pirjv.isSelected()) );
+        Cache.applicationProperties.setProperty("PIR_MODELLER", Boolean.toString(modellerOutput.isSelected()) );
+        jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
+
+        Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
+                                                Boolean.toString(autoCalculateConsCheck.isSelected()));
+        Cache.applicationProperties.setProperty("PAD_GAPS",
+                                                Boolean.toString(padGaps.isSelected()));
+
+        dasSource.saveProperties(Cache.applicationProperties);
+
+        Cache.saveProperties();
+        try
+        {
+            frame.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void startupFileTextfield_mouseClicked()
+    {
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"),
+                new String[]
+                {
+                    "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
+                    "jar"
+                },
+                new String[]
+                {
+                    "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
+                }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Select startup file");
+
+        int value = chooser.showOpenDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            jalview.bin.Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
+                chooser.getSelectedFormat());
+            startupFileTextfield.setText(chooser.getSelectedFile()
+                                                .getAbsolutePath());
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void cancel_actionPerformed(ActionEvent e)
+    {
+        try
+        {
+            frame.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void annotations_actionPerformed(ActionEvent e)
+    {
+        conservation.setEnabled(annotations.isSelected());
+        quality.setEnabled(annotations.isSelected());
+        identity.setEnabled(annotations.isSelected());
+    }
+
+
+    public void newLink_actionPerformed(ActionEvent e) {
+
+      GSequenceLink link = new GSequenceLink();
+      boolean valid = false;
+      while( !valid )
+      {
+        if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+                                                  "New sequence URL link",
+                                                  JOptionPane.OK_CANCEL_OPTION
+                                                  ,-1, null)
+            == JOptionPane.OK_OPTION)
+        {
+          if (link.checkValid())
+          {
+            nameLinks.addElement(link.getName());
+            urlLinks.addElement(link.getURL());
+            updateLinkData();
+            valid = true;
+          }
+        }
+        else
+          break;
+      }
+    }
+
+    public void editLink_actionPerformed(ActionEvent e) {
+      GSequenceLink link = new GSequenceLink();
+
+      int index = linkNameList.getSelectedIndex();
+      if(index==-1)
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop, "No link selected!"
+            ,"No link selected", JOptionPane.WARNING_MESSAGE);
+        return;
+      }
+
+      link.setName( nameLinks.elementAt(index).toString() );
+      link.setURL( urlLinks.elementAt(index).toString() );
+
+      boolean valid = false;
+      while (!valid)
+      {
+
+        if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+                                                  "New sequence URL link",
+                                                  JOptionPane.OK_CANCEL_OPTION
+                                                  ,-1, null)
+            == JOptionPane.OK_OPTION)
+        {
+          if (link.checkValid())
+          {
+            nameLinks.setElementAt(link.getName(), index);
+            urlLinks.setElementAt(link.getURL(), index);
+            updateLinkData();
+            valid = true;
+          }
+        }
+
+        else
+          break;
+      }
+    }
+
+    public void deleteLink_actionPerformed(ActionEvent e) {
+      int index = linkNameList.getSelectedIndex();
+      if(index==-1)
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop, "No link selected!"
+            ,"No link selected", JOptionPane.WARNING_MESSAGE);
+        return;
+      }
+      nameLinks.removeElementAt(index);
+      urlLinks.removeElementAt(index);
+      updateLinkData();
+    }
+
+    void updateLinkData()
+    {
+      linkNameList.setListData(nameLinks);
+      linkURLList.setListData(urlLinks);
+    }
+
+    public void defaultBrowser_mouseClicked(MouseEvent e)
+    {
+      JFileChooser chooser = new JFileChooser(".");
+      chooser.setDialogTitle("Select default web browser");
+
+      int value = chooser.showOpenDialog(this);
+
+      if (value == JFileChooser.APPROVE_OPTION)
+      {
+        defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
+      }
+
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+  }
+}
index 3901b1f..0e193ba 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.event.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.event.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class RedundancyPanel extends GSliderPanel\r
-{\r
-    AlignFrame af;\r
-    AlignmentPanel ap;\r
-    Stack historyList = new Stack(); // simpler than synching with alignFrame.\r
-\r
-    /**\r
-     * Creates a new RedundancyPanel object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     * @param af DOCUMENT ME!\r
-     */\r
-    public RedundancyPanel(AlignmentPanel ap, AlignFrame af)\r
-    {\r
-        this.ap = ap;\r
-        this.af = af;\r
-        label.setText("Enter the redundancy threshold");\r
-\r
-        slider.addChangeListener(new ChangeListener()\r
-            {\r
-                public void stateChanged(ChangeEvent evt)\r
-                {\r
-                    valueField.setText(slider.getValue() + "");\r
-                }\r
-            });\r
-\r
-        slider.setMinimum(0);\r
-        slider.setMaximum(100);\r
-        slider.setValue(100);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void applyButton_actionPerformed(ActionEvent e)\r
-    {\r
-        float threshold = slider.getValue();\r
-        Vector del;\r
-        historyList.push(new HistoryItem("Remove redundancy",\r
-                    ap.av.alignment, HistoryItem.HIDE));\r
-\r
-        if ((historyList.size() == 1) ||\r
-                !af.historyList.contains(historyList.firstElement()))\r
-        {\r
-            af.addHistoryItem((HistoryItem) historyList.firstElement());\r
-            af.updateEditMenuBar();\r
-        }\r
-\r
-        undoButton.setEnabled(true);\r
-\r
-        SequenceGroup sg = ap.av.getSelectionGroup();\r
-\r
-        if ((sg != null) && (sg.getSize() >= 1))\r
-        {\r
-            del = ap.av.alignment.removeRedundancy(threshold, sg.sequences);\r
-\r
-            for (int i = 0; i < del.size(); i++)\r
-            {\r
-                if (sg.sequences.contains((SequenceI) del.elementAt(i)))\r
-                {\r
-                    sg.deleteSequence((SequenceI) del.elementAt(i), true);\r
-                }\r
-            }\r
-        }\r
-        else\r
-        {\r
-            Vector s = new Vector();\r
-            int i = 0;\r
-\r
-            while (i < ap.av.alignment.getHeight())\r
-            {\r
-                s.addElement(ap.av.alignment.getSequenceAt(i));\r
-                i++;\r
-            }\r
-\r
-            del = ap.av.alignment.removeRedundancy(threshold, s);\r
-        }\r
-\r
-        // This has to be done before the restoreHistoryItem method of alignFrame will\r
-        // actually restore these sequences.\r
-        if (del.size() > 0)\r
-        {\r
-            for (int i = 0, j = del.size(); i < j; i++)\r
-            {\r
-                SequenceI sq = (SequenceI) del.elementAt(i);\r
-                sq.deleteChars(0, sq.getLength());\r
-            }\r
-        }\r
-\r
-        ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());\r
-        af.updateEditMenuBar();\r
-\r
-\r
-        if (ap.av.getAlignment().getHeight() < 1)\r
-        {\r
-            try\r
-            {\r
-                af.setClosed(true);\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void undoButton_actionPerformed(ActionEvent e)\r
-    {\r
-        HistoryItem hi = (HistoryItem) historyList.pop();\r
-        af.restoreHistoryItem(hi);\r
-\r
-        if (historyList.size() == 0)\r
-        {\r
-            undoButton.setEnabled(false);\r
-\r
-            if (af.historyList.contains(hi))\r
-            {\r
-                af.historyList.remove(hi);\r
-                af.updateEditMenuBar();\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void valueField_actionPerformed(ActionEvent e)\r
-    {\r
-        try\r
-        {\r
-            int i = Integer.parseInt(valueField.getText());\r
-            slider.setValue(i);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            valueField.setText(slider.getValue() + "");\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.jbgui.*;
+
+import java.awt.event.*;
+
+import java.util.*;
+
+import javax.swing.event.*;
+import jalview.util.Comparison;
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class RedundancyPanel extends GSliderPanel implements Runnable
+{
+    AlignFrame af;
+    AlignmentPanel ap;
+    Stack historyList = new Stack(); // simpler than synching with alignFrame.
+    float [] redundancy;
+    SequenceI [] originalSequences;
+    JInternalFrame frame;
+    Vector redundantSeqs;
+
+    /**
+     * Creates a new RedundancyPanel object.
+     *
+     * @param ap DOCUMENT ME!
+     * @param af DOCUMENT ME!
+     */
+    public RedundancyPanel(final AlignmentPanel ap, AlignFrame af)
+    {
+        this.ap = ap;
+        this.af = af;
+        redundantSeqs = new Vector();
+
+        slider.addChangeListener(new ChangeListener()
+            {
+                public void stateChanged(ChangeEvent evt)
+                {
+                    valueField.setText(slider.getValue() + "");
+                    sliderValueChanged();
+                }
+            });
+
+        applyButton.setText("Remove");
+        allGroupsCheck.setVisible(false);
+        slider.setMinimum(0);
+        slider.setMaximum(100);
+        slider.setValue(100);
+
+        Thread worker = new Thread(this);
+        worker.start();
+
+        frame = new JInternalFrame();
+        frame.setContentPane(this);
+        Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,
+                         100, false);
+        frame.addInternalFrameListener(new InternalFrameAdapter()
+            {
+              public void internalFrameClosing(InternalFrameEvent evt)
+              {
+               ap.idPanel.idCanvas.setHighlighted(null);
+              }
+            }
+            );
+
+    }
+
+
+    /**
+     * This is a copy of remove redundancy in jalivew.datamodel.Alignment
+     * except we dont want to remove redundancy, just calculate once
+     * so we can use the slider to dynamically hide redundant sequences
+     *
+     * @param threshold DOCUMENT ME!
+     * @param sel DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public void run()
+    {
+        JProgressBar progress = new JProgressBar();
+        progress.setIndeterminate(true);
+        southPanel.add(progress, java.awt.BorderLayout.SOUTH);
+
+        label.setText("Calculating....");
+
+        slider.setVisible(false);
+        applyButton.setEnabled(false);
+        valueField.setVisible(false);
+
+        validate();
+
+        String[] omitHidden = null;
+
+        SequenceGroup sg = ap.av.getSelectionGroup();
+        int height;
+
+        int start, end;
+
+        if ( (sg != null) && (sg.getSize(false) >= 1))
+        {
+           originalSequences = sg.getSequencesInOrder(ap.av.alignment);
+           start = sg.getStartRes();
+           end = sg.getEndRes();
+        }
+        else
+        {
+          originalSequences = ap.av.alignment.getSequencesArray();
+          start = 0;
+          end = ap.av.alignment.getWidth();
+        }
+
+        height = originalSequences.length;
+
+        redundancy = new float[height];
+        for (int i = 0; i < height; i++)
+        {
+          redundancy[i] = 0f;
+        }
+
+        if (ap.av.hasHiddenColumns)
+        {
+          omitHidden = ap.av.getViewAsString(sg!=null);
+        }
+
+
+       // long start = System.currentTimeMillis();
+
+        float pid;
+        String seqi, seqj;
+        for (int i = 0; i < height; i++)
+        {
+
+            for (int j = 0; j < i; j++)
+            {
+              if(i==j)
+                continue;
+
+              if(omitHidden==null)
+              {
+                seqi = originalSequences[i].getSequence(start, end);
+                seqj = originalSequences[j].getSequence(start, end);
+              }
+              else
+              {
+                seqi = omitHidden[i];
+                seqj = omitHidden[j];
+              }
+
+              pid = Comparison.PID( seqi,  seqj );
+
+              if(seqj.length() < seqi.length())
+                redundancy[j] = Math.max(pid, redundancy[j]);
+              else
+                redundancy[i] = Math.max(pid, redundancy[i]);
+
+            }
+        }
+
+        progress.setIndeterminate(false);
+        progress.setVisible(false);
+        progress = null;
+
+        label.setText("Enter the redundancy threshold");
+        slider.setVisible(true);
+        applyButton.setEnabled(true);
+        valueField.setVisible(true);
+
+        validate();
+       // System.out.println((System.currentTimeMillis()-start));
+    }
+
+    void sliderValueChanged()
+    {
+      if(redundancy==null)
+        return;
+
+      float value = slider.getValue();
+
+      for(int i=0; i<redundancy.length; i++)
+      {
+        if (value > redundancy[i])
+          redundantSeqs.remove(originalSequences[i]);
+        else if(!redundantSeqs.contains(originalSequences[i]))
+          redundantSeqs.add(originalSequences[i]);
+
+      }
+
+      ap.idPanel.idCanvas.setHighlighted(redundantSeqs);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void applyButton_actionPerformed(ActionEvent e)
+    {
+        historyList.push(new HistoryItem("Remove redundancy",
+                    ap.av.alignment, HistoryItem.HIDE));
+
+        if ((historyList.size() == 1) ||
+                !af.historyList.contains(historyList.firstElement()))
+        {
+            af.addHistoryItem((HistoryItem) historyList.firstElement());
+            af.updateEditMenuBar();
+        }
+
+        Vector del = new Vector();
+
+        undoButton.setEnabled(true);
+
+        float value = slider.getValue();
+        SequenceGroup sg = ap.av.getSelectionGroup();
+
+        for (int i = 0; i < redundancy.length; i++)
+        {
+          if (value <= redundancy[i])
+          {
+            SequenceI seq = originalSequences[i];
+            ap.av.alignment.deleteSequence(seq);
+            del.add(seq);
+            if (sg != null)
+            {
+              sg.deleteSequence(seq, false);
+            }
+          }
+        }
+
+
+        // This has to be done before the restoreHistoryItem method of alignFrame will
+        // actually restore these sequences.
+        if (del.size() > 0)
+        {
+            for (int i = 0, j = del.size(); i < j; i++)
+            {
+                SequenceI sq = (SequenceI) del.elementAt(i);
+                sq.deleteChars(0, sq.getLength());
+            }
+        }
+
+        ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
+        af.updateEditMenuBar();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void undoButton_actionPerformed(ActionEvent e)
+    {
+      HistoryItem hi = (HistoryItem) historyList.pop();
+      af.restoreHistoryItem(hi);
+
+      if (historyList.size() == 0)
+      {
+        undoButton.setEnabled(false);
+
+        if (af.historyList.contains(hi))
+        {
+          af.historyList.remove(hi);
+          af.updateEditMenuBar();
+        }
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void valueField_actionPerformed(ActionEvent e)
+    {
+        try
+        {
+            int i = Integer.parseInt(valueField.getText());
+            slider.setValue(i);
+        }
+        catch (Exception ex)
+        {
+            valueField.setText(slider.getValue() + "");
+        }
+    }
+
+
+}
index 724b9fb..5c13c92 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.math.*;\r
-\r
-import jalview.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class RotatableCanvas extends JPanel implements MouseListener,\r
-    MouseMotionListener, KeyListener\r
-{\r
-    RotatableMatrix idmat = new RotatableMatrix(3, 3);\r
-    RotatableMatrix objmat = new RotatableMatrix(3, 3);\r
-    RotatableMatrix rotmat = new RotatableMatrix(3, 3);\r
-\r
-    //RubberbandRectangle rubberband;\r
-    boolean drawAxes = true;\r
-    int omx = 0;\r
-    int mx = 0;\r
-    int omy = 0;\r
-    int my = 0;\r
-    Image img;\r
-    Graphics ig;\r
-    Dimension prefsize;\r
-    float[] centre = new float[3];\r
-    float[] width = new float[3];\r
-    float[] max = new float[3];\r
-    float[] min = new float[3];\r
-    float maxwidth;\r
-    float scale;\r
-    int npoint;\r
-    Vector points;\r
-    float[][] orig;\r
-    float[][] axes;\r
-    int startx;\r
-    int starty;\r
-    int lastx;\r
-    int lasty;\r
-    int rectx1;\r
-    int recty1;\r
-    int rectx2;\r
-    int recty2;\r
-    float scalefactor = 1;\r
-    AlignViewport av;\r
-    boolean showLabels = false;\r
-    Color bgColour = Color.black;\r
-\r
-    //  Controller    controller;\r
-    public RotatableCanvas(AlignViewport av)\r
-    {\r
-      this.av = av;\r
-    }\r
-\r
-    public void showLabels(boolean b)\r
-    {\r
-      showLabels = b;\r
-      repaint();\r
-    }\r
-\r
-    public void setPoints(Vector points, int npoint)\r
-    {\r
-        this.points = points;\r
-        this.npoint = npoint;\r
-        ToolTipManager.sharedInstance().registerComponent(this);\r
-        ToolTipManager.sharedInstance().setInitialDelay(0);\r
-        ToolTipManager.sharedInstance().setDismissDelay(10000);\r
-        PaintRefresher.Register(this, av.alignment);\r
-\r
-        prefsize = getPreferredSize();\r
-        orig = new float[npoint][3];\r
-\r
-        for (int i = 0; i < npoint; i++)\r
-        {\r
-            SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                orig[i][j] = sp.coord[j];\r
-            }\r
-        }\r
-\r
-        //Initialize the matrices to identity\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                if (i != j)\r
-                {\r
-                    idmat.addElement(i, j, 0);\r
-                    objmat.addElement(i, j, 0);\r
-                    rotmat.addElement(i, j, 0);\r
-                }\r
-                else\r
-                {\r
-                    idmat.addElement(i, j, 0);\r
-                    objmat.addElement(i, j, 0);\r
-                    rotmat.addElement(i, j, 0);\r
-                }\r
-            }\r
-        }\r
-\r
-        axes = new float[3][3];\r
-        initAxes();\r
-\r
-        findCentre();\r
-        findWidth();\r
-\r
-        scale = findScale();\r
-\r
-        addMouseListener(this);\r
-        addKeyListener(this);\r
-\r
-        addMouseMotionListener(this);\r
-\r
-    }\r
-\r
-    public void initAxes()\r
-    {\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                if (i != j)\r
-                {\r
-                    axes[i][j] = 0;\r
-                }\r
-                else\r
-                {\r
-                    axes[i][j] = 1;\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void findWidth()\r
-    {\r
-        max = new float[3];\r
-        min = new float[3];\r
-\r
-        max[0] = (float) -1e30;\r
-        max[1] = (float) -1e30;\r
-        max[2] = (float) -1e30;\r
-\r
-        min[0] = (float) 1e30;\r
-        min[1] = (float) 1e30;\r
-        min[2] = (float) 1e30;\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < npoint; j++)\r
-            {\r
-                SequencePoint sp = (SequencePoint) points.elementAt(j);\r
-\r
-                if (sp.coord[i] >= max[i])\r
-                {\r
-                    max[i] = sp.coord[i];\r
-                }\r
-\r
-                if (sp.coord[i] <= min[i])\r
-                {\r
-                    min[i] = sp.coord[i];\r
-                }\r
-            }\r
-        }\r
-\r
-        //    System.out.println("xmax " + max[0] + " min " + min[0]);\r
-        //System.out.println("ymax " + max[1] + " min " + min[1]);\r
-        //System.out.println("zmax " + max[2] + " min " + min[2]);\r
-        width[0] = Math.abs(max[0] - min[0]);\r
-        width[1] = Math.abs(max[1] - min[1]);\r
-        width[2] = Math.abs(max[2] - min[2]);\r
-\r
-        maxwidth = width[0];\r
-\r
-        if (width[1] > width[0])\r
-        {\r
-            maxwidth = width[1];\r
-        }\r
-\r
-        if (width[2] > width[1])\r
-        {\r
-            maxwidth = width[2];\r
-        }\r
-\r
-        //System.out.println("Maxwidth = " + maxwidth);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float findScale()\r
-    {\r
-        int dim;\r
-        int width;\r
-        int height;\r
-\r
-        if (getWidth() != 0)\r
-        {\r
-            width = getWidth();\r
-            height = getHeight();\r
-        }\r
-        else\r
-        {\r
-            width = prefsize.width;\r
-            height = prefsize.height;\r
-        }\r
-\r
-        if (width < height)\r
-        {\r
-            dim = width;\r
-        }\r
-        else\r
-        {\r
-            dim = height;\r
-        }\r
-\r
-        return (float) ((dim * scalefactor) / (2 * maxwidth));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void findCentre()\r
-    {\r
-        //Find centre coordinate\r
-        findWidth();\r
-\r
-        centre[0] = (max[0] + min[0]) / 2;\r
-        centre[1] = (max[1] + min[1]) / 2;\r
-        centre[2] = (max[2] + min[2]) / 2;\r
-\r
-        //    System.out.println("Centre x " + centre[0]);\r
-        //System.out.println("Centre y " + centre[1]);\r
-        //System.out.println("Centre z " + centre[2]);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Dimension getPreferredSize()\r
-    {\r
-        if (prefsize != null)\r
-        {\r
-            return prefsize;\r
-        }\r
-        else\r
-        {\r
-            return new Dimension(400, 400);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Dimension getMinimumSize()\r
-    {\r
-        return getPreferredSize();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g1)\r
-    {\r
-\r
-      Graphics2D g = (Graphics2D) g1;\r
-\r
-      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                         RenderingHints.VALUE_ANTIALIAS_ON);\r
-      if(points==null)\r
-      {\r
-        g.setFont(new Font("Verdana", Font.PLAIN, 18));\r
-        g.drawString("Calculating PCA....", 20, getHeight()/2);\r
-      }\r
-      else\r
-      {\r
-        //Only create the image at the beginning -\r
-        if ( (img == null) || (prefsize.width != getWidth()) ||\r
-            (prefsize.height != getHeight()))\r
-        {\r
-          prefsize.width = getWidth();\r
-          prefsize.height = getHeight();\r
-\r
-          scale = findScale();\r
-\r
-          //      System.out.println("New scale = " + scale);\r
-          img = createImage(getWidth(), getHeight());\r
-          ig = img.getGraphics();\r
-        }\r
-\r
-\r
-        drawBackground(ig, bgColour);\r
-        drawScene(ig);\r
-\r
-        if (drawAxes == true)\r
-        {\r
-          drawAxes(ig);\r
-        }\r
-\r
-        g.drawImage(img, 0, 0, this);\r
-      }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void drawAxes(Graphics g)\r
-    {\r
-\r
-        g.setColor(Color.yellow);\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            g.drawLine(getWidth() / 2, getHeight() / 2,\r
-                (int) ((axes[i][0] * scale * max[0]) + (getWidth() / 2)),\r
-                (int) ((axes[i][1] * scale * max[1]) + (getHeight() / 2)));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param col DOCUMENT ME!\r
-     */\r
-    public void drawBackground(Graphics g, Color col)\r
-    {\r
-        g.setColor(col);\r
-        g.fillRect(0, 0, prefsize.width, prefsize.height);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void drawScene(Graphics g1)\r
-    {\r
-\r
-      Graphics2D g = (Graphics2D) g1;\r
-\r
-      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                         RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-\r
-        int halfwidth = getWidth() / 2;\r
-        int halfheight = getHeight() / 2;\r
-\r
-        for (int i = 0; i < npoint; i++)\r
-        {\r
-            SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-            int x = (int) ((float) (sp.coord[0] - centre[0]) * scale) +\r
-                halfwidth;\r
-            int y = (int) ((float) (sp.coord[1] - centre[1]) * scale) +\r
-                halfheight;\r
-            float z = sp.coord[1] - centre[2];\r
-\r
-            if (sp.sequence.getColor() == Color.black)\r
-            {\r
-                g.setColor(Color.white);\r
-            }\r
-            else\r
-            {\r
-                g.setColor(sp.sequence.getColor());\r
-            }\r
-\r
-            if (av.getSelectionGroup() != null)\r
-            {\r
-                if (av.getSelectionGroup().sequences.contains(\r
-                            ((SequencePoint) points.elementAt(i)).sequence))\r
-                {\r
-                    g.setColor(Color.gray);\r
-                }\r
-            }\r
-\r
-            if (z < 0)\r
-            {\r
-                g.setColor(g.getColor().darker());\r
-            }\r
-\r
-            g.fillRect(x - 3, y - 3, 6, 6);\r
-            if(showLabels)\r
-            {\r
-              g.setColor(Color.red);\r
-              g.drawString( ( (SequencePoint) points.elementAt(i)).sequence.\r
-                           getName(),\r
-                           x - 3, y - 4);\r
-            }\r
-        }\r
-\r
-        //    //Now the rectangle\r
-        //    if (rectx2 != -1 && recty2 != -1) {\r
-        //      g.setColor(Color.white);\r
-        //\r
-        //      g.drawRect(rectx1,recty1,rectx2-rectx1,recty2-recty1);\r
-        //    }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Dimension minimumsize()\r
-    {\r
-        return prefsize;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Dimension preferredsize()\r
-    {\r
-        return prefsize;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void keyTyped(KeyEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void keyReleased(KeyEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void keyPressed(KeyEvent evt)\r
-    {\r
-        if (evt.getKeyCode() == KeyEvent.VK_UP)\r
-        {\r
-            scalefactor = (float) (scalefactor * 1.1);\r
-            scale = findScale();\r
-        }\r
-        else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
-        {\r
-            scalefactor = (float) (scalefactor * 0.9);\r
-            scale = findScale();\r
-        }\r
-        else if (evt.getKeyChar() == 's')\r
-        {\r
-            System.err.println("DEBUG: Rectangle selection"); // log.debug\r
-\r
-            if ((rectx2 != -1) && (recty2 != -1))\r
-            {\r
-                rectSelect(rectx1, recty1, rectx2, recty2);\r
-            }\r
-        }\r
-\r
-        repaint();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseClicked(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent evt)\r
-    {\r
-        int x = evt.getX();\r
-        int y = evt.getY();\r
-\r
-        mx = x;\r
-        my = y;\r
-\r
-        omx = mx;\r
-        omy = my;\r
-\r
-        startx = x;\r
-        starty = y;\r
-\r
-        rectx1 = x;\r
-        recty1 = y;\r
-\r
-        rectx2 = -1;\r
-        recty2 = -1;\r
-\r
-        SequenceI found = findPoint(x, y);\r
-\r
-        if (found != null)\r
-        {\r
-            if (av.getSelectionGroup() != null)\r
-            {\r
-                av.getSelectionGroup().addOrRemove(found, true);\r
-                PaintRefresher.Refresh(this, av.alignment);\r
-            }\r
-            else\r
-            {\r
-                av.setSelectionGroup(new SequenceGroup());\r
-                av.getSelectionGroup().addOrRemove(found, true);\r
-                av.getSelectionGroup().setEndRes(av.alignment.getWidth()-1);\r
-            }\r
-        }\r
-\r
-        repaint();\r
-    }\r
-\r
-    // private void fireSequenceSelectionEvent(Selection sel) {\r
-    //   controller.handleSequenceSelectionEvent(new SequenceSelectionEvent(this,sel));\r
-    //}\r
-    public void mouseMoved(MouseEvent evt)\r
-    {\r
-        SequenceI found = findPoint(evt.getX(), evt.getY());\r
-\r
-        if (found != null)\r
-        {\r
-            this.setToolTipText(found.getName());\r
-        }\r
-        else\r
-        {\r
-            this.setToolTipText(null);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-        mx = evt.getX();\r
-        my = evt.getY();\r
-\r
-        //Check if this is a rectangle drawing drag\r
-        if ((evt.getModifiers() & InputEvent.BUTTON2_MASK) != 0)\r
-        {\r
-            //      rectx2 = evt.getX();\r
-            //      recty2 = evt.getY();\r
-        }\r
-        else\r
-        {\r
-            rotmat.setIdentity();\r
-\r
-            rotmat.rotate((float) (my - omy), 'x');\r
-            rotmat.rotate((float) (mx - omx), 'y');\r
-\r
-            for (int i = 0; i < npoint; i++)\r
-            {\r
-                SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-                sp.coord[0] -= centre[0];\r
-                sp.coord[1] -= centre[1];\r
-                sp.coord[2] -= centre[2];\r
-\r
-                //Now apply the rotation matrix\r
-                sp.coord = rotmat.vectorMultiply(sp.coord);\r
-\r
-                //Now translate back again\r
-                sp.coord[0] += centre[0];\r
-                sp.coord[1] += centre[1];\r
-                sp.coord[2] += centre[2];\r
-            }\r
-\r
-            for (int i = 0; i < 3; i++)\r
-            {\r
-                axes[i] = rotmat.vectorMultiply(axes[i]);\r
-            }\r
-\r
-            omx = mx;\r
-            omy = my;\r
-\r
-            paint(this.getGraphics());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param x2 DOCUMENT ME!\r
-     * @param y2 DOCUMENT ME!\r
-     */\r
-    public void rectSelect(int x1, int y1, int x2, int y2)\r
-    {\r
-        boolean changedSel = false;\r
-\r
-        for (int i = 0; i < npoint; i++)\r
-        {\r
-            SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-            int tmp1 = (int) (((sp.coord[0] - centre[0]) * scale) +\r
-                ((float) getWidth() / 2.0));\r
-            int tmp2 = (int) (((sp.coord[1] - centre[1]) * scale) +\r
-                ((float) getHeight() / 2.0));\r
-\r
-            if ((tmp1 > x1) && (tmp1 < x2) && (tmp2 > y1) && (tmp2 < y2))\r
-            {\r
-                if (av != null)\r
-                {\r
-                    if (!av.getSelectionGroup().sequences.contains(sp.sequence))\r
-                    {\r
-                        changedSel = true;\r
-                        av.getSelectionGroup().addSequence(sp.sequence, true);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        // if (changedSel) {\r
-        //    fireSequenceSelectionEvent(av.getSelection());\r
-        // }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param x DOCUMENT ME!\r
-     * @param y DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceI findPoint(int x, int y)\r
-    {\r
-        int halfwidth = getWidth() / 2;\r
-        int halfheight = getHeight() / 2;\r
-\r
-        int found = -1;\r
-\r
-        for (int i = 0; i < npoint; i++)\r
-        {\r
-            SequencePoint sp = (SequencePoint) points.elementAt(i);\r
-            int px = (int) ((float) (sp.coord[0] - centre[0]) * scale) +\r
-                halfwidth;\r
-            int py = (int) ((float) (sp.coord[1] - centre[1]) * scale) +\r
-                halfheight;\r
-\r
-            if ((Math.abs(px - x) < 3) && (Math.abs(py - y) < 3))\r
-            {\r
-                found = i;\r
-            }\r
-        }\r
-\r
-        if (found != -1)\r
-        {\r
-            return ((SequencePoint) points.elementAt(found)).sequence;\r
-        }\r
-        else\r
-        {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    /*  public boolean handleRubberbandEvent(RubberbandEvent evt) {\r
-        System.out.println("Rubberband handler called in RotatableCanvas with " +\r
-                           evt.getBounds());\r
-\r
-        Rubberband rb = (Rubberband)evt.getSource();\r
-\r
-        // Clear the current selection (instance variable)\r
-        //if ((rb.getModifiers() & Event.SHIFT_MASK) == 0) {\r
-        //   clearSelection();\r
-        //}\r
-\r
-        if (rb.getComponent() == this) {\r
-          Rectangle bounds = evt.getBounds();\r
-     rectSelect(bounds.x,bounds.y,bounds.x+bounds.width,bounds.y+bounds.height);\r
-        }\r
-\r
-        redrawneeded = true;\r
-        paint(this.getGraphics());\r
-\r
-        return true;\r
-      }*/\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.math.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import java.util.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class RotatableCanvas extends JPanel implements MouseListener,
+    MouseMotionListener, KeyListener
+{
+    RotatableMatrix idmat = new RotatableMatrix(3, 3);
+    RotatableMatrix objmat = new RotatableMatrix(3, 3);
+    RotatableMatrix rotmat = new RotatableMatrix(3, 3);
+
+    //RubberbandRectangle rubberband;
+    boolean drawAxes = true;
+    int omx = 0;
+    int mx = 0;
+    int omy = 0;
+    int my = 0;
+    Image img;
+    Graphics ig;
+    Dimension prefsize;
+    float[] centre = new float[3];
+    float[] width = new float[3];
+    float[] max = new float[3];
+    float[] min = new float[3];
+    float maxwidth;
+    float scale;
+    int npoint;
+    Vector points;
+    float[][] orig;
+    float[][] axes;
+    int startx;
+    int starty;
+    int lastx;
+    int lasty;
+    int rectx1;
+    int recty1;
+    int rectx2;
+    int recty2;
+    float scalefactor = 1;
+    AlignViewport av;
+    boolean showLabels = false;
+    Color bgColour = Color.black;
+
+    //  Controller    controller;
+    public RotatableCanvas(AlignViewport av)
+    {
+      this.av = av;
+    }
+
+    public void showLabels(boolean b)
+    {
+      showLabels = b;
+      repaint();
+    }
+
+    public void setPoints(Vector points, int npoint)
+    {
+        this.points = points;
+        this.npoint = npoint;
+        ToolTipManager.sharedInstance().registerComponent(this);
+        ToolTipManager.sharedInstance().setInitialDelay(0);
+        ToolTipManager.sharedInstance().setDismissDelay(10000);
+        PaintRefresher.Register(this, av.alignment);
+
+        prefsize = getPreferredSize();
+        orig = new float[npoint][3];
+
+        for (int i = 0; i < npoint; i++)
+        {
+            SequencePoint sp = (SequencePoint) points.elementAt(i);
+
+            for (int j = 0; j < 3; j++)
+            {
+                orig[i][j] = sp.coord[j];
+            }
+        }
+
+        //Initialize the matrices to identity
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {
+                if (i != j)
+                {
+                    idmat.addElement(i, j, 0);
+                    objmat.addElement(i, j, 0);
+                    rotmat.addElement(i, j, 0);
+                }
+                else
+                {
+                    idmat.addElement(i, j, 0);
+                    objmat.addElement(i, j, 0);
+                    rotmat.addElement(i, j, 0);
+                }
+            }
+        }
+
+        axes = new float[3][3];
+        initAxes();
+
+        findCentre();
+        findWidth();
+
+        scale = findScale();
+
+        addMouseListener(this);
+        addKeyListener(this);
+
+        addMouseMotionListener(this);
+
+    }
+
+    public void initAxes()
+    {
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {
+                if (i != j)
+                {
+                    axes[i][j] = 0;
+                }
+                else
+                {
+                    axes[i][j] = 1;
+                }
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void findWidth()
+    {
+        max = new float[3];
+        min = new float[3];
+
+        max[0] = (float) -1e30;
+        max[1] = (float) -1e30;
+        max[2] = (float) -1e30;
+
+        min[0] = (float) 1e30;
+        min[1] = (float) 1e30;
+        min[2] = (float) 1e30;
+
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < npoint; j++)
+            {
+                SequencePoint sp = (SequencePoint) points.elementAt(j);
+
+                if (sp.coord[i] >= max[i])
+                {
+                    max[i] = sp.coord[i];
+                }
+
+                if (sp.coord[i] <= min[i])
+                {
+                    min[i] = sp.coord[i];
+                }
+            }
+        }
+
+        //    System.out.println("xmax " + max[0] + " min " + min[0]);
+        //System.out.println("ymax " + max[1] + " min " + min[1]);
+        //System.out.println("zmax " + max[2] + " min " + 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];
+
+        if (width[1] > width[0])
+        {
+            maxwidth = width[1];
+        }
+
+        if (width[2] > width[1])
+        {
+            maxwidth = width[2];
+        }
+
+        //System.out.println("Maxwidth = " + maxwidth);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float findScale()
+    {
+        int dim;
+        int width;
+        int height;
+
+        if (getWidth() != 0)
+        {
+            width = getWidth();
+            height = getHeight();
+        }
+        else
+        {
+            width = prefsize.width;
+            height = prefsize.height;
+        }
+
+        if (width < height)
+        {
+            dim = width;
+        }
+        else
+        {
+            dim = height;
+        }
+
+        return (float) ((dim * scalefactor) / (2 * maxwidth));
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void findCentre()
+    {
+        //Find centre coordinate
+        findWidth();
+
+        centre[0] = (max[0] + min[0]) / 2;
+        centre[1] = (max[1] + min[1]) / 2;
+        centre[2] = (max[2] + min[2]) / 2;
+
+        //    System.out.println("Centre x " + centre[0]);
+        //System.out.println("Centre y " + centre[1]);
+        //System.out.println("Centre z " + centre[2]);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension getPreferredSize()
+    {
+        if (prefsize != null)
+        {
+            return prefsize;
+        }
+        else
+        {
+            return new Dimension(400, 400);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension getMinimumSize()
+    {
+        return getPreferredSize();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g1)
+    {
+
+      Graphics2D g = (Graphics2D) g1;
+
+      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                         RenderingHints.VALUE_ANTIALIAS_ON);
+      if(points==null)
+      {
+        g.setFont(new Font("Verdana", Font.PLAIN, 18));
+        g.drawString("Calculating PCA....", 20, getHeight()/2);
+      }
+      else
+      {
+        //Only create the image at the beginning -
+        if ( (img == null) || (prefsize.width != getWidth()) ||
+            (prefsize.height != getHeight()))
+        {
+          prefsize.width = getWidth();
+          prefsize.height = getHeight();
+
+          scale = findScale();
+
+          //      System.out.println("New scale = " + scale);
+          img = createImage(getWidth(), getHeight());
+          ig = img.getGraphics();
+        }
+
+
+        drawBackground(ig, bgColour);
+        drawScene(ig);
+
+        if (drawAxes == true)
+        {
+          drawAxes(ig);
+        }
+
+        g.drawImage(img, 0, 0, this);
+      }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void drawAxes(Graphics g)
+    {
+
+        g.setColor(Color.yellow);
+
+        for (int i = 0; i < 3; i++)
+        {
+            g.drawLine(getWidth() / 2, getHeight() / 2,
+                (int) ((axes[i][0] * scale * max[0]) + (getWidth() / 2)),
+                (int) ((axes[i][1] * scale * max[1]) + (getHeight() / 2)));
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param col DOCUMENT ME!
+     */
+    public void drawBackground(Graphics g, Color col)
+    {
+        g.setColor(col);
+        g.fillRect(0, 0, prefsize.width, prefsize.height);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void drawScene(Graphics g1)
+    {
+
+      Graphics2D g = (Graphics2D) g1;
+
+      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                         RenderingHints.VALUE_ANTIALIAS_ON);
+
+
+        int halfwidth = getWidth() / 2;
+        int halfheight = getHeight() / 2;
+
+        for (int i = 0; i < npoint; i++)
+        {
+            SequencePoint sp = (SequencePoint) points.elementAt(i);
+            int x = (int) ((float) (sp.coord[0] - centre[0]) * scale) +
+                halfwidth;
+            int y = (int) ((float) (sp.coord[1] - centre[1]) * scale) +
+                halfheight;
+            float z = sp.coord[1] - centre[2];
+
+            if (sp.sequence.getColor() == Color.black)
+            {
+                g.setColor(Color.white);
+            }
+            else
+            {
+                g.setColor(sp.sequence.getColor());
+            }
+
+            if (av.getSelectionGroup() != null)
+            {
+                if (av.getSelectionGroup().getSequences(false).contains(
+                            ((SequencePoint) points.elementAt(i)).sequence))
+                {
+                    g.setColor(Color.gray);
+                }
+            }
+
+            if (z < 0)
+            {
+                g.setColor(g.getColor().darker());
+            }
+
+            g.fillRect(x - 3, y - 3, 6, 6);
+            if(showLabels)
+            {
+              g.setColor(Color.red);
+              g.drawString( ( (SequencePoint) points.elementAt(i)).sequence.
+                           getName(),
+                           x - 3, y - 4);
+            }
+        }
+
+        //    //Now the rectangle
+        //    if (rectx2 != -1 && recty2 != -1) {
+        //      g.setColor(Color.white);
+        //
+        //      g.drawRect(rectx1,recty1,rectx2-rectx1,recty2-recty1);
+        //    }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension minimumsize()
+    {
+        return prefsize;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension preferredsize()
+    {
+        return prefsize;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void keyTyped(KeyEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void keyReleased(KeyEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void keyPressed(KeyEvent evt)
+    {
+        if (evt.getKeyCode() == KeyEvent.VK_UP)
+        {
+            scalefactor = (float) (scalefactor * 1.1);
+            scale = findScale();
+        }
+        else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
+        {
+            scalefactor = (float) (scalefactor * 0.9);
+            scale = findScale();
+        }
+        else if (evt.getKeyChar() == 's')
+        {
+            System.err.println("DEBUG: Rectangle selection"); // log.debug
+
+            if ((rectx2 != -1) && (recty2 != -1))
+            {
+                rectSelect(rectx1, recty1, rectx2, recty2);
+            }
+        }
+
+        repaint();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseClicked(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent evt)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent evt)
+    {
+        int x = evt.getX();
+        int y = evt.getY();
+
+        mx = x;
+        my = y;
+
+        omx = mx;
+        omy = my;
+
+        startx = x;
+        starty = y;
+
+        rectx1 = x;
+        recty1 = y;
+
+        rectx2 = -1;
+        recty2 = -1;
+
+        SequenceI found = findPoint(x, y);
+
+        if (found != null)
+        {
+            if (av.getSelectionGroup() != null)
+            {
+                av.getSelectionGroup().addOrRemove(found, true);
+                PaintRefresher.Refresh(this, av.alignment);
+            }
+            else
+            {
+                av.setSelectionGroup(new SequenceGroup());
+                av.getSelectionGroup().addOrRemove(found, true);
+                av.getSelectionGroup().setEndRes(av.alignment.getWidth()-1);
+            }
+        }
+
+        repaint();
+    }
+
+    // private void fireSequenceSelectionEvent(Selection sel) {
+    //   controller.handleSequenceSelectionEvent(new SequenceSelectionEvent(this,sel));
+    //}
+    public void mouseMoved(MouseEvent evt)
+    {
+        SequenceI found = findPoint(evt.getX(), evt.getY());
+
+        if (found != null)
+        {
+            this.setToolTipText(found.getName());
+        }
+        else
+        {
+            this.setToolTipText(null);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent evt)
+    {
+        mx = evt.getX();
+        my = evt.getY();
+
+        //Check if this is a rectangle drawing drag
+        if ((evt.getModifiers() & InputEvent.BUTTON2_MASK) != 0)
+        {
+            //      rectx2 = evt.getX();
+            //      recty2 = evt.getY();
+        }
+        else
+        {
+            rotmat.setIdentity();
+
+            rotmat.rotate((float) (my - omy), 'x');
+            rotmat.rotate((float) (mx - omx), 'y');
+
+            for (int i = 0; i < npoint; i++)
+            {
+                SequencePoint sp = (SequencePoint) points.elementAt(i);
+                sp.coord[0] -= centre[0];
+                sp.coord[1] -= centre[1];
+                sp.coord[2] -= centre[2];
+
+                //Now apply the rotation matrix
+                sp.coord = rotmat.vectorMultiply(sp.coord);
+
+                //Now translate back again
+                sp.coord[0] += centre[0];
+                sp.coord[1] += centre[1];
+                sp.coord[2] += centre[2];
+            }
+
+            for (int i = 0; i < 3; i++)
+            {
+                axes[i] = rotmat.vectorMultiply(axes[i]);
+            }
+
+            omx = mx;
+            omy = my;
+
+            paint(this.getGraphics());
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param x2 DOCUMENT ME!
+     * @param y2 DOCUMENT ME!
+     */
+    public void rectSelect(int x1, int y1, int x2, int y2)
+    {
+        for (int i = 0; i < npoint; i++)
+        {
+            SequencePoint sp = (SequencePoint) points.elementAt(i);
+            int tmp1 = (int) (((sp.coord[0] - centre[0]) * scale) +
+                ((float) getWidth() / 2.0));
+            int tmp2 = (int) (((sp.coord[1] - centre[1]) * scale) +
+                ((float) getHeight() / 2.0));
+
+            if ((tmp1 > x1) && (tmp1 < x2) && (tmp2 > y1) && (tmp2 < y2))
+            {
+                if (av != null)
+                {
+                    if (!av.getSelectionGroup().getSequences(false).contains(sp.sequence))
+                    {
+                        av.getSelectionGroup().addSequence(sp.sequence, true);
+                    }
+                }
+            }
+        }
+
+        // if (changedSel) {
+        //    fireSequenceSelectionEvent(av.getSelection());
+        // }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param x DOCUMENT ME!
+     * @param y DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceI findPoint(int x, int y)
+    {
+        int halfwidth = getWidth() / 2;
+        int halfheight = getHeight() / 2;
+
+        int found = -1;
+
+        for (int i = 0; i < npoint; i++)
+        {
+            SequencePoint sp = (SequencePoint) points.elementAt(i);
+            int px = (int) ((float) (sp.coord[0] - centre[0]) * scale) +
+                halfwidth;
+            int py = (int) ((float) (sp.coord[1] - centre[1]) * scale) +
+                halfheight;
+
+            if ((Math.abs(px - x) < 3) && (Math.abs(py - y) < 3))
+            {
+                found = i;
+            }
+        }
+
+        if (found != -1)
+        {
+            return ((SequencePoint) points.elementAt(found)).sequence;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /*  public boolean handleRubberbandEvent(RubberbandEvent evt) {
+        System.out.println("Rubberband handler called in RotatableCanvas with " +
+                           evt.getBounds());
+
+        Rubberband rb = (Rubberband)evt.getSource();
+
+        // Clear the current selection (instance variable)
+        //if ((rb.getModifiers() & Event.SHIFT_MASK) == 0) {
+        //   clearSelection();
+        //}
+
+        if (rb.getComponent() == this) {
+          Rectangle bounds = evt.getBounds();
+     rectSelect(bounds.x,bounds.y,bounds.x+bounds.width,bounds.y+bounds.height);
+        }
+
+        redrawneeded = true;
+        paint(this.getGraphics());
+
+        return true;
+      }*/
+}
index 07be3d0..91a2da1 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class ScalePanel extends JPanel implements MouseMotionListener, MouseListener\r
-{\r
-    protected int offy = 4;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int width;\r
-    protected AlignViewport av;\r
-    AlignmentPanel ap;\r
-    boolean stretchingGroup = false;\r
-    int min; //used by mouseDragged to see if user\r
-    int max; //used by mouseDragged to see if user\r
-\r
-    // wants to delete columns\r
-    public ScalePanel(AlignViewport av, AlignmentPanel ap)\r
-    {\r
-        this.av = av;\r
-        this.ap = ap;\r
-\r
-        addMouseListener(this);\r
-        addMouseMotionListener(this);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent evt)\r
-    {\r
-        int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
-        final int res;\r
-\r
-        if(av.hasHiddenColumns)\r
-          res = av.getColumnSelection().adjustForHiddenColumns(x);\r
-        else\r
-          res = x;\r
-\r
-        min = res;\r
-        max = res;\r
-\r
-        if(reveal != null && SwingUtilities.isRightMouseButton(evt))\r
-          {\r
-            JPopupMenu pop = new JPopupMenu();\r
-            JMenuItem item = new JMenuItem("Reveal");\r
-            item.addActionListener(new ActionListener()\r
-            {\r
-              public void actionPerformed(ActionEvent e)\r
-              {\r
-                av.getColumnSelection().revealHiddenColumns(reveal[0], av);\r
-                reveal = null;\r
-                ap.repaint();\r
-                if(ap.overviewPanel != null)\r
-                    ap.overviewPanel.updateOverviewImage();\r
-              }\r
-            });\r
-            pop.add(item);\r
-\r
-            if(av.getColumnSelection().hiddenColumns.size()>1)\r
-            {\r
-              item = new JMenuItem("Reveal All");\r
-              item.addActionListener(new ActionListener()\r
-              {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                  av.getColumnSelection().revealAllHiddenColumns(av);\r
-                  reveal = null;\r
-                  ap.repaint();\r
-                  if(ap.overviewPanel != null)\r
-                    ap.overviewPanel.updateOverviewImage();\r
-                }\r
-              });\r
-              pop.add(item);\r
-            }\r
-\r
-            pop.show(this, evt.getX(), evt.getY());\r
-\r
-          }\r
-        else if (av.getColumnSelection().contains(res))\r
-        {\r
-          if( SwingUtilities.isRightMouseButton(evt))\r
-          {\r
-            JPopupMenu pop = new JPopupMenu();\r
-            JMenuItem item = new JMenuItem("Hide Columns");\r
-            item.addActionListener(new ActionListener()\r
-            {\r
-              public void actionPerformed(ActionEvent e)\r
-              {\r
-                av.getColumnSelection().hideColumns(res, av);\r
-                ap.repaint();\r
-                if(ap.overviewPanel != null)\r
-                  ap.overviewPanel.updateOverviewImage();\r
-              }\r
-            });\r
-            pop.add(item);\r
-            pop.show(this, evt.getX(), evt.getY());\r
-\r
-          }\r
-          else\r
-          {\r
-            av.getColumnSelection().removeElement(res);\r
-            av.setSelectionGroup(null);\r
-          }\r
-        }\r
-        else\r
-        {\r
-            av.getColumnSelection().addElement(res);\r
-            SequenceGroup sg = new SequenceGroup();\r
-\r
-            for (int i = 0; i < av.alignment.getSequences().size(); i++)\r
-            {\r
-                sg.addSequence(av.alignment.getSequenceAt(i), false);\r
-            }\r
-\r
-            sg.setStartRes(res);\r
-            sg.setEndRes(res);\r
-            av.setSelectionGroup(sg);\r
-        }\r
-\r
-\r
-        ap.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
-\r
-        if(av.hasHiddenColumns)\r
-          res = av.getColumnSelection().adjustForHiddenColumns(res);\r
-\r
-        if (!stretchingGroup)\r
-        {\r
-            ap.repaint();\r
-\r
-            return;\r
-        }\r
-\r
-        SequenceGroup sg = av.getSelectionGroup();\r
-\r
-        if (res > sg.getStartRes())\r
-        {\r
-            sg.setEndRes(res);\r
-        }\r
-        else if (res < sg.getStartRes())\r
-        {\r
-            sg.setStartRes(res);\r
-        }\r
-\r
-        stretchingGroup = false;\r
-        ap.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
-\r
-        if(av.hasHiddenColumns)\r
-          res = av.getColumnSelection().adjustForHiddenColumns(res);\r
-\r
-        if (res < min)\r
-        {\r
-            min = res;\r
-        }\r
-\r
-        if (res > max)\r
-        {\r
-            max = res;\r
-        }\r
-\r
-        SequenceGroup sg = av.getSelectionGroup();\r
-\r
-        if (sg != null)\r
-        {\r
-            stretchingGroup = true;\r
-\r
-            if (!av.getColumnSelection().contains(res))\r
-            {\r
-                av.getColumnSelection().addElement(res);\r
-            }\r
-\r
-            if (res > sg.getStartRes())\r
-            {\r
-                sg.setEndRes(res);\r
-            }\r
-            else if (res < sg.getStartRes())\r
-            {\r
-                sg.setStartRes(res);\r
-            }\r
-\r
-            for (int i = min; i <= max; i++)\r
-            {\r
-                if ((i < sg.getStartRes()) || (i > sg.getEndRes()))\r
-                {\r
-                    av.getColumnSelection().removeElement(i);\r
-                }\r
-                else\r
-                {\r
-                    av.getColumnSelection().addElement(i);\r
-                }\r
-            }\r
-\r
-            ap.repaint();\r
-        }\r
-    }\r
-\r
-    public void mouseEntered(MouseEvent evt){}\r
-    public void mouseExited(MouseEvent evt){}\r
-    public void mouseClicked(MouseEvent evt){}\r
-\r
-    public void mouseMoved(MouseEvent evt)\r
-    {\r
-      if(!av.hasHiddenColumns)\r
-        return;\r
-\r
-      int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
-\r
-      res = av.getColumnSelection().adjustForHiddenColumns(res);\r
-\r
-      reveal = null;\r
-      for(int i=0; i<av.getColumnSelection().getHiddenColumns().size(); i++)\r
-      {\r
-        int [] region = (int[])av.getColumnSelection().getHiddenColumns().elementAt(i);\r
-        if(res+1==region[0] || res-1==region[1])\r
-        {\r
-          reveal = region;\r
-          ToolTipManager.sharedInstance().registerComponent(this);\r
-          this.setToolTipText("Reveal Hidden Columns with Right Mouse Button");\r
-          break;\r
-        }\r
-        else\r
-          this.setToolTipText(null);\r
-\r
-      }\r
-\r
-      repaint();\r
-    }\r
-\r
-    int [] reveal;\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        drawScale(g, av.getStartRes(), av.getEndRes(), getWidth(), getHeight());\r
-    }\r
-\r
-    // scalewidth will normally be screenwidth,\r
-    public void drawScale(Graphics g, int startx, int endx, int width,\r
-        int height)\r
-    {\r
-        Graphics2D gg = (Graphics2D) g;\r
-        gg.setFont(av.getFont());\r
-\r
-        if(av.antiAlias)\r
-          gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                              RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-        //Fill in the background\r
-        gg.setColor(Color.white);\r
-        gg.fillRect(0, 0, width, height);\r
-        gg.setColor(Color.black);\r
-\r
-        //Fill the selected columns\r
-        ColumnSelection cs = av.getColumnSelection();\r
-        gg.setColor(new Color(220, 0, 0));\r
-\r
-        for (int i = 0; i < cs.size(); i++)\r
-        {\r
-            int sel = cs.columnAt(i);\r
-            if(av.hasHiddenColumns)\r
-                sel = av.getColumnSelection().findColumnPosition(sel);\r
-\r
-            if ((sel >= startx) && (sel <= endx))\r
-            {\r
-                gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth,\r
-                    getHeight());\r
-            }\r
-        }\r
-\r
-        // Draw the scale numbers\r
-        gg.setColor(Color.black);\r
-\r
-        int scalestartx = (startx / 10) * 10;\r
-\r
-        FontMetrics fm = gg.getFontMetrics(av.getFont());\r
-        int y = av.charHeight - fm.getDescent();\r
-\r
-        if ((scalestartx % 10) == 0)\r
-        {\r
-            scalestartx += 5;\r
-        }\r
-\r
-        for (int i = scalestartx; i < endx; i += 5)\r
-        {\r
-            if ((i % 10) == 0)\r
-            {\r
-                gg.drawString(String.valueOf(av.getColumnSelection().adjustForHiddenColumns(i)),\r
-                    (i - startx - 1) * av.charWidth, y);\r
-                gg.drawLine((int) (((i - startx - 1) * av.charWidth) +\r
-                    (av.charWidth / 2)), y + 2,\r
-                    (int) (((i - startx - 1) * av.charWidth) +\r
-                    (av.charWidth / 2)), y + (fm.getDescent() * 2));\r
-            }\r
-            else\r
-            {\r
-                gg.drawLine((int) (((i - startx - 1) * av.charWidth) +\r
-                    (av.charWidth / 2)), y + fm.getDescent(),\r
-                    (int) (((i - startx - 1) * av.charWidth) +\r
-                    (av.charWidth / 2)), y + (fm.getDescent() * 2));\r
-            }\r
-        }\r
-\r
-        if (av.hasHiddenColumns)\r
-        {\r
-          gg.setColor(Color.blue);\r
-          int res;\r
-          for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)\r
-          {\r
-            res = av.getColumnSelection().findHiddenRegionPosition( i )-startx;\r
-\r
-            gg.fillPolygon(new int[] { res*av.charWidth - av.charHeight/4,\r
-                                         res*av.charWidth + av.charHeight/4,\r
-                                         res*av.charWidth },\r
-                                new int[]\r
-                                {\r
-                                    y-av.charHeight/2 , y-av.charHeight/2 ,\r
-                                    y + 8\r
-                                }, 3);\r
-\r
-\r
-          }\r
-\r
-          if (reveal != null && reveal[0] > startx && reveal[0] < endx)\r
-          {\r
-            gg.drawString("Reveal Columns", reveal[0] * av.charWidth, 0);\r
-          }\r
-        }\r
-\r
-\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ScalePanel extends JPanel implements MouseMotionListener, MouseListener
+{
+    protected int offy = 4;
+
+    /** DOCUMENT ME!! */
+    public int width;
+    protected AlignViewport av;
+    AlignmentPanel ap;
+    boolean stretchingGroup = false;
+    int min; //used by mouseDragged to see if user
+    int max; //used by mouseDragged to see if user
+    boolean mouseDragging = false;
+
+    // wants to delete columns
+    public ScalePanel(AlignViewport av, AlignmentPanel ap)
+    {
+        this.av = av;
+        this.ap = ap;
+
+        addMouseListener(this);
+        addMouseMotionListener(this);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent evt)
+    {
+        int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+        final int res;
+
+        if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(x);
+        else
+          res = x;
+
+        min = res;
+        max = res;
+
+        if (SwingUtilities.isRightMouseButton(evt))
+        {
+          JPopupMenu pop = new JPopupMenu();
+          if (reveal != null)
+          {
+            JMenuItem item = new JMenuItem("Reveal");
+            item.addActionListener(new ActionListener()
+            {
+              public void actionPerformed(ActionEvent e)
+              {
+                av.showColumn(reveal[0]);
+                reveal = null;
+                ap.repaint();
+                if (ap.overviewPanel != null)
+                  ap.overviewPanel.updateOverviewImage();
+              }
+            });
+            pop.add(item);
+
+            if (av.getColumnSelection().getHiddenColumns().size() > 1)
+            {
+              item = new JMenuItem("Reveal All");
+              item.addActionListener(new ActionListener()
+              {
+                public void actionPerformed(ActionEvent e)
+                {
+                  av.showAllHiddenColumns();
+                  reveal = null;
+                  ap.repaint();
+                  if (ap.overviewPanel != null)
+                    ap.overviewPanel.updateOverviewImage();
+                }
+              });
+              pop.add(item);
+            }
+            pop.show(this, evt.getX(), evt.getY());
+          }
+          else if (av.getColumnSelection().contains(res))
+          {
+            JMenuItem item = new JMenuItem("Hide Columns");
+            item.addActionListener(new ActionListener()
+            {
+              public void actionPerformed(ActionEvent e)
+              {
+                av.hideColumns(res, res);
+                if(av.getSelectionGroup()!=null
+                   && av.getSelectionGroup().getSize(false)==av.alignment.getHeight())
+                  av.setSelectionGroup(null);
+
+                ap.repaint();
+                if (ap.overviewPanel != null)
+                  ap.overviewPanel.updateOverviewImage();
+              }
+            });
+            pop.add(item);
+            pop.show(this, evt.getX(), evt.getY());
+          }
+        }
+        else // LEFT MOUSE TO SELECT
+        {
+          if (!evt.isControlDown() && !evt.isShiftDown())
+          {
+            av.getColumnSelection().clear();
+          }
+
+          av.getColumnSelection().addElement(res);
+          SequenceGroup sg = new SequenceGroup();
+          for (int i = 0; i < av.alignment.getSequences().size(); i++)
+          {
+            sg.addSequence(av.alignment.getSequenceAt(i), false);
+          }
+
+          sg.setStartRes(res);
+          sg.setEndRes(res);
+          av.setSelectionGroup(sg);
+
+          if(evt.isShiftDown())
+          {
+            int min = Math.min(av.getColumnSelection().getMin(), res);
+            int max = Math.max(av.getColumnSelection().getMax(), res);
+            for (int i = min; i<max; i++)
+            {
+                av.getColumnSelection().addElement(i);
+            }
+            sg.setStartRes(min);
+            sg.setEndRes(max);
+          }
+
+
+        }
+
+
+        ap.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent evt)
+    {
+        mouseDragging = false;
+
+        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+        if(res> av.alignment.getWidth())
+        {
+          res = av.alignment.getWidth()-1;
+        }
+
+        if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+        if (!stretchingGroup)
+        {
+            ap.repaint();
+
+            return;
+        }
+
+        SequenceGroup sg = av.getSelectionGroup();
+
+        if (res > sg.getStartRes())
+        {
+            sg.setEndRes(res);
+        }
+        else if (res < sg.getStartRes())
+        {
+            sg.setStartRes(res);
+        }
+
+        stretchingGroup = false;
+        ap.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent evt)
+    {
+        mouseDragging = true;
+
+        int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+        if(res<0)
+          res = 0;
+
+        if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+
+        if(res> av.alignment.getWidth())
+        {
+          res = av.alignment.getWidth()-1;
+        }
+
+        if (res < min)
+        {
+            min = res;
+        }
+
+        if (res > max)
+        {
+            max = res;
+        }
+
+
+
+        SequenceGroup sg = av.getSelectionGroup();
+
+        if (sg != null)
+        {
+            stretchingGroup = true;
+
+            if (!av.getColumnSelection().contains(res))
+            {
+                av.getColumnSelection().addElement(res);
+            }
+
+            if (res > sg.getStartRes())
+            {
+                sg.setEndRes(res);
+            }
+            if (res < sg.getStartRes())
+            {
+                sg.setStartRes(res);
+            }
+
+            for (int i = min; i <= max; i++)
+            {
+                if ((i < sg.getStartRes()) || (i > sg.getEndRes()))
+                {
+                    av.getColumnSelection().removeElement(i);
+                }
+                else
+                {
+                    av.getColumnSelection().addElement(i);
+                }
+            }
+
+            ap.repaint();
+        }
+    }
+
+    public void mouseEntered(MouseEvent evt)
+    {
+      if(mouseDragging)
+        ap.seqPanel.scrollCanvas(null);
+    }
+
+    public void mouseExited(MouseEvent evt)
+    {
+      if(mouseDragging)
+        ap.seqPanel.scrollCanvas(evt);
+    }
+
+    public void mouseClicked(MouseEvent evt){}
+
+    public void mouseMoved(MouseEvent evt)
+    {
+      if(!av.hasHiddenColumns)
+        return;
+
+      int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+
+      res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+      reveal = null;
+      for(int i=0; i<av.getColumnSelection().getHiddenColumns().size(); i++)
+      {
+        int [] region = (int[])av.getColumnSelection().getHiddenColumns().elementAt(i);
+        if(res+1==region[0] || res-1==region[1])
+        {
+          reveal = region;
+          ToolTipManager.sharedInstance().registerComponent(this);
+          this.setToolTipText("Reveal Hidden Columns with Right Mouse Button");
+          break;
+        }
+        else
+          this.setToolTipText(null);
+
+      }
+
+      repaint();
+    }
+
+    int [] reveal;
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+        drawScale(g, av.getStartRes(), av.getEndRes(), getWidth(), getHeight());
+    }
+
+    // scalewidth will normally be screenwidth,
+    public void drawScale(Graphics g, int startx, int endx, int width,
+        int height)
+    {
+        Graphics2D gg = (Graphics2D) g;
+        gg.setFont(av.getFont());
+
+        if(av.antiAlias)
+          gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                              RenderingHints.VALUE_ANTIALIAS_ON);
+
+        //Fill in the background
+        gg.setColor(Color.white);
+        gg.fillRect(0, 0, width, height);
+        gg.setColor(Color.black);
+
+        //Fill the selected columns
+        ColumnSelection cs = av.getColumnSelection();
+        gg.setColor(new Color(220, 0, 0));
+
+        for (int i = 0; i < cs.size(); i++)
+        {
+            int sel = cs.columnAt(i);
+            if(av.hasHiddenColumns)
+                sel = av.getColumnSelection().findColumnPosition(sel);
+
+            if ((sel >= startx) && (sel <= endx))
+            {
+                gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth,
+                    getHeight());
+            }
+        }
+
+        // Draw the scale numbers
+        gg.setColor(Color.black);
+
+        int scalestartx = (startx / 10) * 10;
+
+        FontMetrics fm = gg.getFontMetrics(av.getFont());
+        int y = av.charHeight - fm.getDescent();
+
+        if ((scalestartx % 10) == 0)
+        {
+            scalestartx += 5;
+        }
+
+        String string;
+        int maxX=0;
+
+        for (int i = scalestartx; i < endx; i += 5)
+        {
+            if ((i % 10) == 0)
+            {
+                string = String.valueOf(av.getColumnSelection().adjustForHiddenColumns(i));
+                if ( (i - startx - 1) * av.charWidth > maxX)
+                {
+                  gg.drawString(string,
+                                (i - startx - 1) * av.charWidth, y);
+                  maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string);
+                }
+
+                gg.drawLine( (int) ( ( (i - startx - 1) * av.charWidth) +
+                                    (av.charWidth / 2)), y + 2,
+                            (int) ( ( (i - startx - 1) * av.charWidth) +
+                                   (av.charWidth / 2)),
+                            y + (fm.getDescent() * 2));
+
+            }
+            else
+            {
+                gg.drawLine((int) (((i - startx - 1) * av.charWidth) +
+                    (av.charWidth / 2)), y + fm.getDescent(),
+                    (int) (((i - startx - 1) * av.charWidth) +
+                    (av.charWidth / 2)), y + (fm.getDescent() * 2));
+            }
+        }
+
+        if (av.hasHiddenColumns)
+        {
+          gg.setColor(Color.blue);
+          int res;
+          if(av.getShowHiddenMarkers())
+          {
+            for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size();
+                 i++)
+            {
+
+              res = av.getColumnSelection().findHiddenRegionPosition(i) -
+                  startx;
+
+              if(res < 0 || res > endx-scalestartx)
+                continue;
+
+              gg.fillPolygon(new int[]
+                             {res * av.charWidth - av.charHeight / 4,
+                             res * av.charWidth + av.charHeight / 4,
+                             res * av.charWidth},
+                             new int[]
+                             {
+                             y - av.charHeight / 2, y - av.charHeight / 2,
+                             y + 8
+              }, 3);
+
+            }
+          }
+
+          if (reveal != null && reveal[0] > startx && reveal[0] < endx)
+          {
+            gg.drawString("Reveal Columns", reveal[0] * av.charWidth, 0);
+          }
+        }
+
+
+    }
+}
index 99447a4..74f59a3 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.awt.*;\r
-import java.awt.image.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SeqCanvas extends JComponent\r
-{\r
-    final FeatureRenderer fr;\r
-    final SequenceRenderer sr;\r
-    BufferedImage img;\r
-    Graphics2D gg;\r
-    int imgWidth;\r
-    int imgHeight;\r
-    AlignViewport av;\r
-    SearchResults searchResults = null;\r
-    boolean fastPaint = false;\r
-    int LABEL_WEST;\r
-    int LABEL_EAST;\r
-\r
-\r
-    int cursorX = 0;\r
-    int cursorY = 0;\r
-\r
-\r
-    /**\r
-     * Creates a new SeqCanvas object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     */\r
-    public SeqCanvas(AlignViewport av)\r
-    {\r
-        this.av = av;\r
-        fr = new FeatureRenderer(av);\r
-        sr = new SequenceRenderer(av);\r
-        setLayout(new BorderLayout());\r
-        PaintRefresher.Register(this, av.alignment);\r
-        setBackground(Color.white);\r
-    }\r
-\r
-    MCview.PDBCanvas pdbCanvas;\r
-    public SequenceRenderer getSequenceRenderer()\r
-    {\r
-      return sr;\r
-    }\r
-\r
-    public FeatureRenderer getFeatureRenderer()\r
-    {\r
-      return fr;\r
-    }\r
-\r
-    public void setPDBCanvas(MCview.PDBCanvas pc)\r
-    {\r
-      pdbCanvas = pc;\r
-    }\r
-\r
-    public AlignViewport getViewport()\r
-    {\r
-      return av;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param startx DOCUMENT ME!\r
-     * @param endx DOCUMENT ME!\r
-     * @param ypos DOCUMENT ME!\r
-     */\r
-    void drawNorthScale(Graphics g, int startx, int endx, int ypos)\r
-    {\r
-        int scalestartx = startx - (startx % 10) + 10;\r
-\r
-        g.setColor(Color.black);\r
-\r
-        // NORTH SCALE\r
-        for (int i = scalestartx; i < endx; i += 10)\r
-        {\r
-            int value = i;\r
-            if(av.hasHiddenColumns)\r
-                value = av.getColumnSelection().adjustForHiddenColumns(value);\r
-\r
-            g.drawString( String.valueOf(value), (i - startx - 1) * av.charWidth,\r
-                ypos - (av.charHeight / 2));\r
-\r
-            g.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2),\r
-                (ypos + 2) - (av.charHeight / 2),\r
-                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), ypos -\r
-                2);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param startx DOCUMENT ME!\r
-     * @param endx DOCUMENT ME!\r
-     * @param ypos DOCUMENT ME!\r
-     */\r
-    void drawWestScale(Graphics g, int startx, int endx, int ypos)\r
-    {\r
-        FontMetrics fm = getFontMetrics(av.getFont());\r
-        ypos += av.charHeight;\r
-\r
-        if(av.hasHiddenColumns)\r
-                startx = av.getColumnSelection().adjustForHiddenColumns(startx);\r
-\r
-        // EAST SCALE\r
-        for (int i = 0; i < av.alignment.getHeight(); i++)\r
-        {\r
-            SequenceI seq = av.alignment.getSequenceAt(i);\r
-            int index = startx;\r
-            int value = -1;\r
-\r
-            while (index < endx)\r
-            {\r
-                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
-                {\r
-                    index++;\r
-\r
-                    continue;\r
-                }\r
-\r
-                value = av.alignment.getSequenceAt(i).findPosition(index);\r
-\r
-                break;\r
-            }\r
-\r
-            if (value != -1)\r
-            {\r
-                int x = LABEL_WEST - fm.stringWidth(String.valueOf(value))-av.charWidth/2;\r
-                g.drawString(value + "", x,\r
-                    (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param startx DOCUMENT ME!\r
-     * @param endx DOCUMENT ME!\r
-     * @param ypos DOCUMENT ME!\r
-     */\r
-    void drawEastScale(Graphics g, int startx, int endx, int ypos)\r
-    {\r
-        ypos += av.charHeight;\r
-\r
-        if(av.hasHiddenColumns)\r
-                endx = av.getColumnSelection().adjustForHiddenColumns(endx);\r
-\r
-        // EAST SCALE\r
-        for (int i = 0; i < av.alignment.getHeight(); i++)\r
-        {\r
-            SequenceI seq = av.alignment.getSequenceAt(i);\r
-            int index = endx;\r
-            int value = -1;\r
-\r
-\r
-\r
-            while (index > startx)\r
-            {\r
-                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
-                {\r
-                    index--;\r
-\r
-                    continue;\r
-                }\r
-\r
-                value = av.alignment.getSequenceAt(i).findPosition(index);\r
-\r
-                break;\r
-            }\r
-\r
-            if (value != -1)\r
-            {\r
-                g.drawString(String.valueOf(value), 0,\r
-                    (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param horizontal DOCUMENT ME!\r
-     * @param vertical DOCUMENT ME!\r
-     */\r
-    public void fastPaint(int horizontal, int vertical)\r
-    {\r
-        if (gg == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-\r
-        fastPaint = true;\r
-\r
-        gg.copyArea(horizontal * av.charWidth,\r
-                    vertical * av.charHeight,\r
-                    imgWidth,\r
-                    imgHeight,\r
-                    -horizontal * av.charWidth,\r
-                    -vertical * av.charHeight);\r
-\r
-        int sr = av.startRes;\r
-        int er = av.endRes;\r
-        int ss = av.startSeq;\r
-        int es = av.endSeq;\r
-        int transX = 0;\r
-        int transY = 0;\r
-\r
-\r
-        if (horizontal > 0) // scrollbar pulled right, image to the left\r
-        {\r
-            er ++;\r
-            transX = (er - sr - horizontal) * av.charWidth;\r
-            sr = er - horizontal;\r
-        }\r
-        else if (horizontal < 0)\r
-        {\r
-            er = sr - horizontal-1;\r
-        }\r
-        else if (vertical > 0) // scroll down\r
-        {\r
-            ss = es - vertical;\r
-\r
-            if (ss < av.startSeq)\r
-            { // ie scrolling too fast, more than a page at a time\r
-                ss = av.startSeq;\r
-            }\r
-            else\r
-            {\r
-                transY = imgHeight - (vertical * av.charHeight);\r
-            }\r
-        }\r
-        else if (vertical < 0)\r
-        {\r
-            es = ss - vertical;\r
-\r
-            if (es > av.endSeq)\r
-            {\r
-                es = av.endSeq;\r
-            }\r
-        }\r
-\r
-        gg.translate(transX, transY);\r
-        drawPanel(gg, sr, er, ss, es, 0);\r
-        gg.translate(-transX, -transY);\r
-\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * Definitions of startx and endx (hopefully):\r
-     * SMJS This is what I'm working towards!\r
-     *   startx is the first residue (starting at 0) to display.\r
-     *   endx   is the last residue to display (starting at 0).\r
-     *   starty is the first sequence to display (starting at 0).\r
-     *   endy   is the last sequence to display (starting at 0).\r
-     * NOTE 1: The av limits are set in setFont in this class and\r
-     * in the adjustment listener in SeqPanel when the scrollbars move.\r
-     */\r
-\r
-    // Set this to false to force a full panel paint\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        super.paintComponent(g);\r
-\r
-\r
-\r
-        if ( img != null && (fastPaint\r
-             || (getVisibleRect().width != g.getClipBounds().width)\r
-             || (getVisibleRect().height != g.getClipBounds().height)))\r
-        {\r
-            g.drawImage(img, 0, 0, this);\r
-            fastPaint = false;\r
-            return;\r
-        }\r
-\r
-\r
-        // this draws the whole of the alignment\r
-        imgWidth = getWidth();\r
-        imgHeight = getHeight();\r
-\r
-        imgWidth -= (imgWidth % av.charWidth);\r
-        imgHeight -= (imgHeight % av.charHeight);\r
-\r
-        if ((imgWidth < 1) || (imgHeight < 1))\r
-        {\r
-            return;\r
-        }\r
-\r
-        img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);\r
-        gg = (Graphics2D) img.getGraphics();\r
-        gg.setFont(av.getFont());\r
-\r
-        if (av.antiAlias)\r
-          gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                              RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-        gg.setColor(Color.white);\r
-        gg.fillRect(0, 0, imgWidth, imgHeight);\r
-\r
-\r
-        if (av.getWrapAlignment())\r
-        {\r
-            drawWrappedPanel(gg, getWidth(), getHeight(), av.startRes);\r
-        }\r
-        else\r
-        {\r
-            drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq, 0);\r
-        }\r
-\r
-        g.drawImage(img, 0, 0, this);\r
-\r
-        if (pdbCanvas != null)\r
-        {\r
-           pdbCanvas.updateSeqColours();\r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param cwidth DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getWrappedCanvasWidth(int cwidth)\r
-    {\r
-        FontMetrics fm = getFontMetrics(av.getFont());\r
-\r
-        LABEL_EAST = 0;\r
-        LABEL_WEST = 0;\r
-\r
-        if (av.scaleRightWrapped)\r
-        {\r
-            LABEL_EAST = fm.stringWidth(getMask());\r
-        }\r
-\r
-        if (av.scaleLeftWrapped)\r
-        {\r
-            LABEL_WEST = fm.stringWidth(getMask());\r
-        }\r
-\r
-        return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
-    }\r
-\r
-\r
-    /**\r
-     * Generates a string of zeroes.\r
-     * @return String\r
-     */\r
-    String getMask()\r
-    {\r
-      String mask = "00";\r
-      for (int i = av.alignment.getWidth(); i > 0; i /= 10)\r
-      {\r
-        mask += "0";\r
-      }\r
-      return mask;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param canvasWidth DOCUMENT ME!\r
-     * @param canvasHeight DOCUMENT ME!\r
-     * @param startRes DOCUMENT ME!\r
-     */\r
-    public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,\r
-        int startRes)\r
-    {\r
-\r
-        AlignmentI al = av.getAlignment();\r
-\r
-        FontMetrics fm = getFontMetrics(av.getFont());\r
-\r
-        int LABEL_EAST = 0;\r
-\r
-        if (av.scaleRightWrapped)\r
-        {\r
-            LABEL_EAST = fm.stringWidth(getMask());\r
-        }\r
-\r
-        int LABEL_WEST = 0;\r
-\r
-        if (av.scaleLeftWrapped)\r
-        {\r
-            LABEL_WEST = fm.stringWidth(getMask());\r
-        }\r
-\r
-        int hgap = av.charHeight;\r
-        if(av.scaleAboveWrapped)\r
-          hgap += av.charHeight;\r
-\r
-        int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
-        int cHeight = av.getAlignment().getHeight() * av.charHeight;\r
-\r
-        av.setWrappedWidth(cWidth);\r
-\r
-        av.endRes = av.startRes + cWidth;\r
-\r
-\r
-        int endx;\r
-        int ypos = hgap;\r
-\r
-        while ((ypos <= canvasHeight) && (startRes < av.alignment.getWidth()))\r
-        {\r
-          endx = startRes + cWidth;\r
-\r
-          if (endx > al.getWidth())\r
-          {\r
-            endx = al.getWidth();\r
-          }\r
-\r
-            g.setFont(av.getFont());\r
-            g.setColor(Color.black);\r
-\r
-            if (av.scaleLeftWrapped)\r
-            {\r
-                drawWestScale(g, startRes, endx, ypos);\r
-            }\r
-\r
-            if (av.scaleRightWrapped)\r
-            {\r
-                g.translate(canvasWidth - LABEL_EAST, 0);\r
-                drawEastScale(g, startRes, endx, ypos);\r
-                g.translate(-(canvasWidth - LABEL_EAST), 0);\r
-            }\r
-\r
-            g.translate(LABEL_WEST, 0);\r
-\r
-            if (av.scaleAboveWrapped)\r
-            {\r
-                drawNorthScale(g, startRes, endx, ypos);\r
-            }\r
-\r
-            // When printing we have an extra clipped region,\r
-            // the Printable page which we need to account for here\r
-            Shape clip = g.getClip();\r
-\r
-            if (clip == null)\r
-            {\r
-                g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);\r
-            }\r
-            else\r
-            {\r
-                g.setClip(0, (int) clip.getBounds().getY(),\r
-                    cWidth * av.charWidth, (int) clip.getBounds().getHeight());\r
-            }\r
-\r
-            drawPanel(g, startRes, endx, 0, al.getHeight(), ypos);\r
-\r
-            if(av.showAnnotation)\r
-            {\r
-              g.translate(0, cHeight + ypos + 3);\r
-              if(annotations==null)\r
-                annotations = new AnnotationPanel(av);\r
-\r
-              annotations.drawComponent( (Graphics2D) g, startRes, endx);\r
-              g.translate(0, -cHeight - ypos);\r
-            }\r
-            g.setClip(clip);\r
-            g.translate(-LABEL_WEST, 0);\r
-\r
-            ypos += cHeight+getAnnotationHeight()+hgap;\r
-            if(av.showAnnotation)\r
-              ypos -= 3;\r
-\r
-            startRes += cWidth;\r
-        }\r
-    }\r
-\r
-    AnnotationPanel annotations;\r
-    int getAnnotationHeight()\r
-    {\r
-      if(!av.showAnnotation)\r
-        return 0;\r
-\r
-      if(annotations==null)\r
-        annotations = new AnnotationPanel(av);\r
-\r
-      return annotations.adjustPanelHeight();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g1 DOCUMENT ME!\r
-     * @param startRes DOCUMENT ME!\r
-     * @param endRes DOCUMENT ME!\r
-     * @param startSeq DOCUMENT ME!\r
-     * @param endSeq DOCUMENT ME!\r
-     * @param offset DOCUMENT ME!\r
-     */\r
-    void drawPanel(Graphics g1, int startRes, int endRes,\r
-                    int startSeq, int endSeq, int offset)\r
-    {\r
-      if(!av.hasHiddenColumns)\r
-      {\r
-        draw(g1, startRes, endRes, startSeq, endSeq, offset);\r
-      }\r
-      else\r
-      {\r
-        java.util.Vector regions = av.getColumnSelection().getHiddenColumns();\r
-\r
-        int screenY = 0;\r
-        int blockStart = startRes;\r
-        int blockEnd = endRes;\r
-\r
-        for (int i = 0; i < regions.size(); i++)\r
-        {\r
-          int[] region = (int[]) regions.elementAt(i);\r
-          int hideStart = region[0];\r
-          int hideEnd = region[1];\r
-\r
-          if (hideStart <= blockStart)\r
-          {\r
-            blockStart += (hideEnd - hideStart) + 1;\r
-            continue;\r
-          }\r
-\r
-          blockEnd = hideStart - 1;\r
-\r
-          g1.translate(screenY * av.charWidth, 0);\r
-\r
-          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);\r
-\r
-          g1.setColor(Color.blue);\r
-          g1.drawLine( (blockEnd - blockStart + 1) * av.charWidth - 1,\r
-                      startSeq + offset,\r
-                      (blockEnd - blockStart + 1) * av.charWidth - 1,\r
-                      startSeq + (endSeq - startSeq) * av.charHeight + offset);\r
-          g1.drawLine( (blockEnd - blockStart + 1) * av.charWidth,\r
-                      startSeq + offset,\r
-                      (blockEnd - blockStart + 1) * av.charWidth,\r
-                      startSeq + (endSeq - startSeq) * av.charHeight + offset);\r
-\r
-          g1.translate( -screenY * av.charWidth, 0);\r
-          screenY += blockEnd - blockStart + 1;\r
-          blockStart = hideEnd + 1;\r
-        }\r
-\r
-        if (screenY <= (endRes - startRes))\r
-        {\r
-          blockEnd = blockStart + (endRes - startRes) - screenY;\r
-          g1.translate(screenY * av.charWidth, 0);\r
-          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);\r
-          g1.translate( -screenY * av.charWidth, 0);\r
-        }\r
-      }\r
-\r
-    }\r
-\r
-\r
-\r
-\r
-    //int startRes, int endRes, int startSeq, int endSeq, int x, int y,\r
-    // int x1, int x2, int y1, int y2, int startx, int starty,\r
-    void draw(Graphics g1,\r
-                   int startRes, int endRes,\r
-                   int startSeq, int endSeq,\r
-                   int offset)\r
-   {\r
-\r
-\r
-      Graphics2D g = (Graphics2D) g1;\r
-      g.setFont(av.getFont());\r
-      sr.prepare(g, av.renderGaps);\r
-\r
-      SequenceI nextSeq;\r
-\r
-        /// First draw the sequences\r
-        /////////////////////////////\r
-        for (int i = startSeq; i < endSeq; i++)\r
-        {\r
-            nextSeq = av.alignment.getSequenceAt(i);\r
-\r
-            sr.drawSequence(nextSeq, av.alignment.findAllGroups(nextSeq),\r
-                            startRes, endRes,\r
-                            offset + ( (i - startSeq) * av.charHeight));\r
-\r
-            if (av.showSequenceFeatures)\r
-            {\r
-                fr.drawSequence(g1, nextSeq, startRes, endRes,\r
-                    offset + ((i - startSeq) * av.charHeight));\r
-            }\r
-\r
-            /// Highlight search Results once all sequences have been drawn\r
-            //////////////////////////////////////////////////////////\r
-            if (searchResults != null)\r
-            {\r
-              int[] visibleResults = searchResults.getResults(nextSeq, startRes, endRes);\r
-              if (visibleResults != null)\r
-                for (int r = 0; r < visibleResults.length; r += 2)\r
-                {\r
-                  sr.drawHighlightedText(nextSeq, visibleResults[r],\r
-                                         visibleResults[r + 1],\r
-                                         (visibleResults[r] - startRes) * av.charWidth,\r
-                                         offset + ( (i - startSeq) * av.charHeight));\r
-                }\r
-            }\r
-\r
-            if(av.cursorMode && cursorY==i\r
-               && cursorX>=startRes && cursorX<=endRes)\r
-            {\r
-              sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * av.charWidth,\r
-                            offset + ( (i - startSeq) * av.charHeight));\r
-            }\r
-          }\r
-\r
-        //\r
-        /////////////////////////////////////\r
-        // Now outline any areas if necessary\r
-        /////////////////////////////////////\r
-        SequenceGroup group = av.getSelectionGroup();\r
-\r
-        int sx = -1;\r
-        int sy = -1;\r
-        int ex = -1;\r
-        int groupIndex = -1;\r
-\r
-        if ((group == null) && (av.alignment.getGroups().size() > 0))\r
-        {\r
-            group = (SequenceGroup) av.alignment.getGroups().elementAt(0);\r
-            groupIndex = 0;\r
-        }\r
-\r
-        if (group != null)\r
-        {\r
-            do\r
-            {\r
-                int oldY = -1;\r
-                int i = 0;\r
-                boolean inGroup = false;\r
-                int top = -1;\r
-                int bottom = -1;\r
-\r
-                for (i = startSeq; i < endSeq; i++)\r
-                {\r
-                    sx = (group.getStartRes() - startRes) * av.charWidth;\r
-                    sy = offset + ((i - startSeq) * av.charHeight);\r
-                    ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) -\r
-                        1;\r
-\r
-                    if(sx+ex<0 || sx>imgWidth)\r
-                    {\r
-                      continue;\r
-                    }\r
-\r
-                    if ( (sx <= (endRes-startRes)*av.charWidth) &&\r
-                            group.sequences.contains(av.alignment.getSequenceAt(\r
-                                    i)))\r
-                    {\r
-                        if ((bottom == -1) &&\r
-                                !group.sequences.contains(\r
-                                    av.alignment.getSequenceAt(i + 1)))\r
-                        {\r
-                            bottom = sy + av.charHeight;\r
-                        }\r
-\r
-                        if (!inGroup)\r
-                        {\r
-                            if (((top == -1) && (i == 0)) ||\r
-                                    !group.sequences.contains(\r
-                                        av.alignment.getSequenceAt(i - 1)))\r
-                            {\r
-                                top = sy;\r
-                            }\r
-\r
-                            oldY = sy;\r
-                            inGroup = true;\r
-\r
-                            if (group == av.getSelectionGroup())\r
-                            {\r
-                                g.setStroke(new BasicStroke(1,\r
-                                        BasicStroke.CAP_BUTT,\r
-                                        BasicStroke.JOIN_ROUND, 3f,\r
-                                        new float[] { 5f, 3f }, 0f));\r
-                                g.setColor(Color.RED);\r
-                            }\r
-                            else\r
-                            {\r
-                                g.setStroke(new BasicStroke());\r
-                                g.setColor(group.getOutlineColour());\r
-                            }\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                      if (inGroup)\r
-                      {\r
-                        if (sx >= 0 && sx < imgWidth)\r
-                          g.drawLine(sx, oldY, sx, sy);\r
-\r
-                        if (sx + ex < imgWidth)\r
-                          g.drawLine(sx + ex, oldY, sx + ex, sy);\r
-\r
-                        if (sx < 0)\r
-                        {\r
-                          ex += sx;\r
-                          sx = 0;\r
-                        }\r
-\r
-                        if (sx + ex > imgWidth)\r
-                          ex = imgWidth;\r
-\r
-                        else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)\r
-                          ex = (endRes - startRes + 1) * av.charWidth;\r
-\r
-                        if (top != -1)\r
-                        {\r
-                          g.drawLine(sx, top, sx + ex, top);\r
-                          top = -1;\r
-                        }\r
-\r
-                        if (bottom != -1)\r
-                        {\r
-                          g.drawLine(sx, bottom, sx + ex, bottom);\r
-                          bottom = -1;\r
-                        }\r
-\r
-                        inGroup = false;\r
-                        }\r
-                    }\r
-                }\r
-\r
-                if (inGroup)\r
-                {\r
-                  sy = offset + ( (i - startSeq) * av.charHeight);\r
-                  if (sx >= 0 && sx < imgWidth)\r
-                    g.drawLine(sx, oldY, sx, sy);\r
-\r
-                  if (sx + ex < imgWidth)\r
-                    g.drawLine(sx + ex, oldY, sx + ex, sy);\r
-\r
-                  if (sx < 0)\r
-                  {\r
-                    ex += sx;\r
-                    sx = 0;\r
-                  }\r
-\r
-                  if (sx + ex > imgWidth)\r
-                    ex = imgWidth;\r
-                  else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)\r
-                    ex = (endRes - startRes + 1) * av.charWidth;\r
-\r
-                  if (top != -1)\r
-                  {\r
-                    g.drawLine(sx, top, sx + ex, top);\r
-                    top = -1;\r
-                  }\r
-\r
-                  if (bottom != -1)\r
-                  {\r
-                    g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);\r
-                    bottom = -1;\r
-                  }\r
-\r
-                    inGroup = false;\r
-                }\r
-\r
-                groupIndex++;\r
-\r
-                if (groupIndex >= av.alignment.getGroups().size())\r
-                {\r
-                    break;\r
-                }\r
-\r
-                group = (SequenceGroup) av.alignment.getGroups().elementAt(groupIndex);\r
-            }\r
-            while (groupIndex < av.alignment.getGroups().size());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param results DOCUMENT ME!\r
-     */\r
-    public void highlightSearchResults(SearchResults results)\r
-    {\r
-        img = null;\r
-\r
-        searchResults = results;\r
-\r
-        repaint();\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import java.awt.*;
+import java.awt.image.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SeqCanvas extends JComponent
+{
+    final FeatureRenderer fr;
+    final SequenceRenderer sr;
+    BufferedImage img;
+    Graphics2D gg;
+    int imgWidth;
+    int imgHeight;
+    AlignViewport av;
+    SearchResults searchResults = null;
+    boolean fastPaint = false;
+    int LABEL_WEST;
+    int LABEL_EAST;
+
+
+    int cursorX = 0;
+    int cursorY = 0;
+
+
+    /**
+     * Creates a new SeqCanvas object.
+     *
+     * @param av DOCUMENT ME!
+     */
+    public SeqCanvas(AlignViewport av)
+    {
+        this.av = av;
+        fr = new FeatureRenderer(av);
+        sr = new SequenceRenderer(av);
+        setLayout(new BorderLayout());
+        PaintRefresher.Register(this, av.alignment);
+        setBackground(Color.white);
+    }
+
+    MCview.PDBCanvas pdbCanvas;
+    public SequenceRenderer getSequenceRenderer()
+    {
+      return sr;
+    }
+
+    public FeatureRenderer getFeatureRenderer()
+    {
+      return fr;
+    }
+
+    public void setPDBCanvas(MCview.PDBCanvas pc)
+    {
+      pdbCanvas = pc;
+    }
+
+    public AlignViewport getViewport()
+    {
+      return av;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param startx DOCUMENT ME!
+     * @param endx DOCUMENT ME!
+     * @param ypos DOCUMENT ME!
+     */
+    void drawNorthScale(Graphics g, int startx, int endx, int ypos)
+    {
+        int scalestartx = startx - (startx % 10) + 10;
+
+        g.setColor(Color.black);
+
+        // NORTH SCALE
+        for (int i = scalestartx; i < endx; i += 10)
+        {
+            int value = i;
+            if(av.hasHiddenColumns)
+                value = av.getColumnSelection().adjustForHiddenColumns(value);
+
+            g.drawString( String.valueOf(value), (i - startx - 1) * av.charWidth,
+                ypos - (av.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), ypos -
+                2);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param startx DOCUMENT ME!
+     * @param endx DOCUMENT ME!
+     * @param ypos DOCUMENT ME!
+     */
+    void drawWestScale(Graphics g, int startx, int endx, int ypos)
+    {
+        FontMetrics fm = getFontMetrics(av.getFont());
+        ypos += av.charHeight;
+
+        if(av.hasHiddenColumns)
+        {
+          startx = av.getColumnSelection().adjustForHiddenColumns(startx);
+          endx = av.getColumnSelection().adjustForHiddenColumns(endx);
+        }
+
+        int maxwidth = av.alignment.getWidth();
+        if (av.hasHiddenColumns)
+            maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
+
+        // WEST SCALE
+        for (int i = 0; i < av.alignment.getHeight(); i++)
+        {
+            SequenceI seq = av.alignment.getSequenceAt(i);
+            int index = startx;
+            int value = -1;
+
+            while (index < endx)
+            {
+                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+                {
+                    index++;
+
+                    continue;
+                }
+
+                value = av.alignment.getSequenceAt(i).findPosition(index);
+
+                break;
+            }
+
+            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));
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param startx DOCUMENT ME!
+     * @param endx DOCUMENT ME!
+     * @param ypos DOCUMENT ME!
+     */
+    void drawEastScale(Graphics g, int startx, int endx, int ypos)
+    {
+        ypos += av.charHeight;
+
+        if(av.hasHiddenColumns)
+                endx = av.getColumnSelection().adjustForHiddenColumns(endx);
+
+        SequenceI seq;
+        // EAST SCALE
+        for (int i = 0; i < av.alignment.getHeight(); i++)
+        {
+            seq = av.alignment.getSequenceAt(i);
+            int index = endx;
+            int value = -1;
+
+            while (index > startx)
+            {
+                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+                {
+                    index--;
+
+                    continue;
+                }
+
+                value = seq.findPosition(index);
+
+                break;
+            }
+
+            if (value != -1)
+            {
+                g.drawString(String.valueOf(value), 0,
+                    (ypos + (i * av.charHeight)) - (av.charHeight / 5));
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param horizontal DOCUMENT ME!
+     * @param vertical DOCUMENT ME!
+     */
+    public void fastPaint(int horizontal, int vertical)
+    {
+        if (gg == null)
+        {
+            return;
+        }
+
+
+        fastPaint = true;
+
+        gg.copyArea(horizontal * av.charWidth,
+                    vertical * av.charHeight,
+                    imgWidth,
+                    imgHeight,
+                    -horizontal * av.charWidth,
+                    -vertical * av.charHeight);
+
+        int sr = av.startRes;
+        int er = av.endRes;
+        int ss = av.startSeq;
+        int es = av.endSeq;
+        int transX = 0;
+        int transY = 0;
+
+
+        if (horizontal > 0) // scrollbar pulled right, image to the left
+        {
+            er ++;
+            transX = (er - sr - horizontal) * av.charWidth;
+            sr = er - horizontal;
+        }
+        else if (horizontal < 0)
+        {
+            er = sr - horizontal-1;
+        }
+        else if (vertical > 0) // scroll down
+        {
+            ss = es - vertical;
+
+            if (ss < av.startSeq)
+            { // ie scrolling too fast, more than a page at a time
+                ss = av.startSeq;
+            }
+            else
+            {
+                transY = imgHeight - (vertical * av.charHeight);
+            }
+        }
+        else if (vertical < 0)
+        {
+            es = ss - vertical;
+
+            if (es > av.endSeq)
+            {
+                es = av.endSeq;
+            }
+        }
+
+        gg.translate(transX, transY);
+        drawPanel(gg, sr, er, ss, es, 0);
+        gg.translate(-transX, -transY);
+
+        repaint();
+    }
+
+    /**
+     * Definitions of startx and endx (hopefully):
+     * SMJS This is what I'm working towards!
+     *   startx is the first residue (starting at 0) to display.
+     *   endx   is the last residue to display (starting at 0).
+     *   starty is the first sequence to display (starting at 0).
+     *   endy   is the last sequence to display (starting at 0).
+     * NOTE 1: The av limits are set in setFont in this class and
+     * in the adjustment listener in SeqPanel when the scrollbars move.
+     */
+
+    // Set this to false to force a full panel paint
+    public void paintComponent(Graphics g)
+    {
+        super.paintComponent(g);
+
+
+
+        if ( img != null && (fastPaint
+             || (getVisibleRect().width != g.getClipBounds().width)
+             || (getVisibleRect().height != g.getClipBounds().height)))
+        {
+            g.drawImage(img, 0, 0, this);
+            fastPaint = false;
+            return;
+        }
+
+
+        // this draws the whole of the alignment
+        imgWidth = getWidth();
+        imgHeight = getHeight();
+
+        imgWidth -= (imgWidth % av.charWidth);
+        imgHeight -= (imgHeight % av.charHeight);
+
+        if ((imgWidth < 1) || (imgHeight < 1))
+        {
+            return;
+        }
+
+        img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
+        gg = (Graphics2D) img.getGraphics();
+        gg.setFont(av.getFont());
+
+        if (av.antiAlias)
+          gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                              RenderingHints.VALUE_ANTIALIAS_ON);
+
+        gg.setColor(Color.white);
+        gg.fillRect(0, 0, imgWidth, imgHeight);
+
+
+        if (av.getWrapAlignment())
+        {
+            drawWrappedPanel(gg, getWidth(), getHeight(), av.startRes);
+        }
+        else
+        {
+            drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq, 0);
+        }
+
+        g.drawImage(img, 0, 0, this);
+
+        if (pdbCanvas != null)
+        {
+           pdbCanvas.updateSeqColours();
+        }
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param cwidth DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getWrappedCanvasWidth(int cwidth)
+    {
+        FontMetrics fm = getFontMetrics(av.getFont());
+
+        LABEL_EAST = 0;
+        LABEL_WEST = 0;
+
+        if (av.scaleRightWrapped)
+        {
+            LABEL_EAST = fm.stringWidth(getMask());
+        }
+
+        if (av.scaleLeftWrapped)
+        {
+            LABEL_WEST = fm.stringWidth(getMask());
+        }
+
+        return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;
+    }
+
+
+    /**
+     * Generates a string of zeroes.
+     * @return String
+     */
+    String getMask()
+    {
+      String mask = "00";
+      for (int i = av.alignment.getWidth(); i > 0; i /= 10)
+      {
+        mask += "0";
+      }
+      return mask;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param canvasWidth DOCUMENT ME!
+     * @param canvasHeight DOCUMENT ME!
+     * @param startRes DOCUMENT ME!
+     */
+    public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,
+        int startRes)
+    {
+        AlignmentI al = av.getAlignment();
+
+        FontMetrics fm = getFontMetrics(av.getFont());
+
+
+        if (av.scaleRightWrapped)
+        {
+            LABEL_EAST = fm.stringWidth(getMask());
+        }
+
+
+        if (av.scaleLeftWrapped)
+        {
+            LABEL_WEST = fm.stringWidth(getMask());
+        }
+
+        int hgap = av.charHeight;
+        if(av.scaleAboveWrapped)
+          hgap += av.charHeight;
+
+        int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;
+        int cHeight = av.getAlignment().getHeight() * av.charHeight;
+
+        av.setWrappedWidth(cWidth);
+
+        av.endRes = av.startRes + cWidth;
+
+
+        int endx;
+        int ypos = hgap;
+        int maxwidth = av.alignment.getWidth();
+
+        if(av.hasHiddenColumns)
+          maxwidth = av.getColumnSelection().findColumnPosition(maxwidth)-1;
+
+        while ((ypos <= canvasHeight) && (startRes < maxwidth))
+        {
+          endx = startRes + cWidth -1;
+
+          if (endx > maxwidth)
+          {
+            endx = maxwidth;
+          }
+
+            g.setFont(av.getFont());
+            g.setColor(Color.black);
+
+            if (av.scaleLeftWrapped)
+            {
+                drawWestScale(g, startRes, endx, ypos);
+            }
+
+            if (av.scaleRightWrapped)
+            {
+                g.translate(canvasWidth - LABEL_EAST, 0);
+                drawEastScale(g, startRes, endx, ypos);
+                g.translate(-(canvasWidth - LABEL_EAST), 0);
+            }
+
+            g.translate(LABEL_WEST, 0);
+
+            if (av.scaleAboveWrapped)
+            {
+                drawNorthScale(g, startRes, endx, ypos);
+            }
+
+            if (av.hasHiddenColumns && av.showHiddenMarkers)
+            {
+              g.setColor(Color.blue);
+              int res;
+              for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size();
+                   i++)
+              {
+                res = av.getColumnSelection().findHiddenRegionPosition(i) -
+                    startRes;
+
+                if (res < 0 || res > endx - startRes)
+                  continue;
+
+                gg.fillPolygon(new int[]
+                               {res * av.charWidth - av.charHeight / 4,
+                               res * av.charWidth + av.charHeight / 4,
+                               res * av.charWidth},
+                               new int[]
+                               {
+                               ypos - (av.charHeight / 2),
+                               ypos - (av.charHeight / 2),
+                               ypos - (av.charHeight / 2) + 8
+                }, 3);
+
+              }
+            }
+
+
+
+            // When printing we have an extra clipped region,
+            // the Printable page which we need to account for here
+            Shape clip = g.getClip();
+
+            if (clip == null)
+            {
+                g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);
+            }
+            else
+            {
+                g.setClip(0, (int) clip.getBounds().getY(),
+                    cWidth * av.charWidth, (int) clip.getBounds().getHeight());
+            }
+
+            drawPanel(g, startRes, endx, 0, al.getHeight(), ypos);
+
+            if(av.showAnnotation)
+            {
+              g.translate(0, cHeight + ypos + 3);
+              if(annotations==null)
+                annotations = new AnnotationPanel(av);
+
+              annotations.drawComponent( (Graphics2D) g, startRes, endx+1);
+              g.translate(0, -cHeight - ypos);
+            }
+            g.setClip(clip);
+            g.translate(-LABEL_WEST, 0);
+
+            ypos += cHeight+getAnnotationHeight()+hgap;
+            if(av.showAnnotation)
+              ypos -= 3;
+
+            startRes += cWidth;
+        }
+    }
+
+    AnnotationPanel annotations;
+    int getAnnotationHeight()
+    {
+      if(!av.showAnnotation)
+        return 0;
+
+      if(annotations==null)
+        annotations = new AnnotationPanel(av);
+
+      return annotations.adjustPanelHeight();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g1 DOCUMENT ME!
+     * @param startRes DOCUMENT ME!
+     * @param endRes DOCUMENT ME!
+     * @param startSeq DOCUMENT ME!
+     * @param endSeq DOCUMENT ME!
+     * @param offset DOCUMENT ME!
+     */
+    void drawPanel(Graphics g1, int startRes, int endRes,
+                    int startSeq, int endSeq, int offset)
+    {
+      if(!av.hasHiddenColumns)
+      {
+        draw(g1, startRes, endRes, startSeq, endSeq, offset);
+      }
+      else
+      {
+        java.util.Vector regions = av.getColumnSelection().getHiddenColumns();
+
+        int screenY = 0;
+        int blockStart = startRes;
+        int blockEnd = endRes;
+
+        for (int i = 0; i < regions.size(); i++)
+        {
+          int[] region = (int[]) regions.elementAt(i);
+          int hideStart = region[0];
+          int hideEnd = region[1];
+
+          if (hideStart <= blockStart)
+          {
+            blockStart += (hideEnd - hideStart) + 1;
+            continue;
+          }
+
+          blockEnd = hideStart - 1;
+
+          g1.translate(screenY * av.charWidth, 0);
+
+          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+
+          if(av.getShowHiddenMarkers())
+          {
+            g1.setColor(Color.blue);
+            g1.drawLine( (blockEnd - blockStart + 1) * av.charWidth - 1,
+                        startSeq + offset,
+                        (blockEnd - blockStart + 1) * av.charWidth - 1,
+                        startSeq + (endSeq - startSeq) * av.charHeight + offset);
+          }
+
+          g1.translate( -screenY * av.charWidth, 0);
+          screenY += blockEnd - blockStart + 1;
+          blockStart = hideEnd + 1;
+        }
+
+        if (screenY <= (endRes - startRes))
+        {
+          blockEnd = blockStart + (endRes - startRes) - screenY;
+          g1.translate(screenY * av.charWidth, 0);
+          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+
+          g1.translate( -screenY * av.charWidth, 0);
+        }
+      }
+
+    }
+
+
+
+
+    //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,
+                   int offset)
+   {
+      g.setFont(av.getFont());
+      sr.prepare(g, av.renderGaps);
+
+      SequenceI nextSeq;
+
+        /// First draw the sequences
+        /////////////////////////////
+        for (int i = startSeq; i < endSeq; i++)
+        {
+            nextSeq = av.alignment.getSequenceAt(i);
+
+            sr.drawSequence(nextSeq, av.alignment.findAllGroups(nextSeq),
+                            startRes, endRes,
+                            offset + ( (i - startSeq) * av.charHeight));
+
+            if (av.showSequenceFeatures)
+            {
+                fr.drawSequence(g, nextSeq, startRes, endRes,
+                    offset + ((i - startSeq) * av.charHeight));
+            }
+
+            /// Highlight search Results once all sequences have been drawn
+            //////////////////////////////////////////////////////////
+            if (searchResults != null)
+            {
+              int[] visibleResults = searchResults.getResults(nextSeq, startRes, endRes);
+              if (visibleResults != null)
+                for (int r = 0; r < visibleResults.length; r += 2)
+                {
+                  sr.drawHighlightedText(nextSeq, visibleResults[r],
+                                         visibleResults[r + 1],
+                                         (visibleResults[r] - startRes) * av.charWidth,
+                                         offset + ( (i - startSeq) * av.charHeight));
+                }
+            }
+
+            if(av.cursorMode && cursorY==i
+               && cursorX>=startRes && cursorX<=endRes)
+            {
+              sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * av.charWidth,
+                            offset + ( (i - startSeq) * av.charHeight));
+            }
+          }
+
+          if(av.getSelectionGroup()!=null || av.alignment.getGroups().size()>0)
+            drawGroupsBoundaries(g, startRes, endRes, startSeq, endSeq, offset);
+
+   }
+
+   void drawGroupsBoundaries(Graphics g1,
+                   int startRes, int endRes,
+                   int startSeq, int endSeq,
+                   int offset)
+   {
+       Graphics2D g = (Graphics2D)g1;
+        //
+        /////////////////////////////////////
+        // Now outline any areas if necessary
+        /////////////////////////////////////
+        SequenceGroup group = av.getSelectionGroup();
+
+        int sx = -1;
+        int sy = -1;
+        int ex = -1;
+        int groupIndex = -1;
+
+        if ((group == null) && (av.alignment.getGroups().size() > 0))
+        {
+            group = (SequenceGroup) av.alignment.getGroups().elementAt(0);
+            groupIndex = 0;
+        }
+
+        if (group != null)
+        {
+            do
+            {
+                int oldY = -1;
+                int i = 0;
+                boolean inGroup = false;
+                int top = -1;
+                int bottom = -1;
+
+                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;
+
+                    if(sx+ex<0 || sx>imgWidth)
+                    {
+                      continue;
+                    }
+
+                    if ( (sx <= (endRes-startRes)*av.charWidth) &&
+                            group.getSequences(false).
+                            contains(av.alignment.getSequenceAt(i)))
+                    {
+                        if ((bottom == -1) &&
+                                !group.getSequences(false).contains(
+                                    av.alignment.getSequenceAt(i + 1)))
+                        {
+                            bottom = sy + av.charHeight;
+                        }
+
+                        if (!inGroup)
+                        {
+                            if (((top == -1) && (i == 0)) ||
+                                    !group.getSequences(false).contains(
+                                        av.alignment.getSequenceAt(i - 1)))
+                            {
+                                top = sy;
+                            }
+
+                            oldY = sy;
+                            inGroup = true;
+
+                            if (group == av.getSelectionGroup())
+                            {
+                                g.setStroke(new BasicStroke(1,
+                                        BasicStroke.CAP_BUTT,
+                                        BasicStroke.JOIN_ROUND, 3f,
+                                        new float[] { 5f, 3f }, 0f));
+                                g.setColor(Color.RED);
+                            }
+                            else
+                            {
+                                g.setStroke(new BasicStroke());
+                                g.setColor(group.getOutlineColour());
+                            }
+                        }
+                    }
+                    else
+                    {
+                      if (inGroup)
+                      {
+                        if (sx >= 0 && sx < imgWidth)
+                          g.drawLine(sx, oldY, sx, sy);
+
+                        if (sx + ex < imgWidth)
+                          g.drawLine(sx + ex, oldY, sx + ex, sy);
+
+                        if (sx < 0)
+                        {
+                          ex += sx;
+                          sx = 0;
+                        }
+
+                        if (sx + ex > imgWidth)
+                          ex = imgWidth;
+
+                        else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)
+                          ex = (endRes - startRes + 1) * av.charWidth;
+
+                        if (top != -1)
+                        {
+                          g.drawLine(sx, top, sx + ex, top);
+                          top = -1;
+                        }
+
+                        if (bottom != -1)
+                        {
+                          g.drawLine(sx, bottom, sx + ex, bottom);
+                          bottom = -1;
+                        }
+
+                        inGroup = false;
+                        }
+                    }
+                }
+
+                if (inGroup)
+                {
+                  sy = offset + ( (i - startSeq) * av.charHeight);
+                  if (sx >= 0 && sx < imgWidth)
+                    g.drawLine(sx, oldY, sx, sy);
+
+                  if (sx + ex < imgWidth)
+                    g.drawLine(sx + ex, oldY, sx + ex, sy);
+
+                  if (sx < 0)
+                  {
+                    ex += sx;
+                    sx = 0;
+                  }
+
+                  if (sx + ex > imgWidth)
+                    ex = imgWidth;
+                  else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)
+                    ex = (endRes - startRes + 1) * av.charWidth;
+
+                  if (top != -1)
+                  {
+                    g.drawLine(sx, top, sx + ex, top);
+                    top = -1;
+                  }
+
+                  if (bottom != -1)
+                  {
+                    g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);
+                    bottom = -1;
+                  }
+
+                    inGroup = false;
+                }
+
+                groupIndex++;
+
+                if (groupIndex >= av.alignment.getGroups().size())
+                {
+                    break;
+                }
+
+                group = (SequenceGroup) av.alignment.getGroups().elementAt(groupIndex);
+
+                g.setStroke(new BasicStroke());
+            }
+            while (groupIndex < av.alignment.getGroups().size());
+
+        }
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param results DOCUMENT ME!
+     */
+    public void highlightSearchResults(SearchResults results)
+    {
+        img = null;
+
+        searchResults = results;
+
+        repaint();
+    }
+}
index 3f49cc4..7d26d96 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SeqPanel extends JPanel implements MouseListener,\r
-    MouseMotionListener, MouseWheelListener\r
-\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public SeqCanvas seqCanvas;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public AlignmentPanel ap;\r
-    protected int lastres;\r
-    protected int startseq;\r
-    protected AlignViewport av;\r
-\r
-    // if character is inserted or deleted, we will need to recalculate the conservation\r
-    boolean seqEditOccurred = false;\r
-    ScrollThread scrollThread = null;\r
-    boolean mouseDragging = false;\r
-    boolean editingSeqs = false;\r
-    boolean groupEditing = false;\r
-\r
-    //////////////////////////////////////////\r
-    /////Everything below this is for defining the boundary of the rubberband\r
-    //////////////////////////////////////////\r
-    int oldSeq = -1;\r
-    boolean changeEndSeq = false;\r
-    boolean changeStartSeq = false;\r
-    boolean changeEndRes = false;\r
-    boolean changeStartRes = false;\r
-    SequenceGroup stretchGroup = null;\r
-    boolean remove = false;\r
-\r
-    boolean mouseWheelPressed = false;\r
-\r
-    /**\r
-     * Creates a new SeqPanel object.\r
-     *\r
-     * @param avp DOCUMENT ME!\r
-     * @param p DOCUMENT ME!\r
-     */\r
-    public SeqPanel(AlignViewport avp, AlignmentPanel p)\r
-    {\r
-        ToolTipManager.sharedInstance().registerComponent(this);\r
-        ToolTipManager.sharedInstance().setInitialDelay(0);\r
-        ToolTipManager.sharedInstance().setDismissDelay(10000);\r
-        this.av = avp;\r
-        setBackground(Color.white);\r
-\r
-        seqCanvas = new SeqCanvas(avp);\r
-        setLayout(new BorderLayout());\r
-        add(seqCanvas, BorderLayout.CENTER);\r
-\r
-        ap = p;\r
-\r
-        if(!av.isDataset())\r
-        {\r
-          addMouseMotionListener(this);\r
-          addMouseListener(this);\r
-          addMouseWheelListener(this);\r
-        }\r
-    }\r
-\r
-    int startWrapBlock=-1;\r
-    int wrappedBlock=-1;\r
-    int findRes(MouseEvent evt)\r
-   {\r
-     int res = 0;\r
-     int x = evt.getX();\r
-\r
-    if (av.wrapAlignment)\r
-    {\r
-\r
-      int hgap = av.charHeight;\r
-      if (av.scaleAboveWrapped)\r
-        hgap += av.charHeight;\r
-\r
-      int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-          + hgap + seqCanvas.getAnnotationHeight();\r
-\r
-        int y = evt.getY();\r
-        y -= hgap;\r
-        x -= seqCanvas.LABEL_WEST;\r
-\r
-\r
-        int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());\r
-\r
-        wrappedBlock = y / cHeight;\r
-        wrappedBlock += av.getStartRes() / cwidth;\r
-\r
-        res = wrappedBlock * cwidth + x / av.getCharWidth();\r
-\r
-    }\r
-    else\r
-    {\r
-        res = (x / av.getCharWidth()) + av.getStartRes();\r
-    }\r
-\r
-    if(av.hasHiddenColumns)\r
-          res = av.getColumnSelection().adjustForHiddenColumns(res);\r
-\r
-    return res;\r
-\r
-   }\r
-\r
-   int findSeq(MouseEvent evt)\r
-   {\r
-\r
-     int seq = 0;\r
-     int y = evt.getY();\r
-\r
-     if (av.wrapAlignment)\r
-     {\r
-       int hgap = av.charHeight;\r
-       if (av.scaleAboveWrapped)\r
-         hgap += av.charHeight;\r
-\r
-       int cHeight = av.getAlignment().getHeight() * av.charHeight\r
-           + hgap + seqCanvas.getAnnotationHeight();\r
-\r
-         y -= hgap;\r
-\r
-       seq = ( (y % cHeight) / av.getCharHeight());\r
-     }\r
-     else\r
-     {\r
-       seq = (y / av.getCharHeight()) + av.getStartSeq();\r
-     }\r
-\r
-     return seq;\r
-   }\r
-\r
-   void endEditing()\r
-   {\r
-     startseq = -1;\r
-     lastres = -1;\r
-     seqEditOccurred = false;\r
-     editingSeqs = false;\r
-     groupEditing = false;\r
-     keyboardGaps = null;\r
-    }\r
-\r
-\r
-    void moveCursor(int dx, int dy)\r
-    {\r
-      seqCanvas.cursorX += dx;\r
-      seqCanvas.cursorY += dy;\r
-\r
-      if(seqCanvas.cursorX<0)\r
-        seqCanvas.cursorX = 0;\r
-      else if(seqCanvas.cursorX>av.alignment.getWidth()-1)\r
-        seqCanvas.cursorX = av.alignment.getWidth()-1;\r
-      if(seqCanvas.cursorX<av.startRes)\r
-        ap.scrollRight(false);\r
-      else if(seqCanvas.cursorX>av.endRes)\r
-        ap.scrollRight(true);\r
-\r
-      if(seqCanvas.cursorY<0)\r
-        seqCanvas.cursorY=0;\r
-      else if(seqCanvas.cursorY>av.alignment.getHeight()-1)\r
-        seqCanvas.cursorY = av.alignment.getHeight()-1;\r
-      if(seqCanvas.cursorY<av.startSeq)\r
-        ap.scrollUp(true);\r
-      else if(seqCanvas.cursorY+1>av.endSeq)\r
-        ap.scrollUp(false);\r
-\r
-      setStatusMessage(av.alignment.getSequenceAt(seqCanvas.cursorY),\r
-                       seqCanvas.cursorX, seqCanvas.cursorY);\r
-      seqCanvas.repaint();\r
-    }\r
-\r
-    void setSelectionAreaAtCursor(boolean topLeft)\r
-    {\r
-      SequenceI sequence =\r
-          (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY);\r
-\r
-      if(av.getSelectionGroup()!=null)\r
-      {\r
-        SequenceGroup sg = av.selectionGroup;\r
-        //Find the top and bottom of this group\r
-        int min = av.alignment.getHeight(), max = 0;\r
-        for(int i=0; i<sg.getSize(); i++)\r
-        {\r
-          int index = av.alignment.findIndex( sg.getSequenceAt(i) );\r
-          if(index > max)\r
-            max = index;\r
-          if(index < min)\r
-            min = index;\r
-        }\r
-\r
-        max ++;\r
-\r
-        if(topLeft)\r
-        {\r
-          sg.setStartRes(seqCanvas.cursorX);\r
-          if(sg.getEndRes()<seqCanvas.cursorX)\r
-            sg.setEndRes(seqCanvas.cursorX);\r
-\r
-          min = seqCanvas.cursorY;\r
-        }\r
-        else\r
-        {\r
-          sg.setEndRes(seqCanvas.cursorX);\r
-          if(sg.getStartRes()>seqCanvas.cursorX)\r
-            sg.setStartRes(seqCanvas.cursorX);\r
-\r
-          max = seqCanvas.cursorY+1;\r
-        }\r
-\r
-        if(min>max)\r
-        {\r
-          // Only the user can do this\r
-          av.setSelectionGroup(null);\r
-        }\r
-        else\r
-        {\r
-          // Now add any sequences between min and max\r
-          sg.sequences.clear();\r
-          for (int i = min; i < max; i++)\r
-          {\r
-            sg.addSequence(av.alignment.getSequenceAt(i), false);\r
-          }\r
-        }\r
-      }\r
-\r
-      if (av.getSelectionGroup() == null)\r
-      {\r
-        SequenceGroup sg = new SequenceGroup();\r
-        sg.setStartRes(seqCanvas.cursorX);\r
-        sg.setEndRes(seqCanvas.cursorX);\r
-        sg.addSequence(sequence, false);\r
-        av.setSelectionGroup(sg);\r
-      }\r
-\r
-\r
-      ap.repaint();\r
-    }\r
-\r
-    void insertGapAtCursor(boolean group)\r
-    {\r
-      ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",\r
-                                                   av.alignment, HistoryItem.EDIT));\r
-      groupEditing = group;\r
-      startseq = seqCanvas.cursorY;\r
-      lastres = seqCanvas.cursorX;\r
-      editSequence(true, seqCanvas.cursorX+getKeyboardGaps());\r
-      editOccurred();\r
-    }\r
-\r
-    void deleteGapAtCursor(boolean group)\r
-    {\r
-      ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",\r
-                                                   av.alignment, HistoryItem.EDIT));\r
-      groupEditing = group;\r
-      startseq = seqCanvas.cursorY;\r
-      lastres = seqCanvas.cursorX+getKeyboardGaps();\r
-      editSequence(false, seqCanvas.cursorX);\r
-      editOccurred();\r
-    }\r
-\r
-    void numberPressed(char value)\r
-    {\r
-      if(keyboardGaps==null)\r
-        keyboardGaps = new StringBuffer();\r
-\r
-      keyboardGaps.append(value);\r
-    }\r
-\r
-    StringBuffer keyboardGaps;\r
-    int getKeyboardGaps()\r
-    {\r
-      if(keyboardGaps==null)\r
-        return 1;\r
-      else\r
-        return Integer.parseInt(keyboardGaps.toString());\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent evt)\r
-    {\r
-      mouseDragging = false;\r
-      mouseWheelPressed = false;\r
-\r
-      if (!editingSeqs)\r
-      {\r
-         doMouseReleasedDefineMode(evt);\r
-         return;\r
-      }\r
-\r
-       editOccurred();\r
-\r
-       endEditing();\r
-       ap.repaint();\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent evt)\r
-    {\r
-      if (javax.swing.SwingUtilities.isMiddleMouseButton(evt))\r
-      {\r
-        mouseWheelPressed = true;\r
-        return;\r
-      }\r
-\r
-      if (evt.isShiftDown() || evt.isAltDown() ||\r
-          evt.isControlDown())\r
-      {\r
-        if (evt.isAltDown() || evt.isControlDown())\r
-        {\r
-          groupEditing = true;\r
-        }\r
-        editingSeqs = true;\r
-      }\r
-      else\r
-      {\r
-        doMousePressedDefineMode(evt);\r
-        return;\r
-      }\r
-\r
-\r
-\r
-      int seq = findSeq(evt);\r
-      int res = findRes(evt);\r
-\r
-      if(seq<0 || res<0)\r
-        return;\r
-\r
-      ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",\r
-                                                         av.alignment, HistoryItem.EDIT));\r
-\r
-        if ((seq < av.getAlignment().getHeight()) &&\r
-                (res < av.getAlignment().getSequenceAt(seq).getLength()))\r
-        {\r
-            startseq = seq;\r
-            lastres = res;\r
-        }\r
-        else\r
-        {\r
-            startseq = -1;\r
-            lastres = -1;\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseMoved(MouseEvent evt)\r
-    {\r
-      if (editingSeqs)\r
-      {\r
-       // This is because MacOSX creates a mouseMoved\r
-       // If control is down, other platforms will not.\r
-       mouseDragged(evt);\r
-      }\r
-\r
-      int res = findRes(evt);\r
-      int seq = findSeq(evt);\r
-\r
-\r
-      if(res<0 || seq<0 || seq >= av.getAlignment().getHeight())\r
-            return;\r
-\r
-      SequenceI sequence = av.getAlignment().getSequenceAt(seq);\r
-\r
-      if (res > sequence.getLength())\r
-      {\r
-        return;\r
-      }\r
-\r
-      if(seqCanvas.pdbCanvas!=null && sequence==seqCanvas.pdbCanvas.sequence)\r
-      {\r
-        seqCanvas.pdbCanvas.highlightRes(sequence.findPosition(res));\r
-      }\r
-\r
-      setStatusMessage(sequence, res, seq);\r
-\r
-        // use aa to see if the mouse pointer is on a\r
-        if (av.showSequenceFeatures)\r
-        {\r
-            SequenceFeature [] features = sequence.getDatasetSequence().getSequenceFeatures();\r
-            if(features!=null)\r
-            {\r
-              StringBuffer sbuffer = new StringBuffer("<html>");\r
-\r
-              for (int i = 0; i < features.length; i++)\r
-              {\r
-\r
-                if ( (features[i].getBegin() <= sequence.findPosition(res)) &&\r
-                    (features[i].getEnd() >= sequence.findPosition(res)))\r
-                {\r
-                  if(av.featuresDisplayed==null\r
-                    || !av.featuresDisplayed.containsKey(features[i].getType()))\r
-                  continue;\r
-\r
-\r
-                  if (features[i].getType().equals("disulfide bond"))\r
-                  {\r
-                    if (features[i].getBegin() == sequence.findPosition(res)\r
-                        || features[i].getEnd() == sequence.findPosition(res))\r
-                    {\r
-                      if (sbuffer.length() > 6)\r
-                        sbuffer.append("<br>");\r
-                      sbuffer.append("disulfide bond " + features[i].getBegin() + ":" +\r
-                                     features[i].getEnd());\r
-                    }\r
-                  }\r
-                  else\r
-                  {\r
-                    if (sbuffer.length() > 6)\r
-                      sbuffer.append("<br>");\r
-                    if(features[i].featureGroup!=null)\r
-                      sbuffer.append(features[i].featureGroup+";");\r
-\r
-                    sbuffer.append(features[i].getType());\r
-\r
-                    if (features[i].getDescription() != null\r
-                        && !features[i].description.equals(features[i].getType()))\r
-                      sbuffer.append("; " + features[i].getDescription());\r
-\r
-                    if (features[i].getStatus() != null && features[i].getStatus().length()>0)\r
-                    {\r
-                      sbuffer.append("; (" + features[i].getStatus() + ")");\r
-                    }\r
-                  }\r
-                }\r
-\r
-              }\r
-\r
-              sbuffer.append("</html>");\r
-              if(sbuffer.length()==13) // <html></html>\r
-                setToolTipText("");\r
-              else\r
-               setToolTipText(sbuffer.toString());\r
-            }\r
-            else\r
-              setToolTipText("");\r
-        }\r
-    }\r
-\r
-    void setStatusMessage(SequenceI sequence, int res, int seq)\r
-    {\r
-      StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " +\r
-                                           sequence.getName());\r
-\r
-      Object obj = null;\r
-      if (av.alignment.isNucleotide())\r
-      {\r
-        obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) +\r
-                                                   "");\r
-        if (obj != null)\r
-          text.append(" Nucleotide: ");\r
-      }\r
-      else\r
-      {\r
-        obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + "");\r
-        if (obj != null)\r
-          text.append("  Residue: ");\r
-      }\r
-\r
-      if (obj != null)\r
-      {\r
-\r
-        if (obj != "")\r
-        {\r
-          text.append(obj + " (" + sequence.findPosition(res) +\r
-                      ")");\r
-        }\r
-      }\r
-      ap.alignFrame.statusBar.setText(text.toString());\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void mouseDragged(MouseEvent evt)\r
-    {\r
-      if (!editingSeqs)\r
-      {\r
-        doMouseDraggedDefineMode(evt);\r
-        return;\r
-      }\r
-\r
-        int res = findRes(evt);\r
-\r
-        if (res < 0)\r
-        {\r
-            res = 0;\r
-        }\r
-\r
-        if ((lastres == -1) || (lastres == res))\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ( (res < av.getAlignment().getWidth()) && (res < lastres))\r
-        {\r
-          // dragLeft, delete gap\r
-          editSequence(false, res);\r
-        }\r
-        else\r
-          editSequence(true, res);\r
-\r
-        mouseDragging = true;\r
-        if(scrollThread!=null)\r
-          scrollThread.setEvent(evt);\r
-\r
-    }\r
-\r
-    void editSequence(boolean insertGap, int startres)\r
-    {\r
-      int fixedLeft = -1;\r
-      int fixedRight = -1;\r
-      boolean fixedColumns = false;\r
-\r
-       if(insertGap && av.hasHiddenColumns)\r
-        {\r
-          //Stop editing if the user has dragged beyond hiddenBoundary\r
-          fixedRight = av.getColumnSelection().getHiddenRegionBoundary(lastres);\r
-          if( fixedRight < lastres)\r
-          {\r
-            if(lastres!=fixedRight)\r
-            {\r
-              endEditing();\r
-              return;\r
-            }\r
-          }\r
-        }\r
-\r
-        if (!groupEditing && av.hasHiddenRows)\r
-        {\r
-          if (av.alignment.getSequenceAt(startseq).getHiddenSequences() != null)\r
-          {\r
-            groupEditing = true;\r
-          }\r
-        }\r
-\r
-\r
-        SequenceI seq = av.alignment.getSequenceAt(startseq);\r
-        StringBuffer message = new StringBuffer();\r
-        if (groupEditing)\r
-          message.append("Edit group:");\r
-       else\r
-            message.append("Edit sequence: "+seq.getName());\r
-\r
-       if(insertGap)\r
-         message.append(" insert ");\r
-       else\r
-         message.append(" delete ");\r
-\r
-       message.append(Math.abs(startres-lastres)+" gaps.");\r
-       ap.alignFrame.statusBar.setText(message.toString());\r
-\r
-\r
-        //Are we editing within a selection group?\r
-        if (groupEditing\r
-            || (av.getSelectionGroup() != null &&\r
-                av.getSelectionGroup().sequences.contains(seq)))\r
-        {\r
-          fixedColumns = true;\r
-\r
-          fixedLeft = av.getSelectionGroup().getStartRes();\r
-          fixedRight = av.getSelectionGroup().getEndRes();\r
-\r
-          if (   (startres < fixedLeft && lastres >= fixedLeft)\r
-              || (startres >= fixedLeft && lastres < fixedLeft)\r
-              || (startres > fixedRight && lastres <=fixedRight)\r
-              || (startres <= fixedRight && lastres > fixedRight))\r
-          {\r
-            endEditing();\r
-            return;\r
-          }\r
-\r
-          if (fixedLeft > startres)\r
-          {\r
-            fixedRight = fixedLeft - 1;\r
-            fixedLeft = 0;\r
-          }\r
-          else if (fixedRight < startres)\r
-          {\r
-            fixedLeft = fixedRight;\r
-            fixedRight = -1;\r
-          }\r
-        }\r
-\r
-        if (groupEditing)\r
-        {\r
-          SequenceGroup sg = av.getSelectionGroup();\r
-          if(fixedLeft>sg.getEndRes()\r
-          ||fixedRight<sg.getStartRes())\r
-       {\r
-         endEditing();\r
-         return;\r
-       }\r
-\r
-          if (av.hasHiddenRows)\r
-          {\r
-            //sg might be null as the user may only see 1 sequence\r
-            if (sg == null)\r
-            {\r
-              sg = new SequenceGroup();\r
-              sg.addSequence(av.alignment.getSequenceAt(startseq), false);\r
-            }\r
-\r
-            SequenceGroup tmp = new SequenceGroup();\r
-\r
-            //Do any of the sequences have hidden associates?\r
-            for (int s = 0; s < sg.getSize(); s++)\r
-            {\r
-              seq = sg.getSequenceAt(s);\r
-              tmp.addSequence(seq, false);\r
-              if (seq.getHiddenSequences() != null)\r
-              {\r
-                for (int h = 0; h < seq.getHiddenSequences().getSize(); h++)\r
-                  tmp.addSequence(seq.getHiddenSequences().getSequenceAt(h),\r
-                                  false);\r
-              }\r
-            }\r
-\r
-            sg = tmp;\r
-          }\r
-\r
-          if (sg == null)\r
-          {\r
-            endEditing();\r
-            return;\r
-          }\r
-\r
-         // int blankColumn = -1;\r
-\r
-          // drag to right\r
-          if (insertGap)\r
-          {\r
-            // Is it valid??\r
-            // Find the next gap before the end\r
-            // of the visible region boundary\r
-            if (av.hasHiddenColumns)\r
-            {\r
-             // int lastCol = av.getColumnSelection().\r
-             //     getHiddenRegionBoundary(res);\r
-\r
-            }\r
-\r
-              if (fixedRight != startres && fixedRight<av.alignment.getWidth()-1)\r
-              {\r
-                for (fixedRight = fixedRight;\r
-                     fixedRight > lastres;\r
-                     fixedRight --)\r
-                {\r
-                  boolean blank = true;\r
-                  for (int s = 0; s < sg.getSize(); s++)\r
-                  {\r
-                    seq = sg.getSequenceAt(s);\r
-\r
-                    if (seq.getSequence().length() <= fixedRight)\r
-                    {\r
-                      continue;\r
-                    }\r
-\r
-                    if (!jalview.util.Comparison.isGap(\r
-                        seq.getCharAt(fixedRight)))\r
-                    {\r
-                      blank = false;\r
-                      continue;\r
-                    }\r
-                  }\r
-                  if (blank)\r
-                    break;\r
-                }\r
-              }\r
-\r
-              if (fixedRight <= startres)\r
-              {\r
-                endEditing();\r
-                return;\r
-              }\r
-            }\r
-\r
-\r
-          // drag to left\r
-          else\r
-          {\r
-            /// Are we able to delete?\r
-            // ie are all columns blank?\r
-\r
-            for (int s = 0; s < sg.getSize(); s++)\r
-            {\r
-              seq = sg.getSequenceAt(s);\r
-\r
-              for (int j = startres; j < lastres; j++)\r
-              {\r
-                if (seq.getSequence().length() <= j)\r
-                {\r
-                  continue;\r
-                }\r
-\r
-                if (!jalview.util.Comparison.isGap(\r
-                    seq.getSequence().charAt(j)))\r
-                {\r
-                  // Not a gap, block edit not valid\r
-                  endEditing();\r
-                  return;\r
-                }\r
-              }\r
-            }\r
-          }\r
-\r
-\r
-          for (int i = 0; i < sg.getSize(); i++)\r
-          {\r
-            seq = sg.getSequenceAt(i);\r
-\r
-            if (insertGap)\r
-            {\r
-              // dragging to the right\r
-              for (int j = lastres; j < startres; j++)\r
-              {\r
-                if (fixedColumns && fixedRight != -1)\r
-                {\r
-                  insertChar(j, seq, fixedRight);\r
-                }\r
-                else\r
-                  insertChar(j, seq);\r
-              }\r
-            }\r
-            else\r
-            {\r
-              // dragging to the left\r
-              for (int j = lastres; j > startres; j--)\r
-              {\r
-                if (fixedColumns && fixedRight != -1)\r
-                {\r
-                  deleteChar(startres, seq, fixedRight);\r
-                }\r
-                else\r
-                {\r
-                  deleteChar(startres, seq);\r
-                }\r
-              }\r
-            }\r
-          }\r
-        }\r
-        else /////Editing a single sequence///////////\r
-        {\r
-\r
-          if (insertGap)\r
-          {\r
-            // dragging to the right\r
-            for (int j = lastres; j < startres; j++)\r
-            {\r
-              if (fixedColumns && fixedRight != -1)\r
-                insertChar(j, seq, fixedRight);\r
-              else\r
-                insertChar(j, seq);\r
-            }\r
-          }\r
-          else\r
-          {\r
-            // dragging to the left\r
-            for (int j = lastres; j > startres; j--)\r
-            {\r
-              if (fixedColumns && fixedRight != -1)\r
-              {\r
-                deleteChar(startres, seq, fixedRight);\r
-              }\r
-              else\r
-              {\r
-                deleteChar(startres, seq);\r
-              }\r
-            }\r
-          }\r
-        }\r
-\r
-        lastres = startres;\r
-        seqCanvas.repaint();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param j DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    void insertChar(int j, SequenceI seq)\r
-    {\r
-        seq.insertCharAt(j, av.getGapCharacter());\r
-        seqEditOccurred = true;\r
-    }\r
-\r
-    void insertChar(int j, SequenceI seq, int fixedColumn)\r
-    {\r
-      //Find the next gap before the end of the visible region boundary\r
-      //If lastCol > j, theres a boundary after the gap insertion\r
-      int blankColumn = fixedColumn;\r
-      for (blankColumn = fixedColumn; blankColumn > j; blankColumn--)\r
-      {\r
-        if (jalview.util.Comparison.isGap(seq.getCharAt(blankColumn)))\r
-    {\r
-          //Theres a space, so break and insert the gap\r
-          break;\r
-        }\r
-      }\r
-\r
-      if (blankColumn <= j)\r
-      {\r
-        endEditing();\r
-        return;\r
-      }\r
-\r
-      if (!jalview.util.Comparison.isGap(seq.getCharAt(blankColumn)))\r
-      {\r
-        //Just Checking\r
-        System.out.println("Tried removing residue (INSERT)"+seq.getCharAt(fixedColumn));\r
-        return;\r
-      }\r
-\r
-      seq.deleteCharAt(blankColumn);\r
-      seq.insertCharAt(j, av.getGapCharacter());\r
-      seqEditOccurred = true;\r
-    }\r
-\r
-    void deleteChar(int j, SequenceI seq, int fixedColumn)\r
-    {\r
-      if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))\r
-      {\r
-        ap.alignFrame.statusBar.setText(\r
-            "End editing: Tried removing residue " + seq.getCharAt(j));\r
-        return;\r
-      }\r
-\r
-      seq.deleteCharAt(j);\r
-      seq.insertCharAt(fixedColumn, av.getGapCharacter());\r
-      seqEditOccurred = true;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param j DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     */\r
-    void deleteChar(int j, SequenceI seq)\r
-    {\r
-      if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))\r
-      {\r
-        ap.alignFrame.statusBar.setText(\r
-            "End editing: Tried removing residue " + seq.getCharAt(j));\r
-        return;\r
-      }\r
-\r
-        seq.deleteCharAt(j);\r
-        seqEditOccurred = true;\r
-        seqCanvas.repaint();\r
-    }\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent e)\r
-    {\r
-        if(oldSeq < 0)\r
-          oldSeq = 0;\r
-\r
-        if (scrollThread != null)\r
-        {\r
-            scrollThread.running = false;\r
-            scrollThread = null;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent e)\r
-    {\r
-        if (av.getWrapAlignment())\r
-        {\r
-            return;\r
-        }\r
-\r
-        if (mouseDragging)\r
-        {\r
-            scrollThread = new ScrollThread();\r
-        }\r
-    }\r
-\r
-    public void mouseClicked(MouseEvent evt)\r
-    {}\r
-\r
-    public void mouseWheelMoved(MouseWheelEvent e)\r
-    {\r
-      e.consume();\r
-      if (mouseWheelPressed)\r
-      {\r
-        Font font = av.getFont();\r
-        int fontSize = font.getSize();\r
-        if (e.getWheelRotation() > 0 && fontSize < 51)\r
-          fontSize++;\r
-        else if (fontSize > 1)\r
-          fontSize--;\r
-\r
-        av.setFont(new Font(font.getName(), font.getStyle(), fontSize));\r
-        ap.fontChanged();\r
-      }\r
-      else\r
-      {\r
-        if (e.getWheelRotation() > 0)\r
-          ap.scrollUp(false);\r
-        else\r
-          ap.scrollUp(true);\r
-      }\r
-\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    void editOccurred()\r
-    {\r
-      if (!seqEditOccurred)\r
-      {\r
-        ap.alignFrame.historyList.pop();\r
-        ap.alignFrame.updateEditMenuBar();\r
-      }\r
-\r
-      endEditing();\r
-\r
-      av.firePropertyChange("alignment", null,av.getAlignment().getSequences());\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void doMousePressedDefineMode(MouseEvent evt)\r
-    {\r
-      int res = findRes(evt);\r
-      int seq = findSeq(evt);\r
-      oldSeq = seq;\r
-\r
-      startWrapBlock=wrappedBlock;\r
-\r
-      if(av.wrapAlignment && seq>av.alignment.getHeight())\r
-      {\r
-          JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-              "Cannot edit annotations in wrapped view.",\r
-              "Wrapped view - no edit",\r
-              JOptionPane.WARNING_MESSAGE);\r
-        return;\r
-      }\r
-\r
-      if(seq<0 || res<0)\r
-            return;\r
-\r
-        SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq);\r
-\r
-        if ((sequence == null) || (res > sequence.getLength()))\r
-        {\r
-            return;\r
-        }\r
-\r
-        stretchGroup = av.getSelectionGroup();\r
-\r
-        if (stretchGroup == null)\r
-        {\r
-            stretchGroup = av.alignment.findGroup(sequence);\r
-\r
-            if ((stretchGroup != null) && (res > stretchGroup.getStartRes()) &&\r
-                    (res < stretchGroup.getEndRes()))\r
-            {\r
-                av.setSelectionGroup(stretchGroup);\r
-            }\r
-            else\r
-            {\r
-                stretchGroup = null;\r
-            }\r
-        }\r
-        else if (!stretchGroup.sequences.contains(sequence) ||\r
-                (stretchGroup.getStartRes() > res) ||\r
-                (stretchGroup.getEndRes() < res))\r
-        {\r
-            stretchGroup = null;\r
-\r
-            SequenceGroup[] allGroups = av.alignment.findAllGroups(sequence);\r
-\r
-            if (allGroups != null)\r
-            {\r
-                for (int i = 0; i < allGroups.length; i++)\r
-                {\r
-                    if ((allGroups[i].getStartRes() <= res) &&\r
-                            (allGroups[i].getEndRes() >= res))\r
-                    {\r
-                        stretchGroup = allGroups[i];\r
-                        av.setSelectionGroup(stretchGroup);\r
-\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        if (av.cursorMode)\r
-        {\r
-          seqCanvas.cursorX = findRes(evt);\r
-          seqCanvas.cursorY = findSeq(evt);\r
-          seqCanvas.repaint();\r
-          return;\r
-        }\r
-\r
-\r
-        if (stretchGroup == null)\r
-        {\r
-            // define a new group here\r
-            SequenceGroup sg = new SequenceGroup();\r
-            sg.setStartRes(res);\r
-            sg.setEndRes(res);\r
-            sg.addSequence(sequence, false);\r
-            av.setSelectionGroup(sg);\r
-            stretchGroup = sg;\r
-\r
-            if (av.getConservationSelected())\r
-            {\r
-                SliderPanel.setConservationSlider(ap,\r
-                    av.getGlobalColourScheme(), "Background");\r
-            }\r
-\r
-            if (av.getAbovePIDThreshold())\r
-            {\r
-                SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),\r
-                    "Background");\r
-            }\r
-        }\r
-        else if (javax.swing.SwingUtilities.isRightMouseButton(evt))\r
-        {\r
-            jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(ap, null);\r
-            pop.show(this, evt.getX(), evt.getY());\r
-\r
-            // edit the properties of existing group\r
-        }\r
-\r
-        if ((stretchGroup != null) && (stretchGroup.getEndRes() == res))\r
-        {\r
-            // Edit end res position of selected group\r
-            changeEndRes = true;\r
-        }\r
-        else if ((stretchGroup != null) && (stretchGroup.getStartRes() == res))\r
-        {\r
-            // Edit end res position of selected group\r
-            changeStartRes = true;\r
-        }\r
-\r
-        stretchGroup.getWidth();\r
-\r
-        seqCanvas.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void doMouseReleasedDefineMode(MouseEvent evt)\r
-    {\r
-        if (stretchGroup == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-\r
-        if(stretchGroup.cs!=null)\r
-        {\r
-          if (stretchGroup.cs instanceof ClustalxColourScheme)\r
-          {\r
-            ( (ClustalxColourScheme) stretchGroup.cs).resetClustalX(stretchGroup.\r
-                sequences,\r
-                stretchGroup.getWidth());\r
-          }\r
-\r
-          if (stretchGroup.cs.conservationApplied())\r
-          {\r
-            SliderPanel.setConservationSlider(ap, stretchGroup.cs,\r
-                                              stretchGroup.getName());\r
-            stretchGroup.recalcConservation();\r
-          }\r
-          else\r
-          {\r
-            SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,\r
-                                           stretchGroup.getName());\r
-          }\r
-        }\r
-        changeEndRes = false;\r
-        changeStartRes = false;\r
-        stretchGroup = null;\r
-        PaintRefresher.Refresh(av.alignment);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void doMouseDraggedDefineMode(MouseEvent evt)\r
-    {\r
-      int res = findRes(evt);\r
-      int y = findSeq(evt);\r
-\r
-      if(wrappedBlock!=startWrapBlock)\r
-        return;\r
-\r
-       if (stretchGroup == null)\r
-       {\r
-            return;\r
-       }\r
-\r
-\r
-        if(y > av.alignment.getHeight())\r
-        {\r
-          y = av.alignment.getHeight() -1;\r
-        }\r
-\r
-        if (stretchGroup.getEndRes() == res)\r
-        {\r
-            // Edit end res position of selected group\r
-            changeEndRes = true;\r
-        }\r
-        else if (stretchGroup.getStartRes() == res)\r
-        {\r
-            // Edit start res position of selected group\r
-            changeStartRes = true;\r
-        }\r
-\r
-        if (res < av.getStartRes())\r
-        {\r
-            res = av.getStartRes();\r
-        }\r
-\r
-        if (changeEndRes)\r
-        {\r
-            if (res > (stretchGroup.getStartRes() - 1))\r
-            {\r
-                stretchGroup.setEndRes(res);\r
-            }\r
-        }\r
-        else if (changeStartRes)\r
-        {\r
-            if (res < (stretchGroup.getEndRes() + 1))\r
-            {\r
-                stretchGroup.setStartRes(res);\r
-            }\r
-        }\r
-\r
-        int dragDirection = 0;\r
-\r
-        if (y > oldSeq)\r
-        {\r
-            dragDirection = 1;\r
-        }\r
-        else if (y < oldSeq)\r
-        {\r
-            dragDirection = -1;\r
-        }\r
-\r
-\r
-        while ((y != oldSeq) && (oldSeq > -1) && (y < av.alignment.getHeight()))\r
-        {\r
-            // This routine ensures we don't skip any sequences, as the\r
-            // selection is quite slow.\r
-            Sequence seq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);\r
-\r
-            oldSeq += dragDirection;\r
-\r
-            if(oldSeq<0)\r
-              break;\r
-\r
-            Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);\r
-\r
-            if (stretchGroup.sequences.contains(nextSeq))\r
-            {\r
-                stretchGroup.deleteSequence(seq, false);\r
-            }\r
-            else\r
-            {\r
-                if (seq != null)\r
-                {\r
-                    stretchGroup.addSequence(seq, false);\r
-                }\r
-\r
-                stretchGroup.addSequence(nextSeq, false);\r
-            }\r
-        }\r
-\r
-        if(oldSeq < 0)\r
-          oldSeq = -1;\r
-\r
-        mouseDragging = true;\r
-\r
-        if (scrollThread != null)\r
-        {\r
-            scrollThread.setEvent(evt);\r
-        }\r
-\r
-        seqCanvas.repaint();\r
-    }\r
-\r
-\r
-\r
-    // this class allows scrolling off the bottom of the visible alignment\r
-    class ScrollThread extends Thread\r
-    {\r
-        MouseEvent evt;\r
-        boolean running = false;\r
-\r
-        public ScrollThread()\r
-        {\r
-            start();\r
-        }\r
-\r
-        public void setEvent(MouseEvent e)\r
-        {\r
-            evt = e;\r
-        }\r
-\r
-        public void stopScrolling()\r
-        {\r
-            running = false;\r
-        }\r
-\r
-        public void run()\r
-        {\r
-            running = true;\r
-\r
-            while (running)\r
-            {\r
-                if (evt != null)\r
-                {\r
-                    if (mouseDragging && (evt.getY() < 0) &&\r
-                            (av.getStartSeq() > 0))\r
-                    {\r
-                        running = ap.scrollUp(true);\r
-                    }\r
-\r
-                    if (mouseDragging && (evt.getY() >= getHeight()) &&\r
-                            (av.alignment.getHeight() > av.getEndSeq()))\r
-                    {\r
-                        running = ap.scrollUp(false);\r
-                    }\r
-\r
-                    if (mouseDragging && (evt.getX() < 0))\r
-                    {\r
-                        running = ap.scrollRight(false);\r
-                    }\r
-                    else if (mouseDragging && (evt.getX() >= getWidth()))\r
-                    {\r
-                        running = ap.scrollRight(true);\r
-                    }\r
-                }\r
-\r
-                try\r
-                {\r
-                    Thread.sleep(20);\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import java.util.Vector;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SeqPanel extends JPanel implements MouseListener,
+    MouseMotionListener, MouseWheelListener
+
+{
+    /** DOCUMENT ME!! */
+    public SeqCanvas seqCanvas;
+
+    /** DOCUMENT ME!! */
+    public AlignmentPanel ap;
+    protected int lastres;
+    protected int startseq;
+    protected AlignViewport av;
+
+    // if character is inserted or deleted, we will need to recalculate the conservation
+    boolean seqEditOccurred = false;
+    ScrollThread scrollThread = null;
+    boolean mouseDragging = false;
+    boolean editingSeqs = false;
+    boolean groupEditing = false;
+
+    //////////////////////////////////////////
+    /////Everything below this is for defining the boundary of the rubberband
+    //////////////////////////////////////////
+    int oldSeq = -1;
+    boolean changeEndSeq = false;
+    boolean changeStartSeq = false;
+    boolean changeEndRes = false;
+    boolean changeStartRes = false;
+    SequenceGroup stretchGroup = null;
+    boolean remove = false;
+
+    Point lastMousePress;
+    boolean mouseWheelPressed = false;
+    StringBuffer keyboardNo1;
+    StringBuffer keyboardNo2;
+
+    java.net.URL linkImageURL;
+
+    /**
+     * Creates a new SeqPanel object.
+     *
+     * @param avp DOCUMENT ME!
+     * @param p DOCUMENT ME!
+     */
+    public SeqPanel(AlignViewport avp, AlignmentPanel p)
+    {
+        linkImageURL = getClass().getResource("/images/link.gif");
+        ToolTipManager.sharedInstance().registerComponent(this);
+        ToolTipManager.sharedInstance().setInitialDelay(0);
+        ToolTipManager.sharedInstance().setDismissDelay(10000);
+        this.av = avp;
+        setBackground(Color.white);
+
+        seqCanvas = new SeqCanvas(avp);
+        setLayout(new BorderLayout());
+        add(seqCanvas, BorderLayout.CENTER);
+
+        ap = p;
+
+        if(!av.isDataset())
+        {
+          addMouseMotionListener(this);
+          addMouseListener(this);
+          addMouseWheelListener(this);
+        }
+    }
+
+    int startWrapBlock=-1;
+    int wrappedBlock=-1;
+    int findRes(MouseEvent evt)
+   {
+     int res = 0;
+     int x = evt.getX();
+
+    if (av.wrapAlignment)
+    {
+
+      int hgap = av.charHeight;
+      if (av.scaleAboveWrapped)
+        hgap += av.charHeight;
+
+      int cHeight = av.getAlignment().getHeight() * av.charHeight
+          + hgap + seqCanvas.getAnnotationHeight();
+
+        int y = evt.getY();
+        y -= hgap;
+        x -= seqCanvas.LABEL_WEST;
+
+
+        int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());
+
+        wrappedBlock = y / cHeight;
+        wrappedBlock += av.getStartRes() / cwidth;
+
+        res = wrappedBlock * cwidth + x / av.getCharWidth();
+
+    }
+    else
+    {
+        res = (x / av.getCharWidth()) + av.getStartRes();
+    }
+
+    if(av.hasHiddenColumns)
+          res = av.getColumnSelection().adjustForHiddenColumns(res);
+
+    return res;
+
+   }
+
+   int findSeq(MouseEvent evt)
+   {
+     int seq = 0;
+     int y = evt.getY();
+
+     if (av.wrapAlignment)
+     {
+       int hgap = av.charHeight;
+       if (av.scaleAboveWrapped)
+         hgap += av.charHeight;
+
+       int cHeight = av.getAlignment().getHeight() * av.charHeight
+           + hgap + seqCanvas.getAnnotationHeight();
+
+         y -= hgap;
+
+       seq = Math.min( (y % cHeight) / av.getCharHeight(),
+                       av.alignment.getHeight() -1);
+     }
+     else
+     {
+       seq = Math.min( (y / av.getCharHeight()) + av.getStartSeq(),
+                       av.alignment.getHeight() -1);
+     }
+
+     return seq;
+   }
+
+   Vector getAllFeaturesAtRes(SequenceI seq, int res)
+   {
+     Vector allFeatures = new Vector();
+     int index = 0;
+     if(seq.getSequenceFeatures()!=null && av.featuresDisplayed!=null)
+     {
+       while (index < seq.getSequenceFeatures().length)
+       {
+         SequenceFeature sf = seq.getSequenceFeatures()[index];
+         if (sf.getBegin() <= res &&
+             sf.getEnd() >= res)
+         {
+           if (av.featuresDisplayed.containsKey(sf.getType()))
+           {
+             allFeatures.addElement(sf);
+           }
+         }
+         index++;
+       }
+     }
+     return allFeatures;
+  }
+
+   void endEditing()
+   {
+     startseq = -1;
+     lastres = -1;
+     seqEditOccurred = false;
+     editingSeqs = false;
+     groupEditing = false;
+     keyboardNo1 = null;
+     keyboardNo2 = null;
+    }
+
+    void setCursorRow()
+    {
+      seqCanvas.cursorY = getKeyboardNo(keyboardNo1)-1;
+      scrollToVisible();
+    }
+
+    void setCursorColumn()
+    {
+      seqCanvas.cursorX = getKeyboardNo(keyboardNo1)-1;
+      scrollToVisible();
+    }
+
+    void setCursorRowAndColumn()
+    {
+      if(keyboardNo2==null)
+      {
+        keyboardNo2 = new StringBuffer();
+      }
+      else
+      {
+        seqCanvas.cursorX = getKeyboardNo(keyboardNo1) - 1;
+        seqCanvas.cursorY = getKeyboardNo(keyboardNo2) - 1;
+        scrollToVisible();
+      }
+    }
+
+    void setCursorPosition()
+    {
+      SequenceI sequence =
+          (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY);
+
+      seqCanvas.cursorX = sequence.findIndex(
+          getKeyboardNo(keyboardNo1)-1
+          );
+      scrollToVisible();
+    }
+
+    void moveCursor(int dx, int dy)
+    {
+      seqCanvas.cursorX += dx;
+      seqCanvas.cursorY += dy;
+      scrollToVisible();
+    }
+
+    void scrollToVisible()
+    {
+      if (seqCanvas.cursorX < 0)
+        seqCanvas.cursorX = 0;
+      else if (seqCanvas.cursorX > av.alignment.getWidth() - 1)
+        seqCanvas.cursorX = av.alignment.getWidth() - 1;
+
+      if (seqCanvas.cursorY < 0)
+        seqCanvas.cursorY = 0;
+      else if (seqCanvas.cursorY > av.alignment.getHeight() - 1)
+        seqCanvas.cursorY = av.alignment.getHeight() - 1;
+
+
+      endEditing();
+      if(av.wrapAlignment)
+      {
+        ap.scrollToWrappedVisible(seqCanvas.cursorX);
+      }
+      else
+      {
+        while (seqCanvas.cursorY < av.startSeq)
+        {
+          ap.scrollUp(true);
+        }
+        while (seqCanvas.cursorY + 1 > av.endSeq)
+        {
+          ap.scrollUp(false);
+        }
+        if (!av.wrapAlignment)
+        {
+          while (seqCanvas.cursorX < av.startRes)
+          {
+            if (!ap.scrollRight(false))
+              break;
+          }
+          while (seqCanvas.cursorX > av.endRes)
+          {
+            if (!ap.scrollRight(true))
+              break;
+          }
+        }
+      }
+      setStatusMessage(av.alignment.getSequenceAt(seqCanvas.cursorY),
+                       seqCanvas.cursorX, seqCanvas.cursorY);
+
+      seqCanvas.repaint();
+    }
+
+    void setSelectionAreaAtCursor(boolean topLeft)
+    {
+      SequenceI sequence =
+          (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY);
+
+      if(av.getSelectionGroup()!=null)
+      {
+        SequenceGroup sg = av.selectionGroup;
+        //Find the top and bottom of this group
+        int min = av.alignment.getHeight(), max = 0;
+        for(int i=0; i<sg.getSize(false); i++)
+        {
+          int index = av.alignment.findIndex( sg.getSequenceAt(i) );
+          if(index > max)
+            max = index;
+          if(index < min)
+            min = index;
+        }
+
+        max ++;
+
+        if(topLeft)
+        {
+          sg.setStartRes(seqCanvas.cursorX);
+          if(sg.getEndRes()<seqCanvas.cursorX)
+            sg.setEndRes(seqCanvas.cursorX);
+
+          min = seqCanvas.cursorY;
+        }
+        else
+        {
+          sg.setEndRes(seqCanvas.cursorX);
+          if(sg.getStartRes()>seqCanvas.cursorX)
+            sg.setStartRes(seqCanvas.cursorX);
+
+          max = seqCanvas.cursorY+1;
+        }
+
+        if(min>max)
+        {
+          // Only the user can do this
+          av.setSelectionGroup(null);
+        }
+        else
+        {
+          // Now add any sequences between min and max
+          sg.getSequences(false).clear();
+          for (int i = min; i < max; i++)
+          {
+            sg.addSequence(av.alignment.getSequenceAt(i), false);
+          }
+        }
+      }
+
+      if (av.getSelectionGroup() == null)
+      {
+        SequenceGroup sg = new SequenceGroup();
+        sg.setStartRes(seqCanvas.cursorX);
+        sg.setEndRes(seqCanvas.cursorX);
+        sg.addSequence(sequence, false);
+        av.setSelectionGroup(sg);
+      }
+
+
+      ap.repaint();
+    }
+
+    void insertGapAtCursor(boolean group)
+    {
+      ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",
+                                                   av.alignment, HistoryItem.EDIT));
+      groupEditing = group;
+      startseq = seqCanvas.cursorY;
+      lastres = seqCanvas.cursorX;
+      editSequence(true, seqCanvas.cursorX+getKeyboardNo(keyboardNo1));
+      editOccurred();
+    }
+
+    void deleteGapAtCursor(boolean group)
+    {
+      ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",
+                                                   av.alignment, HistoryItem.EDIT));
+      groupEditing = group;
+      startseq = seqCanvas.cursorY;
+      lastres = seqCanvas.cursorX+getKeyboardNo(keyboardNo1);
+      editSequence(false, seqCanvas.cursorX);
+      editOccurred();
+    }
+
+    void numberPressed(char value)
+    {
+      if(keyboardNo1==null)
+        keyboardNo1 = new StringBuffer();
+
+      if(keyboardNo2!=null)
+        keyboardNo2.append(value);
+      else
+        keyboardNo1.append(value);
+    }
+
+    int getKeyboardNo(StringBuffer kb)
+    {
+      if(kb==null)
+        return 1;
+      else
+        return Integer.parseInt(kb.toString());
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent evt)
+    {
+      mouseDragging = false;
+      mouseWheelPressed = false;
+
+      if (!editingSeqs)
+      {
+         doMouseReleasedDefineMode(evt);
+         return;
+      }
+
+       editOccurred();
+
+       ap.repaint();
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent evt)
+    {
+      lastMousePress = evt.getPoint();
+
+      if (javax.swing.SwingUtilities.isMiddleMouseButton(evt))
+      {
+        mouseWheelPressed = true;
+        return;
+      }
+
+      if (evt.isShiftDown() || evt.isAltDown() ||
+          evt.isControlDown())
+      {
+        if (evt.isAltDown() || evt.isControlDown())
+        {
+          groupEditing = true;
+        }
+        editingSeqs = true;
+      }
+      else
+      {
+        doMousePressedDefineMode(evt);
+        return;
+      }
+
+
+
+      int seq = findSeq(evt);
+      int res = findRes(evt);
+
+      if(seq<0 || res<0)
+        return;
+
+      ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence",
+                                                         av.alignment, HistoryItem.EDIT));
+
+        if ((seq < av.getAlignment().getHeight()) &&
+                (res < av.getAlignment().getSequenceAt(seq).getLength()))
+        {
+            startseq = seq;
+            lastres = res;
+        }
+        else
+        {
+            startseq = -1;
+            lastres = -1;
+        }
+
+        return;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseMoved(MouseEvent evt)
+    {
+      if (editingSeqs)
+      {
+       // This is because MacOSX creates a mouseMoved
+       // If control is down, other platforms will not.
+       mouseDragged(evt);
+      }
+
+      int res = findRes(evt);
+      int seq = findSeq(evt);
+
+
+      if(res<0 || seq<0 || seq >= av.getAlignment().getHeight())
+            return;
+
+      SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+
+      if (res > sequence.getLength())
+      {
+        return;
+      }
+
+      if(seqCanvas.pdbCanvas!=null && sequence==seqCanvas.pdbCanvas.sequence)
+      {
+        seqCanvas.pdbCanvas.highlightRes(sequence.findPosition(res));
+      }
+
+      setStatusMessage(sequence, res, seq);
+
+        // use aa to see if the mouse pointer is on a
+        if (av.showSequenceFeatures)
+        {
+            SequenceFeature [] features = sequence.getDatasetSequence().getSequenceFeatures();
+            if(features!=null)
+            {
+              StringBuffer sbuffer = new StringBuffer("<html>");
+              StringBuffer seqSpecific =  new StringBuffer();
+
+              for (int i = 0; i < features.length; i++)
+              {
+
+                if ( (features[i].getBegin() <= sequence.findPosition(res)) &&
+                    (features[i].getEnd() >= sequence.findPosition(res)))
+                {
+                  if(av.featuresDisplayed==null
+                    || !av.featuresDisplayed.containsKey(features[i].getType()))
+                  continue;
+
+
+                  if (features[i].getType().equals("disulfide bond"))
+                  {
+                    if (features[i].getBegin() == sequence.findPosition(res)
+                        || features[i].getEnd() == sequence.findPosition(res))
+                    {
+                      if (sbuffer.length() > 6)
+                        sbuffer.append("<br>");
+                      sbuffer.append("disulfide bond " + features[i].getBegin() + ":" +
+                                     features[i].getEnd());
+                      if (features[i].links != null)
+                      sbuffer.append(" <img src=\"" + linkImageURL + "\">");
+                    }
+                  }
+                  else
+                  {
+                    if (sbuffer.length() > 6)
+                      sbuffer.append("<br>");
+
+                    sbuffer.append(features[i].getType() + " " +
+                                   features[i].begin);
+                    if (features[i].begin != features[i].end)
+                      sbuffer.append(" " + features[i].end);
+
+                    if (features[i].getDescription() != null
+                        && !features[i].description.equals(features[i].getType()))
+                      sbuffer.append("; " + features[i].getDescription());
+
+                    if (features[i].getValue("status") != null)
+                    {
+                      sbuffer.append("; (" + features[i].getValue("status") + ")");
+                    }
+                    if (features[i].links != null)
+                      sbuffer.append(" <img src=\"" + linkImageURL + "\">");
+
+                  }
+                }
+                else if(features[i].begin==0 && features[i].end==0)
+                {
+                  // seqSpecific.append(features[i].featureGroup+": "
+                  //                   + features[i].getType()+" "
+                   //                   +features[i].getDescription()+"<br>");
+
+                }
+              }
+
+              if(seqSpecific.length()>0)
+                seqSpecific.setLength(seqSpecific.length()-4);
+
+              sbuffer.append(seqSpecific);
+              sbuffer.append("</html>");
+              if(sbuffer.length()==13) // <html></html>
+                setToolTipText("");
+              else
+               setToolTipText(sbuffer.toString());
+            }
+            else
+              setToolTipText("");
+        }
+    }
+
+    void setStatusMessage(SequenceI sequence, int res, int seq)
+    {
+      StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " +
+                                           sequence.getName());
+
+      Object obj = null;
+      if (av.alignment.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) +
+                      ")");
+        }
+      }
+      ap.alignFrame.statusBar.setText(text.toString());
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void mouseDragged(MouseEvent evt)
+    {
+      if (mouseWheelPressed)
+      {
+        int oldWidth = av.charWidth;
+
+        //Which is bigger, left-right or up-down?
+        if (Math.abs(evt.getY() - lastMousePress.getY())
+            > Math.abs(evt.getX() - lastMousePress.getX()))
+        {
+          int fontSize = av.font.getSize();
+
+          if (evt.getY() < lastMousePress.getY())
+          {
+            fontSize--;
+          }
+          else if (evt.getY() > lastMousePress.getY())
+          {
+            fontSize++;
+          }
+
+          if(fontSize<1)
+            fontSize = 1;
+
+          av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize));
+          av.charWidth = oldWidth;
+          ap.fontChanged();
+        }
+        else
+        {
+          if (evt.getX() < lastMousePress.getX() && av.charWidth > 1)
+          {
+            av.charWidth--;
+          }
+          else if (evt.getX() > lastMousePress.getX())
+          {
+            av.charWidth++;
+          }
+
+          ap.repaint();
+        }
+
+        FontMetrics fm = getFontMetrics(av.getFont());
+        av.validCharWidth = fm.charWidth('M') <= av.charWidth;
+
+        lastMousePress = evt.getPoint();
+
+        return;
+      }
+
+      if (!editingSeqs)
+      {
+        doMouseDraggedDefineMode(evt);
+        return;
+      }
+
+        int res = findRes(evt);
+
+        if (res < 0)
+        {
+            res = 0;
+        }
+
+        if ((lastres == -1) || (lastres == res))
+        {
+            return;
+        }
+
+        if ( (res < av.getAlignment().getWidth()) && (res < lastres))
+        {
+          // dragLeft, delete gap
+          editSequence(false, res);
+        }
+        else
+          editSequence(true, res);
+
+        mouseDragging = true;
+        if(scrollThread!=null)
+          scrollThread.setEvent(evt);
+
+    }
+
+    synchronized void editSequence(boolean insertGap, int startres)
+    {
+      int fixedLeft = -1;
+      int fixedRight = -1;
+      boolean fixedColumns = false;
+      SequenceGroup sg = av.getSelectionGroup();
+
+
+        if (!groupEditing && av.hasHiddenRows)
+        {
+          if (av.alignment.getSequenceAt(startseq).getHiddenSequences() != null)
+          {
+            groupEditing = true;
+          }
+        }
+
+        //No group, but the sequence may represent a group
+        if (groupEditing
+            && sg == null
+            && av.alignment.getSequenceAt(startseq).getHiddenSequences() == null)
+        {
+          groupEditing = false;
+        }
+
+        SequenceI seq = av.alignment.getSequenceAt(startseq);
+        StringBuffer message = new StringBuffer();
+        if (groupEditing)
+           message.append("Edit group:");
+        else
+           message.append("Edit sequence: "+seq.getName());
+
+       if(insertGap)
+         message.append(" insert ");
+       else
+         message.append(" delete ");
+
+       message.append(Math.abs(startres-lastres)+" gaps.");
+       ap.alignFrame.statusBar.setText(message.toString());
+
+
+        //Are we editing within a selection group?
+        if (groupEditing
+            || (sg != null && sg.getSequences(true).contains(seq)))
+        {
+          fixedColumns = true;
+
+          //sg might be null as the user may only see 1 sequence,
+          //but the sequence represents a group
+          if (sg == null)
+          {
+            sg = new SequenceGroup(null, null, false, false, false, 0,
+                                   av.alignment.getWidth()-1);
+            sg.addSequence(av.alignment.getSequenceAt(startseq), false);
+          }
+
+          fixedLeft = sg.getStartRes();
+          fixedRight = sg.getEndRes();
+
+          if (   (startres < fixedLeft && lastres >= fixedLeft)
+              || (startres >= fixedLeft && lastres < fixedLeft)
+              || (startres > fixedRight && lastres <=fixedRight)
+              || (startres <= fixedRight && lastres > fixedRight))
+          {
+            endEditing();
+            return;
+          }
+
+          if (fixedLeft > startres)
+          {
+            fixedRight = fixedLeft - 1;
+            fixedLeft = 0;
+          }
+          else if (fixedRight < startres)
+          {
+            fixedLeft = fixedRight;
+            fixedRight = -1;
+          }
+        }
+
+
+        if(av.hasHiddenColumns )
+        {
+            fixedColumns = true;
+            int y1 = av.getColumnSelection().getHiddenBoundaryLeft(startres);
+            int y2 = av.getColumnSelection().getHiddenBoundaryRight(startres);
+
+            if ( (insertGap && startres > y1 && lastres < y1)
+                || (!insertGap && startres < y2 && lastres > y2))
+            {
+              endEditing();
+              return;
+            }
+
+            //System.out.print(y1+" "+y2+" "+fixedLeft+" "+fixedRight+"~~");
+            //Selection spans a hidden region
+            if(fixedLeft<y1 && (fixedRight>y2 || fixedRight==-1))
+            {
+              if(startres>=y2)
+              {
+                fixedLeft = y2;
+              }
+              else
+              {
+               fixedRight = y2 - 1;
+             }
+            }
+        }
+
+
+        if (groupEditing)
+        {
+          // drag to right
+          if (insertGap)
+          {
+              //If the user has selected the whole sequence, and is dragging to
+              // the right, we can still extend the alignment and selectionGroup
+              if(   sg.getStartRes() == 0
+                    && sg.getEndRes() == fixedRight
+                    && sg.getEndRes() == av.alignment.getWidth()-1
+                 )
+              {
+                sg.setEndRes(av.alignment.getWidth() + startres - lastres);
+                fixedRight = sg.getEndRes();
+              }
+
+            // Is it valid with fixed columns??
+            // Find the next gap before the end
+            // of the visible region boundary
+            boolean blank = false;
+            for (fixedRight = fixedRight;
+                 fixedRight > lastres;
+                 fixedRight--)
+            {
+              blank = true;
+              for (int s = 0; s < sg.getSize(true); s++)
+              {
+                seq = (SequenceI)sg.getSequences(true).elementAt(s);
+                for (int j = 0; j < startres - lastres; j++)
+                {
+                  if (!jalview.util.Comparison.isGap(
+                      seq.getCharAt(fixedRight - j)))
+                  {
+                    blank = false;
+                    break;
+                  }
+                }
+              }
+              if (blank)
+                break;
+            }
+
+            if (!blank)
+            {
+              if(sg.getSize(false) == av.alignment.getHeight()  )
+              {
+                if((av.hasHiddenColumns
+                    && startres<av.getColumnSelection().getHiddenBoundaryRight(startres)))
+                {
+                  endEditing();
+                  return;
+                }
+
+                int alWidth = av.alignment.getWidth();
+                if(av.hasHiddenRows)
+                {
+                  int hwidth = av.alignment.getHiddenSequences().getWidth();
+                  if(hwidth>alWidth)
+                    alWidth = hwidth;
+                }
+                //We can still insert gaps if the selectionGroup
+                //contains all the sequences
+                sg.setEndRes(sg.getEndRes()+startres-lastres);
+                fixedRight = alWidth+startres-lastres;
+              }
+              else
+              {
+                endEditing();
+                return;
+              }
+            }
+          }
+
+
+          // drag to left
+          else if(!insertGap)
+          {
+            /// Are we able to delete?
+            // ie are all columns blank?
+
+            for (int s = 0; s < sg.getSize(true); s++)
+            {
+              seq = (SequenceI)sg.getSequences(true).elementAt(s);
+
+              for (int j = startres; j < lastres; j++)
+              {
+                if (seq.getSequence().length() <= j)
+                {
+                  continue;
+                }
+
+                if (!jalview.util.Comparison.isGap(
+                    seq.getSequence().charAt(j)))
+                {
+                  // Not a gap, block edit not valid
+                  endEditing();
+                  return;
+                }
+              }
+            }
+          }
+
+
+          for (int i = 0; i < sg.getSize(true); i++)
+          {
+            seq = (SequenceI) sg.getSequences(true).elementAt(i);
+
+            if (insertGap)
+            {
+              // dragging to the right
+              for (int j = lastres; j < startres; j++)
+              {
+                if (fixedColumns && fixedRight != -1)
+                {
+                  insertChar(j, seq, fixedRight);
+                }
+                else
+                  insertChar(j, seq);
+              }
+            }
+            else
+            {
+              // dragging to the left
+              for (int j = lastres; j > startres; j--)
+              {
+                if (fixedColumns && fixedRight != -1)
+                {
+                  deleteChar(startres, seq, fixedRight);
+                }
+                else
+                {
+                  deleteChar(startres, seq);
+                }
+              }
+            }
+          }
+        }
+        else /////Editing a single sequence///////////
+        {
+          if (insertGap)
+          {
+            // dragging to the right
+            for (int j = lastres; j < startres; j++)
+            {
+              if (fixedColumns && fixedRight != -1)
+              {
+                  insertChar(j, seq, fixedRight);
+              }
+              else
+                insertChar(j, seq);
+            }
+          }
+          else
+          {
+            // dragging to the left
+            for (int j = lastres; j > startres; j--)
+            {
+              if (fixedColumns && fixedRight != -1)
+              {
+                deleteChar(startres, seq, fixedRight);
+              }
+              else
+              {
+                deleteChar(startres, seq);
+              }
+            }
+          }
+        }
+
+        lastres = startres;
+        seqCanvas.repaint();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param j DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     */
+    void insertChar(int j, SequenceI seq)
+    {
+        seq.insertCharAt(j, av.getGapCharacter());
+        seqEditOccurred = true;
+    }
+
+    void insertChar(int j, SequenceI seq, int fixedColumn)
+    {
+      //Find the next gap before the end of the visible region boundary
+      //If lastCol > j, theres a boundary after the gap insertion
+      int blankColumn = fixedColumn;
+      for (blankColumn = fixedColumn; blankColumn > j; blankColumn--)
+      {
+        if (jalview.util.Comparison.isGap(seq.getCharAt(blankColumn)))
+        {
+          //Theres a space, so break and insert the gap
+          break;
+        }
+      }
+
+      if (blankColumn <= j)
+      {
+        blankColumn = fixedColumn;
+        endEditing();
+        return;
+      }
+
+      if (!jalview.util.Comparison.isGap(seq.getCharAt(blankColumn)))
+      {
+        //Just Checking
+        System.out.println("Tried removing residue (INSERT)"+seq.getCharAt(fixedColumn));
+        return;
+      }
+
+      seq.deleteCharAt(blankColumn);
+      seq.insertCharAt(j, av.getGapCharacter());
+      seqEditOccurred = true;
+    }
+
+    void deleteChar(int j, SequenceI seq, int fixedColumn)
+    {
+      if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))
+      {
+        ap.alignFrame.statusBar.setText(
+            "End editing: Tried removing residue " + seq.getCharAt(j));
+        return;
+      }
+
+      seq.deleteCharAt(j);
+      seq.insertCharAt(fixedColumn, av.getGapCharacter());
+      seqEditOccurred = true;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param j DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     */
+    void deleteChar(int j, SequenceI seq)
+    {
+      if (!jalview.util.Comparison.isGap(seq.getCharAt(j)))
+      {
+        ap.alignFrame.statusBar.setText(
+            "End editing: Tried removing residue " + seq.getCharAt(j));
+        return;
+      }
+
+        seq.deleteCharAt(j);
+        seqEditOccurred = true;
+        seqCanvas.repaint();
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+        if(oldSeq < 0)
+          oldSeq = 0;
+
+        if (scrollThread != null)
+        {
+            scrollThread.running = false;
+            scrollThread = null;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent e)
+    {
+        if (av.getWrapAlignment())
+        {
+            return;
+        }
+
+        if (mouseDragging)
+        {
+            scrollThread = new ScrollThread();
+        }
+    }
+
+    public void mouseClicked(MouseEvent evt)
+    {}
+
+    public void mouseWheelMoved(MouseWheelEvent e)
+    {
+      e.consume();
+     /* if (mouseWheelPressed)
+      {
+        Font font = av.getFont();
+        int fontSize = font.getSize();
+        if (e.getWheelRotation() > 0 && fontSize < 51)
+          fontSize++;
+        else if (fontSize > 1)
+          fontSize--;
+
+
+
+        av.setFont(new Font(font.getName(), font.getStyle(), fontSize));
+
+        ap.fontChanged();
+      }
+      else*/
+      {
+        if (e.getWheelRotation() > 0)
+          ap.scrollUp(false);
+        else
+          ap.scrollUp(true);
+      }
+
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    void editOccurred()
+    {
+      if (!seqEditOccurred)
+      {
+        ap.alignFrame.historyList.pop();
+        ap.alignFrame.updateEditMenuBar();
+      }
+
+      endEditing();
+
+      av.firePropertyChange("alignment", null,av.getAlignment().getSequences());
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void doMousePressedDefineMode(MouseEvent evt)
+    {
+      int res = findRes(evt);
+      int seq = findSeq(evt);
+      oldSeq = seq;
+
+      startWrapBlock=wrappedBlock;
+
+      if(av.wrapAlignment && seq>av.alignment.getHeight())
+      {
+          JOptionPane.showInternalMessageDialog(Desktop.desktop,
+              "Cannot edit annotations in wrapped view.",
+              "Wrapped view - no edit",
+              JOptionPane.WARNING_MESSAGE);
+          return;
+      }
+
+      if(seq<0 || res<0)
+            return;
+
+        SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq);
+
+        if ((sequence == null) || (res > sequence.getLength()))
+        {
+            return;
+        }
+
+        stretchGroup = av.getSelectionGroup();
+
+        if (stretchGroup == null)
+        {
+            stretchGroup = av.alignment.findGroup(sequence);
+
+            if ((stretchGroup != null) && (res > stretchGroup.getStartRes()) &&
+                    (res < stretchGroup.getEndRes()))
+            {
+                av.setSelectionGroup(stretchGroup);
+            }
+            else
+            {
+                stretchGroup = null;
+            }
+        }
+        else if (!stretchGroup.getSequences(false).contains(sequence) ||
+                (stretchGroup.getStartRes() > res) ||
+                (stretchGroup.getEndRes() < res))
+        {
+            stretchGroup = null;
+
+            SequenceGroup[] allGroups = av.alignment.findAllGroups(sequence);
+
+            if (allGroups != null)
+            {
+                for (int i = 0; i < allGroups.length; i++)
+                {
+                    if ((allGroups[i].getStartRes() <= res) &&
+                            (allGroups[i].getEndRes() >= res))
+                    {
+                        stretchGroup = allGroups[i];
+                        break;
+                    }
+                }
+            }
+
+            av.setSelectionGroup(stretchGroup);
+
+        }
+
+
+        if (javax.swing.SwingUtilities.isRightMouseButton(evt))
+        {
+          Vector allFeatures = getAllFeaturesAtRes(sequence.getDatasetSequence(),
+                                                  sequence.findPosition(res));
+          Vector links = new Vector();
+            for (int i = 0; i < allFeatures.size(); i++)
+            {
+              SequenceFeature sf = (SequenceFeature) allFeatures.elementAt(i);
+              if (sf.links != null)
+              {
+                for (int j = 0; j < sf.links.size(); j++)
+                {
+                  links.addElement(sf.links.elementAt(j));
+                }
+              }
+            }
+
+            jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(ap, null, links);
+            pop.show(this, evt.getX(), evt.getY());
+            return;
+        }
+
+        if (av.cursorMode)
+        {
+          seqCanvas.cursorX = findRes(evt);
+          seqCanvas.cursorY = findSeq(evt);
+          seqCanvas.repaint();
+          return;
+        }
+
+        if (stretchGroup == null)
+        {
+          //Only if left mouse button do we want to change group sizes
+
+          // define a new group here
+          SequenceGroup sg = new SequenceGroup();
+          sg.setStartRes(res);
+          sg.setEndRes(res);
+          sg.addSequence(sequence, false);
+          av.setSelectionGroup(sg);
+          stretchGroup = sg;
+
+          if (av.getConservationSelected())
+          {
+            SliderPanel.setConservationSlider(ap,
+                                              av.getGlobalColourScheme(),
+                                              "Background");
+          }
+
+          if (av.getAbovePIDThreshold())
+          {
+            SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),
+                                           "Background");
+          }
+          if ( (stretchGroup != null) && (stretchGroup.getEndRes() == res))
+          {
+            // Edit end res position of selected group
+            changeEndRes = true;
+          }
+          else if ( (stretchGroup != null) &&
+                   (stretchGroup.getStartRes() == res))
+          {
+            // Edit end res position of selected group
+            changeStartRes = true;
+          }
+          stretchGroup.getWidth();
+        }
+
+        seqCanvas.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void doMouseReleasedDefineMode(MouseEvent evt)
+    {
+        if (stretchGroup == null)
+        {
+            return;
+        }
+
+
+        if(stretchGroup.cs!=null)
+        {
+          if (stretchGroup.cs instanceof ClustalxColourScheme)
+          {
+            ( (ClustalxColourScheme) stretchGroup.cs).resetClustalX(
+                stretchGroup.getSequences(true),
+                stretchGroup.getWidth());
+          }
+
+          if (stretchGroup.cs.conservationApplied())
+          {
+            SliderPanel.setConservationSlider(ap, stretchGroup.cs,
+                                              stretchGroup.getName());
+            stretchGroup.recalcConservation();
+          }
+          else
+          {
+            SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,
+                                           stretchGroup.getName());
+          }
+        }
+        changeEndRes = false;
+        changeStartRes = false;
+        stretchGroup = null;
+        PaintRefresher.Refresh(av.alignment);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void doMouseDraggedDefineMode(MouseEvent evt)
+    {
+      int res = findRes(evt);
+      int y = findSeq(evt);
+
+      if(wrappedBlock!=startWrapBlock)
+        return;
+
+       if (stretchGroup == null)
+       {
+            return;
+       }
+
+        if(res> av.alignment.getWidth())
+        {
+          res = av.alignment.getWidth()-1;
+        }
+
+        if (stretchGroup.getEndRes() == res)
+        {
+            // Edit end res position of selected group
+            changeEndRes = true;
+        }
+        else if (stretchGroup.getStartRes() == res)
+        {
+            // Edit start res position of selected group
+            changeStartRes = true;
+        }
+
+        if (res < av.getStartRes())
+        {
+            res = av.getStartRes();
+        }
+
+        if (changeEndRes)
+        {
+            if (res > (stretchGroup.getStartRes() - 1))
+            {
+                stretchGroup.setEndRes(res);
+            }
+        }
+        else if (changeStartRes)
+        {
+            if (res < (stretchGroup.getEndRes() + 1))
+            {
+                stretchGroup.setStartRes(res);
+            }
+        }
+
+        int dragDirection = 0;
+
+        if (y > oldSeq)
+        {
+            dragDirection = 1;
+        }
+        else if (y < oldSeq)
+        {
+            dragDirection = -1;
+        }
+
+
+        while ((y != oldSeq) && (oldSeq > -1) && (y < av.alignment.getHeight()))
+        {
+            // This routine ensures we don't skip any sequences, as the
+            // selection is quite slow.
+            Sequence seq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);
+
+            oldSeq += dragDirection;
+
+            if(oldSeq<0)
+              break;
+
+            Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);
+
+            if (stretchGroup.getSequences(false).contains(nextSeq))
+            {
+                stretchGroup.deleteSequence(seq, false);
+            }
+            else
+            {
+                if (seq != null)
+                {
+                    stretchGroup.addSequence(seq, false);
+                }
+
+                stretchGroup.addSequence(nextSeq, false);
+            }
+        }
+
+        if(oldSeq < 0)
+          oldSeq = -1;
+
+        mouseDragging = true;
+
+        if (scrollThread != null)
+        {
+            scrollThread.setEvent(evt);
+        }
+
+        seqCanvas.repaint();
+    }
+
+    void scrollCanvas(MouseEvent evt)
+    {
+      if(evt==null)
+      {
+        if(scrollThread!=null)
+        {
+          scrollThread.running = false;
+          scrollThread = null;
+        }
+        mouseDragging = false;
+      }
+      else
+      {
+        if (scrollThread == null)
+          scrollThread = new ScrollThread();
+
+        mouseDragging = true;
+        scrollThread.setEvent(evt);
+      }
+
+    }
+
+
+    // this class allows scrolling off the bottom of the visible alignment
+    class ScrollThread extends Thread
+    {
+        MouseEvent evt;
+        boolean running = false;
+
+        public ScrollThread()
+        {
+            start();
+        }
+
+        public void setEvent(MouseEvent e)
+        {
+            evt = e;
+        }
+
+        public void stopScrolling()
+        {
+            running = false;
+        }
+
+        public void run()
+        {
+            running = true;
+
+            while (running)
+            {
+                if (evt != null)
+                {
+                    if (mouseDragging && (evt.getY() < 0) &&
+                            (av.getStartSeq() > 0))
+                    {
+                        running = ap.scrollUp(true);
+                    }
+
+                    if (mouseDragging && (evt.getY() >= getHeight()) &&
+                            (av.alignment.getHeight() > av.getEndSeq()))
+                    {
+                        running = ap.scrollUp(false);
+                    }
+
+                    if (mouseDragging && (evt.getX() < 0))
+                    {
+                        running = ap.scrollRight(false);
+                    }
+                    else if (mouseDragging && (evt.getX() >= getWidth()))
+                    {
+                        running = ap.scrollRight(true);
+                    }
+                }
+
+                try
+                {
+                    Thread.sleep(20);
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+        }
+    }
+}
index 67a3eff..eaf21c6 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import javax.swing.*;\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import jalview.io.EBIFetchClient;\r
-import MCview.*;\r
-import jalview.datamodel.*;\r
-import jalview.analysis.AlignSeq;\r
-import java.io.File;\r
-import jalview.io.*;\r
-import java.util.*;\r
-\r
-public class SequenceFetcher\r
-    extends JPanel implements Runnable\r
-{\r
-  JInternalFrame frame;\r
-  AlignFrame alignFrame;\r
-  StringBuffer result;\r
-  final String noDbSelected = "-- Select Database --";\r
-  public SequenceFetcher(AlignFrame af)\r
-  {\r
-    alignFrame = af;\r
-    database.addItem(noDbSelected);\r
-    database.addItem("Uniprot");\r
-    database.addItem("EMBL");\r
-    database.addItem("EMBLCDS");\r
-    database.addItem("PDB");\r
-    database.addItem("PFAM");\r
-\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    frame = new JInternalFrame();\r
-    frame.setContentPane(this);\r
-    if (System.getProperty("os.name").startsWith("Mac"))\r
-      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 140);\r
-    else\r
-      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 125);\r
-  }\r
-\r
-  private String getFrameTitle()\r
-  {\r
-    return ( (alignFrame == null) ? "New " : "Additional ") + "Sequence Fetcher";\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.setLayout(gridBagLayout1);\r
-\r
-    database.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    database.setMinimumSize(new Dimension(160, 21));\r
-    database.setPreferredSize(new Dimension(160, 21));\r
-    jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));\r
-    jLabel1.setText(\r
-        "Separate multiple accession ids with semi colon \";\"");\r
-    ok.setText("OK");\r
-    ok.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        ok_actionPerformed(e);\r
-      }\r
-    });\r
-    close.setText("Close");\r
-    close.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        close_actionPerformed(e);\r
-      }\r
-    });\r
-    textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    textfield.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        ok_actionPerformed(e);\r
-      }\r
-    });\r
-    jPanel1.add(ok);\r
-    jPanel1.add(close);\r
-    this.add(jLabel1, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0\r
-                                             , GridBagConstraints.WEST,\r
-                                             GridBagConstraints.NONE,\r
-                                             new Insets(7, 4, 0, 6), 77, 6));\r
-    this.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0\r
-                                             , GridBagConstraints.WEST,\r
-                                             GridBagConstraints.BOTH,\r
-                                             new Insets(7, -2, 7, 12), 241, -2));\r
-    this.add(database, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0\r
-                                              , GridBagConstraints.WEST,\r
-                                              GridBagConstraints.NONE,\r
-                                              new Insets(0, 4, 0, 0), 1, 0));\r
-    this.add(textfield, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0\r
-                                               , GridBagConstraints.CENTER,\r
-                                               GridBagConstraints.HORIZONTAL,\r
-                                               new Insets(0, 0, 0, 6), 200, 1));\r
-  }\r
-\r
-  JComboBox database = new JComboBox();\r
-  JLabel jLabel1 = new JLabel();\r
-  JButton ok = new JButton();\r
-  JButton close = new JButton();\r
-  JPanel jPanel1 = new JPanel();\r
-  JTextField textfield = new JTextField();\r
-  GridBagLayout gridBagLayout1 = new GridBagLayout();\r
-  public void close_actionPerformed(ActionEvent e)\r
-  {\r
-    try\r
-    {\r
-      frame.setClosed(true);\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-  }\r
-\r
-  public void ok_actionPerformed(ActionEvent e)\r
-  {\r
-    database.setEnabled(false);\r
-    textfield.setEnabled(false);\r
-    ok.setEnabled(false);\r
-    close.setEnabled(false);\r
-\r
-    Thread worker = new Thread(this);\r
-    worker.start();\r
-  }\r
-\r
-  private void resetDialog()\r
-  {\r
-    database.setEnabled(true);\r
-    textfield.setEnabled(true);\r
-    ok.setEnabled(true);\r
-    close.setEnabled(true);\r
-  }\r
-\r
-  public void run()\r
-  {\r
-    String error = "";\r
-    if (database.getSelectedItem().equals(noDbSelected))\r
-      error += "Please select the source database\n";\r
-    com.stevesoft.pat.Regex empty = new com.stevesoft.pat.Regex("\\s+", "");\r
-    textfield.setText(empty.replaceAll(textfield.getText()));\r
-    if (textfield.getText().length() == 0)\r
-      error += "Please enter a (semi-colon separated list of) database id(s)";\r
-    if (error.length() > 0)\r
-    {\r
-      showErrorMessage(error);\r
-      resetDialog();\r
-      return;\r
-    }\r
-\r
-    result = new StringBuffer();\r
-    if (database.getSelectedItem().equals("Uniprot"))\r
-    {\r
-      getUniprotFile(textfield.getText());\r
-    }\r
-    else if (database.getSelectedItem().equals("EMBL")\r
-             || database.getSelectedItem().equals("EMBLCDS"))\r
-    {\r
-      EBIFetchClient dbFetch = new EBIFetchClient();\r
-      String[] reply = dbFetch.fetchData(\r
-          database.getSelectedItem().toString().toLowerCase(\r
-          ) + ":" + textfield.getText(),\r
-          "fasta", "raw");\r
-\r
-      if(reply!=null)\r
-      {\r
-        for (int i = 0; i < reply.length; i++)\r
-          result.append(reply[i] + "\n");\r
-\r
-        parseResult(result.toString(), null);\r
-      }\r
-    }\r
-    else if (database.getSelectedItem().equals("PDB"))\r
-    {\r
-      StringTokenizer qset = new StringTokenizer(textfield.getText(), ";");\r
-      String query;\r
-      while (qset.hasMoreTokens() && ((query = qset.nextToken())!=null))\r
-      {\r
-        StringBuffer respart = getPDBFile(query.toUpperCase());\r
-        if(respart!=null)\r
-          result.append(respart);\r
-      }\r
-\r
-\r
-      if (result.length()>0)\r
-        parseResult(result.toString(), null);\r
-    }\r
-    else if( database.getSelectedItem().equals("PFAM"))\r
-    {\r
-      try{\r
-        result.append(new FastaFile(\r
-           "http://www.sanger.ac.uk/cgi-bin/Pfam/getalignment.pl?format=fal&acc="\r
-           +  textfield.getText().toUpperCase(), "URL").print()\r
-           );\r
-\r
-         if(result.length()>0)\r
-           parseResult( result.toString(), textfield.getText().toUpperCase() );\r
-\r
-      }catch(java.io.IOException ex)\r
-      {   result = null;    }\r
-    }\r
-\r
-    if (result == null || result.length() == 0)\r
-      showErrorMessage("Error retrieving " + textfield.getText()\r
-                       + " from " + database.getSelectedItem());\r
-\r
-    resetDialog();\r
-    return;\r
-  }\r
-\r
-  void getUniprotFile(String id)\r
-  {\r
-    EBIFetchClient ebi = new EBIFetchClient();\r
-    File file = ebi.fetchDataAsFile("uniprot:" + id, "xml", null);\r
-    SequenceFeatureFetcher sff = new SequenceFeatureFetcher();\r
-    Vector entries = sff.getUniprotEntries(file);\r
-\r
-    if (entries != null)\r
-    {\r
-      //First, make the new sequences\r
-      Enumeration en = entries.elements();\r
-      while (en.hasMoreElements())\r
-      {\r
-        UniprotEntry entry = (UniprotEntry) en.nextElement();\r
-        StringBuffer name = new StringBuffer(">UniProt/Swiss-Prot");\r
-        Enumeration en2 = entry.getAccession().elements();\r
-        while (en2.hasMoreElements())\r
-        {\r
-          name.append("|");\r
-          name.append(en2.nextElement());\r
-        }\r
-        en2 = entry.getName().elements();\r
-        while (en2.hasMoreElements())\r
-        {\r
-          name.append("|");\r
-          name.append(en2.nextElement());\r
-        }\r
-\r
-        if (entry.getProteinName() != null)\r
-          name.append(" " + entry.getProteinName().elementAt(0));\r
-\r
-        result.append(name + "\n" + entry.getUniprotSequence().getContent() +\r
-                      "\n");\r
-\r
-      }\r
-\r
-      //Then read in the features and apply them to the dataset\r
-      SequenceI[] sequence = parseResult(result.toString(), null);\r
-      for (int i = 0; i < entries.size(); i++)\r
-      {\r
-        UniprotEntry entry = (UniprotEntry) entries.elementAt(i);\r
-        Enumeration e = entry.getDbReference().elements();\r
-        Vector onlyPdbEntries = new Vector();\r
-        while (e.hasMoreElements())\r
-        {\r
-          PDBEntry pdb = (PDBEntry) e.nextElement();\r
-          if (!pdb.getType().equals("PDB"))\r
-            continue;\r
-\r
-          onlyPdbEntries.addElement(pdb);\r
-        }\r
-\r
-        sequence[i].getDatasetSequence().setPDBId(onlyPdbEntries);\r
-        if (entry.getFeature() != null)\r
-        {\r
-          e = entry.getFeature().elements();\r
-          while (e.hasMoreElements())\r
-          {\r
-            sequence[i].getDatasetSequence().addSequenceFeature( (\r
-                SequenceFeature) e.nextElement());\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  StringBuffer getPDBFile(String id)\r
-  {\r
-    StringBuffer result = new StringBuffer();\r
-    String chain = null;\r
-    if (id.indexOf(":") > -1)\r
-    {\r
-      chain = id.substring(id.indexOf(":") + 1);\r
-      id = id.substring(0, id.indexOf(":"));\r
-    }\r
-\r
-    EBIFetchClient ebi = new EBIFetchClient();\r
-    String[] reply = ebi.fetchData("pdb:" + id, "pdb", "raw");\r
-    if (reply == null)\r
-      return null;\r
-    try\r
-    {\r
-      PDBfile pdbfile = new PDBfile(reply);\r
-      for (int i = 0; i < pdbfile.chains.size(); i++)\r
-      {\r
-        if (chain == null ||\r
-            ( (PDBChain) pdbfile.chains.elementAt(i)).id.\r
-            toUpperCase().equals(chain))\r
-          result.append("\n>PDB|" + id + "|" +\r
-                        ( (PDBChain) pdbfile.chains.elementAt(i)).sequence.\r
-                        getName() +\r
-                        "\n"\r
-                        +\r
-                        ( (PDBChain) pdbfile.chains.elementAt(i)).sequence.\r
-                        getSequence());\r
-      }\r
-    }\r
-    catch (Exception ex) // Problem parsing PDB file\r
-    {\r
-      jalview.bin.Cache.log.warn("Exception when retrieving " +\r
-                                 textfield.getText() + " from " +\r
-                                 database.getSelectedItem(), ex);\r
-      return null;\r
-    }\r
-\r
-    return result;\r
-  }\r
-\r
-  SequenceI[] parseResult(String result, String title)\r
-  {\r
-    String format = new IdentifyFile().Identify(result, "Paste");\r
-    SequenceI[] sequences = null;\r
-\r
-    if (FormatAdapter.formats.contains(format))\r
-    {\r
-      sequences = null;\r
-      try{ sequences = new FormatAdapter().readFile(result.toString(), "Paste",\r
-                                               format);}\r
-      catch(Exception ex){}\r
-\r
-      if (sequences != null && sequences.length > 0)\r
-      {\r
-        if (alignFrame == null)\r
-        {\r
-          AlignFrame af = new AlignFrame(new Alignment(sequences));\r
-          af.currentFileFormat = format;\r
-          if(title==null)\r
-            title = "Retrieved from " + database.getSelectedItem();\r
-          Desktop.addInternalFrame(af,\r
-                                   title,\r
-                                   AlignFrame.NEW_WINDOW_WIDTH,\r
-                                   AlignFrame.NEW_WINDOW_HEIGHT);\r
-          af.statusBar.setText("Successfully pasted alignment file");\r
-          try\r
-          {\r
-            af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));\r
-          }\r
-          catch (Exception ex)\r
-          {}\r
-        }\r
-        else\r
-        {\r
-          for (int i = 0; i < sequences.length; i++)\r
-          {\r
-            alignFrame.viewport.alignment.addSequence(sequences[i]);\r
-\r
-            ////////////////////////////\r
-            //Dataset needs extension;\r
-            /////////////////////////////\r
-            Sequence ds = new Sequence(sequences[i].getName(),\r
-                                       AlignSeq.extractGaps("-. ",\r
-                sequences[i].getSequence()),\r
-                                       sequences[i].getStart(),\r
-                                       sequences[i].getEnd());\r
-            sequences[i].setDatasetSequence(ds);\r
-            alignFrame.viewport.alignment.getDataset().addSequence(ds);\r
-          }\r
-          alignFrame.viewport.setEndSeq(alignFrame.viewport.alignment.\r
-                                        getHeight());\r
-          alignFrame.viewport.alignment.getWidth();\r
-          alignFrame.viewport.firePropertyChange("alignment", null,\r
-                                                 alignFrame.viewport.\r
-                                                 getAlignment().getSequences());\r
-\r
-        }\r
-\r
-        if (database.getSelectedItem().equals("PDB"))\r
-        {\r
-          // Parse out the ids from the structured names\r
-          boolean errors = false;\r
-          for (int i = 0; i < sequences.length; i++)\r
-          {\r
-            PDBEntry entry = new PDBEntry();\r
-            com.stevesoft.pat.Regex idbits = new com.stevesoft.pat.Regex(\r
-                "PDB\\|([0-9A-z]{4})\\|(.)");\r
-            if (idbits.search(sequences[i].getName()))\r
-            {\r
-              String pdbid = idbits.substring(1);\r
-              String pdbccode = idbits.substring(2);\r
-              // Construct the PDBEntry\r
-              entry.setId(pdbid);\r
-              if (entry.getProperty() == null)\r
-                entry.setProperty(new Hashtable());\r
-              entry.getProperty().put("chains",\r
-                                      pdbccode\r
-                                      + "=" + sequences[i].getStart()\r
-                                      + "-" + sequences[i].getEnd());\r
-              sequences[i].getDatasetSequence().addPDBId(entry);\r
-\r
-              // We make a DBRefEtntry because we have obtained the PDB file from a verifiable source\r
-              // JBPNote - PDB DBRefEntry should also carry the chain and mapping information\r
-              DBRefEntry dbentry = new DBRefEntry("PDB","0",pdbid);\r
-              sequences[i].getDatasetSequence().addDBRef(dbentry);\r
-            }\r
-            else\r
-            {\r
-              // don't add an entry for this chain, but this is probably a bug\r
-              // that the user should know about.\r
-              jalview.bin.Cache.log.warn(\r
-                  "No PDBEntry constructed for sequence " + i + " : " +\r
-                  sequences[i].getName());\r
-              errors = true;\r
-            }\r
-          }\r
-          if (errors)\r
-            jalview.bin.Cache.log.warn(\r
-                "Query string that resulted in PDBEntry construction failure was :\n" +\r
-                textfield.getText());\r
-        }\r
-\r
-      }\r
-      else\r
-        showErrorMessage("Error retrieving " + textfield.getText()\r
-                         + " from " + database.getSelectedItem());\r
-    }\r
-\r
-    return sequences;\r
-\r
-  }\r
-\r
-  void showErrorMessage(String error)\r
-  {\r
-    resetDialog();\r
-    JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                          error, "Error Retrieving Data",\r
-                                          JOptionPane.WARNING_MESSAGE);\r
-    return;\r
-  }\r
-}\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import jalview.io.EBIFetchClient;
+import MCview.*;
+import jalview.datamodel.*;
+import jalview.analysis.AlignSeq;
+import java.io.File;
+import jalview.io.*;
+import java.util.*;
+
+public class SequenceFetcher
+    extends JPanel implements Runnable
+{
+  JInternalFrame frame;
+  AlignFrame alignFrame;
+  StringBuffer result;
+  final String noDbSelected = "-- Select Database --";
+  public SequenceFetcher(AlignFrame af)
+  {
+    alignFrame = af;
+    database.addItem(noDbSelected);
+    database.addItem("Uniprot");
+    database.addItem("EMBL");
+    database.addItem("EMBLCDS");
+    database.addItem("PDB");
+    database.addItem("PFAM");
+
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    frame = new JInternalFrame();
+    frame.setContentPane(this);
+    if (System.getProperty("os.name").startsWith("Mac"))
+      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 140);
+    else
+      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 125);
+  }
+
+  private String getFrameTitle()
+  {
+    return ( (alignFrame == null) ? "New " : "Additional ") + "Sequence Fetcher";
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    this.setLayout(gridBagLayout1);
+
+    database.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    database.setMinimumSize(new Dimension(160, 21));
+    database.setPreferredSize(new Dimension(160, 21));
+    jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+    jLabel1.setText(
+        "Separate multiple accession ids with semi colon \";\"");
+    ok.setText("OK");
+    ok.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+    close.setText("Close");
+    close.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        close_actionPerformed(e);
+      }
+    });
+    textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    textfield.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+    jPanel1.add(ok);
+    jPanel1.add(close);
+    this.add(jLabel1, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0
+                                             , GridBagConstraints.WEST,
+                                             GridBagConstraints.NONE,
+                                             new Insets(7, 4, 0, 6), 77, 6));
+    this.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0
+                                             , GridBagConstraints.WEST,
+                                             GridBagConstraints.BOTH,
+                                             new Insets(7, -2, 7, 12), 241, -2));
+    this.add(database, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0
+                                              , GridBagConstraints.WEST,
+                                              GridBagConstraints.NONE,
+                                              new Insets(0, 4, 0, 0), 1, 0));
+    this.add(textfield, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0
+                                               , GridBagConstraints.CENTER,
+                                               GridBagConstraints.NONE,
+                                               new Insets(0, 0, 0, 6), 211, 1));
+  }
+
+  JComboBox database = new JComboBox();
+  JLabel jLabel1 = new JLabel();
+  JButton ok = new JButton();
+  JButton close = new JButton();
+  JPanel jPanel1 = new JPanel();
+  JTextField textfield = new JTextField();
+  GridBagLayout gridBagLayout1 = new GridBagLayout();
+  public void close_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      frame.setClosed(true);
+    }
+    catch (Exception ex)
+    {}
+  }
+
+  public void ok_actionPerformed(ActionEvent e)
+  {
+    database.setEnabled(false);
+    textfield.setEnabled(false);
+    ok.setEnabled(false);
+    close.setEnabled(false);
+
+    Thread worker = new Thread(this);
+    worker.start();
+  }
+
+  private void resetDialog()
+  {
+    database.setEnabled(true);
+    textfield.setEnabled(true);
+    ok.setEnabled(true);
+    close.setEnabled(true);
+  }
+
+  public void run()
+  {
+    String error = "";
+    if (database.getSelectedItem().equals(noDbSelected))
+      error += "Please select the source database\n";
+    com.stevesoft.pat.Regex empty = new com.stevesoft.pat.Regex("\\s+", "");
+    textfield.setText(empty.replaceAll(textfield.getText()));
+    if (textfield.getText().length() == 0)
+      error += "Please enter a (semi-colon separated list of) database id(s)";
+    if (error.length() > 0)
+    {
+      showErrorMessage(error);
+      resetDialog();
+      return;
+    }
+
+    result = new StringBuffer();
+    if (database.getSelectedItem().equals("Uniprot"))
+    {
+      getUniprotFile(textfield.getText());
+    }
+    else if (database.getSelectedItem().equals("EMBL")
+             || database.getSelectedItem().equals("EMBLCDS"))
+    {
+      StringTokenizer st = new StringTokenizer(textfield.getText(), ";");
+      while(st.hasMoreTokens())
+      {
+        EBIFetchClient dbFetch = new EBIFetchClient();
+
+        String[] reply = dbFetch.fetchData(
+            database.getSelectedItem().toString().toLowerCase(
+            ) + ":" + st.nextToken(),
+            "fasta", "raw");
+//
+        if (reply != null)
+        {
+          for (int i = 0; i < reply.length; i++)
+            result.append(reply[i] + "\n");
+        }
+      }
+
+      if(result!=null)
+      {
+        System.out.println(result.toString());
+
+        parseResult(result.toString(), null);
+      }
+    }
+    else if (database.getSelectedItem().equals("PDB"))
+    {
+      StringTokenizer qset = new StringTokenizer(textfield.getText(), ";");
+      String query;
+      while (qset.hasMoreTokens() && ((query = qset.nextToken())!=null))
+      {
+        StringBuffer respart = getPDBFile(query.toUpperCase());
+        if(respart!=null)
+          result.append(respart);
+      }
+
+
+      if (result.length()>0)
+        parseResult(result.toString(), null);
+    }
+    else if( database.getSelectedItem().equals("PFAM"))
+    {
+      try{
+        result.append(new FastaFile(
+           "http://www.sanger.ac.uk/cgi-bin/Pfam/getalignment.pl?format=fal&acc="
+           +  textfield.getText().toUpperCase(), "URL").print()
+           );
+
+         if(result.length()>0)
+           parseResult( result.toString(), textfield.getText().toUpperCase() );
+
+      }catch(java.io.IOException ex)
+      {   result = null;    }
+    }
+
+    if (result == null || result.length() == 0)
+      showErrorMessage("Error retrieving " + textfield.getText()
+                       + " from " + database.getSelectedItem());
+
+    resetDialog();
+    return;
+  }
+
+  void getUniprotFile(String id)
+  {
+    EBIFetchClient ebi = new EBIFetchClient();
+    File file = ebi.fetchDataAsFile("uniprot:" + id, "xml", null);
+
+    DBRefFetcher dbref = new DBRefFetcher();
+    Vector entries = dbref.getUniprotEntries(file);
+
+    if (entries != null)
+    {
+      //First, make the new sequences
+      Enumeration en = entries.elements();
+      while (en.hasMoreElements())
+      {
+        UniprotEntry entry = (UniprotEntry) en.nextElement();
+
+        StringBuffer name = new StringBuffer(">UniProt/Swiss-Prot");
+        Enumeration en2 = entry.getAccession().elements();
+        while (en2.hasMoreElements())
+        {
+          name.append("|");
+          name.append(en2.nextElement());
+        }
+        en2 = entry.getName().elements();
+        while (en2.hasMoreElements())
+        {
+          name.append("|");
+          name.append(en2.nextElement());
+        }
+
+        if (entry.getProtein() != null)
+        {
+           name.append(" " + entry.getProtein().getName().elementAt(0));
+        }
+
+        result.append(name + "\n" + entry.getUniprotSequence().getContent() +
+                      "\n");
+
+      }
+
+      //Then read in the features and apply them to the dataset
+      SequenceI[] sequence = parseResult(result.toString(), null);
+      for (int i = 0; i < entries.size(); i++)
+      {
+        UniprotEntry entry = (UniprotEntry) entries.elementAt(i);
+        Enumeration e = entry.getDbReference().elements();
+        Vector onlyPdbEntries = new Vector();
+        while (e.hasMoreElements())
+        {
+          PDBEntry pdb = (PDBEntry) e.nextElement();
+          if (!pdb.getType().equals("PDB"))
+            continue;
+
+          onlyPdbEntries.addElement(pdb);
+        }
+
+        Enumeration en2 = entry.getAccession().elements();
+        while (en2.hasMoreElements())
+        {
+          sequence[i].getDatasetSequence().addDBRef(new DBRefEntry(DBRefSource.UNIPROT,
+                    "0",
+                    en2.nextElement().toString()));
+        }
+
+
+
+
+        sequence[i].getDatasetSequence().setPDBId(onlyPdbEntries);
+        if (entry.getFeature() != null)
+        {
+          e = entry.getFeature().elements();
+          while (e.hasMoreElements())
+          {
+            SequenceFeature sf = (SequenceFeature) e.nextElement();
+            sf.setFeatureGroup("Uniprot");
+            sequence[i].getDatasetSequence().addSequenceFeature( sf );
+          }
+        }
+      }
+    }
+  }
+
+  StringBuffer getPDBFile(String id)
+  {
+    StringBuffer result = new StringBuffer();
+    String chain = null;
+    if (id.indexOf(":") > -1)
+    {
+      chain = id.substring(id.indexOf(":") + 1);
+      id = id.substring(0, id.indexOf(":"));
+    }
+
+    EBIFetchClient ebi = new EBIFetchClient();
+    String file = ebi.fetchDataAsFile("pdb:" + id, "pdb", "raw").getAbsolutePath();
+    if (file == null)
+      return null;
+    try
+    {
+      PDBfile pdbfile = new PDBfile(file, jalview.io.AppletFormatAdapter.FILE);
+      for (int i = 0; i < pdbfile.chains.size(); i++)
+      {
+        if (chain == null ||
+            ( (PDBChain) pdbfile.chains.elementAt(i)).id.
+            toUpperCase().equals(chain))
+
+          result.append("\n>PDB|" + id + "|" +
+                        ( (PDBChain) pdbfile.chains.elementAt(i)).sequence.
+                        getName() +
+                        "\n"
+                        +
+                        ( (PDBChain) pdbfile.chains.elementAt(i)).sequence.
+                        getSequence());
+      }
+    }
+    catch (Exception ex) // Problem parsing PDB file
+    {
+      jalview.bin.Cache.log.warn("Exception when retrieving " +
+                                 textfield.getText() + " from " +
+                                 database.getSelectedItem(), ex);
+      return null;
+    }
+
+    return result;
+  }
+
+  SequenceI[] parseResult(String result, String title)
+  {
+    String format = new IdentifyFile().Identify(result, "Paste");
+    SequenceI[] sequences = null;
+
+    if (FormatAdapter.isValidFormat(format))
+    {
+      sequences = null;
+      try{ sequences = new FormatAdapter().readFile(result.toString(), "Paste",
+                                               format);}
+      catch(Exception ex){}
+
+      if (sequences != null && sequences.length > 0)
+      {
+        if (alignFrame == null)
+        {
+          AlignFrame af = new AlignFrame(new Alignment(sequences));
+          af.currentFileFormat = format;
+          if(title==null)
+            title = "Retrieved from " + database.getSelectedItem();
+          Desktop.addInternalFrame(af,
+                                   title,
+                                   AlignFrame.NEW_WINDOW_WIDTH,
+                                   AlignFrame.NEW_WINDOW_HEIGHT);
+          af.statusBar.setText("Successfully pasted alignment file");
+
+          try
+          {
+            af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));
+          }
+          catch (Exception ex)
+          {}
+        }
+        else
+        {
+          for (int i = 0; i < sequences.length; i++)
+          {
+            alignFrame.viewport.alignment.addSequence(sequences[i]);
+
+            ////////////////////////////
+            //Dataset needs extension;
+            /////////////////////////////
+            Sequence ds = new Sequence(sequences[i].getName(),
+                                       AlignSeq.extractGaps("-. ",
+                sequences[i].getSequence()),
+                                       sequences[i].getStart(),
+                                       sequences[i].getEnd());
+            sequences[i].setDatasetSequence(ds);
+            alignFrame.viewport.alignment.getDataset().addSequence(ds);
+          }
+          alignFrame.viewport.setEndSeq(alignFrame.viewport.alignment.
+                                        getHeight());
+          alignFrame.viewport.alignment.getWidth();
+          alignFrame.viewport.firePropertyChange("alignment", null,
+                                                 alignFrame.viewport.
+                                                 getAlignment().getSequences());
+
+        }
+
+        if (database.getSelectedItem().equals("PDB"))
+        {
+          // Parse out the ids from the structured names
+          boolean errors = false;
+          for (int i = 0; i < sequences.length; i++)
+          {
+            PDBEntry entry = new PDBEntry();
+            com.stevesoft.pat.Regex idbits = new com.stevesoft.pat.Regex(
+                "PDB\\|([0-9A-z]{4})\\|(.)");
+            if (idbits.search(sequences[i].getName()))
+            {
+              String pdbid = idbits.substring(1);
+              String pdbccode = idbits.substring(2);
+              // Construct the PDBEntry
+              entry.setId(pdbid);
+              if (entry.getProperty() == null)
+                entry.setProperty(new Hashtable());
+              entry.getProperty().put("chains",
+                                      pdbccode
+                                      + "=" + sequences[i].getStart()
+                                      + "-" + sequences[i].getEnd());
+              sequences[i].getDatasetSequence().addPDBId(entry);
+
+              // We make a DBRefEtntry because we have obtained the PDB file from a verifiable source
+              // JBPNote - PDB DBRefEntry should also carry the chain and mapping information
+              DBRefEntry dbentry = new DBRefEntry(jalview.datamodel.DBRefSource.PDB,"0",pdbid);
+              sequences[i].getDatasetSequence().addDBRef(dbentry);
+            }
+            else
+            {
+              // don't add an entry for this chain, but this is probably a bug
+              // that the user should know about.
+              jalview.bin.Cache.log.warn(
+                  "No PDBEntry constructed for sequence " + i + " : " +
+                  sequences[i].getName());
+              errors = true;
+            }
+          }
+          if (errors)
+            jalview.bin.Cache.log.warn(
+                "Query string that resulted in PDBEntry construction failure was :\n" +
+                textfield.getText());
+        }
+
+      }
+      else
+        showErrorMessage("Error retrieving " + textfield.getText()
+                         + " from " + database.getSelectedItem());
+    }
+
+    return sequences;
+
+  }
+
+  void showErrorMessage(final String error)
+  {
+    resetDialog();
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      public void run()
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                              error, "Error Retrieving Data",
+                                          JOptionPane.WARNING_MESSAGE);
+      }
+    });
+  }
+}
+
index ab6c1ab..6a63236 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SequenceRenderer\r
-{\r
-    AlignViewport av;\r
-    FontMetrics fm;\r
-    boolean renderGaps = true;\r
-    SequenceGroup currentSequenceGroup = null;\r
-    SequenceGroup[] allGroups = null;\r
-    Color resBoxColour;\r
-    Graphics graphics;\r
-    boolean monospacedFont;\r
-    boolean forOverview = false;\r
-\r
-    /**\r
-     * Creates a new SequenceRenderer object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     */\r
-    public SequenceRenderer(AlignViewport av)\r
-    {\r
-        this.av = av;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void prepare(Graphics g, boolean renderGaps)\r
-    {\r
-        graphics = g;\r
-        fm = g.getFontMetrics();\r
-        monospacedFont = fm.getStringBounds("M",g).getWidth()==fm.getStringBounds("|",g).getWidth();\r
-        this.renderGaps = renderGaps;\r
-    }\r
-\r
-\r
-    public Color getResidueBoxColour(SequenceI seq, int i)\r
-    {\r
-      allGroups = av.alignment.findAllGroups(seq);\r
-\r
-      if (inCurrentSequenceGroup(i))\r
-      {\r
-        if (currentSequenceGroup.getDisplayBoxes())\r
-        {\r
-          getBoxColour(currentSequenceGroup.cs, seq, i);\r
-        }\r
-      }\r
-      else if (av.getShowBoxes())\r
-      {\r
-          getBoxColour(av.globalColourScheme, seq, i);\r
-      }\r
-\r
-      return resBoxColour;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param cs DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)\r
-    {\r
-        if (cs != null)\r
-        {\r
-            resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);\r
-        }\r
-        else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))\r
-        {\r
-            resBoxColour = Color.lightGray;\r
-        }\r
-        else\r
-        {\r
-          resBoxColour = Color.white;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param seq DOCUMENT ME!\r
-     * @param sg DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    public void drawSequence(SequenceI seq, SequenceGroup[] sg,\r
-        int start, int end, int y1)\r
-    {\r
-        allGroups = sg;\r
-\r
-        drawBoxes(seq, start, end, y1);\r
-\r
-        drawText(seq, start, end, y1);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    public synchronized void drawBoxes(SequenceI seq, int start, int end, int y1)\r
-    {\r
-      int i = start;\r
-      int length = seq.getLength();\r
-\r
-      int curStart = -1;\r
-      int curWidth = av.charWidth;\r
-\r
-      Color tempColour = null;\r
-\r
-      while (i <= end)\r
-      {\r
-        resBoxColour = Color.white;\r
-\r
-        if (i < length)\r
-        {\r
-          if (inCurrentSequenceGroup(i))\r
-          {\r
-            if (currentSequenceGroup.getDisplayBoxes())\r
-            {\r
-              getBoxColour(currentSequenceGroup.cs, seq, i);\r
-            }\r
-          }\r
-          else if (av.getShowBoxes())\r
-          {\r
-            getBoxColour(av.globalColourScheme, seq, i);\r
-          }\r
-\r
-        }\r
-\r
-          if (resBoxColour != tempColour)\r
-          {\r
-              if (tempColour != null)\r
-              {\r
-                  graphics.fillRect( av.charWidth * (curStart - start), y1,\r
-                      curWidth, av.charHeight);\r
-              }\r
-\r
-              graphics.setColor(resBoxColour);\r
-\r
-              curStart = i;\r
-              curWidth = av.charWidth;\r
-              tempColour = resBoxColour;\r
-          }\r
-          else\r
-          {\r
-              curWidth += av.charWidth;\r
-          }\r
-\r
-          i++;\r
-      }\r
-\r
-      graphics.fillRect( av.charWidth * (curStart - start), y1, curWidth,\r
-          av.charHeight);\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    public void drawText(SequenceI seq, int start, int end, int y1)\r
-    {\r
-      y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady\r
-      int charOffset = 0;\r
-      char s;\r
-\r
-        if(end+1>=seq.getLength())\r
-          end = seq.getLength()-1;\r
-        graphics.setColor(Color.black);\r
-\r
-\r
-        if(monospacedFont && av.showText && allGroups.length==0 && !av.getColourText())\r
-        {\r
-          graphics.drawString(seq.getSequence(start, end + 1), 0, y1);\r
-        }\r
-        else\r
-        {\r
-          for (int i = start; i <= end; i++)\r
-          {\r
-            graphics.setColor(Color.black);\r
-            s = seq.getCharAt(i);\r
-            if (!renderGaps && jalview.util.Comparison.isGap(s))\r
-            {\r
-              continue;\r
-            }\r
-\r
-            if (inCurrentSequenceGroup(i))\r
-            {\r
-              if (!currentSequenceGroup.getDisplayText())\r
-              {\r
-                continue;\r
-              }\r
-\r
-              if (currentSequenceGroup.getColourText())\r
-              {\r
-                getBoxColour(currentSequenceGroup.cs, seq, i);\r
-                graphics.setColor(resBoxColour.darker());\r
-              }\r
-            }\r
-            else\r
-            {\r
-              if (!av.getShowText())\r
-              {\r
-                continue;\r
-              }\r
-\r
-              if (av.getColourText())\r
-              {\r
-                getBoxColour(av.globalColourScheme, seq, i);\r
-\r
-                if (av.getShowBoxes())\r
-                {\r
-                  graphics.setColor(resBoxColour.darker());\r
-                }\r
-                else\r
-                {\r
-                  graphics.setColor(resBoxColour);\r
-                }\r
-              }\r
-            }\r
-\r
-            charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
-\r
-          //  System.out.print(s);\r
-            graphics.drawString(String.valueOf(s),\r
-                                charOffset + av.charWidth * (i - start),\r
-                                y1);\r
-\r
-          }\r
-        //  System.out.println("\n");\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param res DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    boolean inCurrentSequenceGroup(int res)\r
-    {\r
-        if (allGroups == null)\r
-        {\r
-            return false;\r
-        }\r
-\r
-        for (int i = 0; i < allGroups.length; i++)\r
-        {\r
-            if ((allGroups[i].getStartRes() <= res) &&\r
-                    (allGroups[i].getEndRes() >= res))\r
-            {\r
-                currentSequenceGroup = allGroups[i];\r
-\r
-                return true;\r
-            }\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     * @param start DOCUMENT ME!\r
-     * @param end DOCUMENT ME!\r
-     * @param x1 DOCUMENT ME!\r
-     * @param y1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1)\r
-    {\r
-        int pady = av.charHeight / 5;\r
-        int charOffset = 0;\r
-        graphics.setColor(Color.BLACK);\r
-        graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), av.charHeight);\r
-        graphics.setColor(Color.white);\r
-\r
-        char s = '~';\r
-\r
-        // Need to find the sequence position here.\r
-        for (int i = start; i <= end; i++)\r
-        {\r
-            if (i < seq.getLength())\r
-            {\r
-                s = seq.getSequence().charAt(i);\r
-            }\r
-\r
-            charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
-            graphics.drawString(String.valueOf(s),\r
-                charOffset + x1 + (av.charWidth * (i - start)),\r
-                (y1 + av.charHeight) - pady);\r
-        }\r
-    }\r
-\r
-    public void drawCursor(SequenceI seq, int res, int x1, int y1)\r
-    {\r
-      int pady = av.charHeight / 5;\r
-      int charOffset = 0;\r
-      graphics.setColor(Color.lightGray);\r
-      graphics.fillRect(x1, y1, av.charWidth, av.charHeight);\r
-      graphics.setColor(Color.white);\r
-\r
-      graphics.setColor(Color.white);\r
-\r
-      char s = seq.getCharAt(res);\r
-\r
-      charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
-      graphics.drawString(String.valueOf(s),\r
-                charOffset + x1,\r
-                (y1 + av.charHeight) - pady);\r
-\r
-\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SequenceRenderer
+{
+    AlignViewport av;
+    FontMetrics fm;
+    boolean renderGaps = true;
+    SequenceGroup currentSequenceGroup = null;
+    SequenceGroup[] allGroups = null;
+    Color resBoxColour;
+    Graphics graphics;
+    boolean monospacedFont;
+    boolean forOverview = false;
+
+    /**
+     * Creates a new SequenceRenderer object.
+     *
+     * @param av DOCUMENT ME!
+     */
+    public SequenceRenderer(AlignViewport av)
+    {
+        this.av = av;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void prepare(Graphics g, boolean renderGaps)
+    {
+        graphics = g;
+        fm = g.getFontMetrics();
+
+        // If EPS graphics, stringWidth will be a double, not an int
+        double dwidth = fm.getStringBounds("M", g).getWidth();
+
+        monospacedFont =
+               (dwidth == fm.getStringBounds("|",g).getWidth()
+               && (float)av.charWidth == dwidth);
+
+        this.renderGaps = renderGaps;
+    }
+
+
+    public Color getResidueBoxColour(SequenceI seq, int i)
+    {
+      allGroups = av.alignment.findAllGroups(seq);
+
+      if (inCurrentSequenceGroup(i))
+      {
+        if (currentSequenceGroup.getDisplayBoxes())
+        {
+          getBoxColour(currentSequenceGroup.cs, seq, i);
+        }
+      }
+      else if (av.getShowBoxes())
+      {
+          getBoxColour(av.globalColourScheme, seq, i);
+      }
+
+      return resBoxColour;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param cs DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     * @param i DOCUMENT ME!
+     */
+    void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)
+    {
+        if (cs != null)
+        {
+            resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);
+        }
+        else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))
+        {
+            resBoxColour = Color.lightGray;
+        }
+        else
+        {
+          resBoxColour = Color.white;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param seq DOCUMENT ME!
+     * @param sg DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    public void drawSequence(SequenceI seq, SequenceGroup[] sg,
+        int start, int end, int y1)
+    {
+        allGroups = sg;
+
+        drawBoxes(seq, start, end, y1);
+
+        if (av.validCharWidth)
+          drawText(seq, start, end, y1);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    public synchronized void drawBoxes(SequenceI seq, int start, int end, int y1)
+    {
+      int i = start;
+      int length = seq.getLength();
+
+      int curStart = -1;
+      int curWidth = av.charWidth;
+
+      Color tempColour = null;
+
+      while (i <= end)
+      {
+        resBoxColour = Color.white;
+
+        if (i < length)
+        {
+          if (inCurrentSequenceGroup(i))
+          {
+            if (currentSequenceGroup.getDisplayBoxes())
+            {
+              getBoxColour(currentSequenceGroup.cs, seq, i);
+            }
+          }
+          else if (av.getShowBoxes())
+          {
+            getBoxColour(av.globalColourScheme, seq, i);
+          }
+
+        }
+
+          if (resBoxColour != tempColour)
+          {
+              if (tempColour != null)
+              {
+                  graphics.fillRect( av.charWidth * (curStart - start), y1,
+                      curWidth, av.charHeight);
+              }
+
+              graphics.setColor(resBoxColour);
+
+              curStart = i;
+              curWidth = av.charWidth;
+              tempColour = resBoxColour;
+          }
+          else
+          {
+              curWidth += av.charWidth;
+          }
+
+          i++;
+      }
+
+      graphics.fillRect( av.charWidth * (curStart - start), y1, curWidth,
+          av.charHeight);
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    public void drawText(SequenceI seq, int start, int end, int y1)
+    {
+      y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady
+      int charOffset = 0;
+      char s;
+
+        if(end+1>=seq.getLength())
+          end = seq.getLength()-1;
+        graphics.setColor(Color.black);
+
+
+        if(monospacedFont && av.showText && allGroups.length==0 && !av.getColourText())
+        {
+          if(av.renderGaps)
+          graphics.drawString(seq.getSequence(start, end + 1), 0, y1);
+         else
+         {
+           char gap = av.getGapCharacter();
+           graphics.drawString( seq.getSequence(start, end+1).replace(gap, ' '), 0, y1);
+         }
+        }
+        else
+        {
+          for (int i = start; i <= end; i++)
+          {
+            graphics.setColor(Color.black);
+            s = seq.getCharAt(i);
+            if (!renderGaps && jalview.util.Comparison.isGap(s))
+            {
+              continue;
+            }
+
+            if (inCurrentSequenceGroup(i))
+            {
+              if (!currentSequenceGroup.getDisplayText())
+              {
+                continue;
+              }
+
+              if (currentSequenceGroup.getColourText())
+              {
+                getBoxColour(currentSequenceGroup.cs, seq, i);
+                graphics.setColor(resBoxColour.darker());
+              }
+            }
+            else
+            {
+              if (!av.getShowText())
+              {
+                continue;
+              }
+
+              if (av.getColourText())
+              {
+                getBoxColour(av.globalColourScheme, seq, i);
+
+                if (av.getShowBoxes())
+                {
+                  graphics.setColor(resBoxColour.darker());
+                }
+                else
+                {
+                  graphics.setColor(resBoxColour);
+                }
+              }
+            }
+
+            charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+
+          //  System.out.print(s);
+            graphics.drawString(String.valueOf(s),
+                                charOffset + av.charWidth * (i - start),
+                                y1);
+
+          }
+        //  System.out.println("\n");
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param res DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    boolean inCurrentSequenceGroup(int res)
+    {
+        if (allGroups == null)
+        {
+            return false;
+        }
+
+        for (int i = 0; i < allGroups.length; i++)
+        {
+            if ((allGroups[i].getStartRes() <= res) &&
+                    (allGroups[i].getEndRes() >= res))
+            {
+                currentSequenceGroup = allGroups[i];
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     * @param start DOCUMENT ME!
+     * @param end DOCUMENT ME!
+     * @param x1 DOCUMENT ME!
+     * @param y1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1)
+    {
+        int pady = av.charHeight / 5;
+        int charOffset = 0;
+        graphics.setColor(Color.BLACK);
+        graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), av.charHeight);
+        graphics.setColor(Color.white);
+
+        char s = '~';
+
+        // Need to find the sequence position here.
+        if(av.validCharWidth)
+        {
+          for (int i = start; i <= end; i++)
+          {
+            if (i < seq.getLength())
+            {
+              s = seq.getSequence().charAt(i);
+            }
+
+            charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+            graphics.drawString(String.valueOf(s),
+                                charOffset + x1 + (av.charWidth * (i - start)),
+                                (y1 + av.charHeight) - pady);
+          }
+        }
+    }
+
+    public void drawCursor(SequenceI seq, int res, int x1, int y1)
+    {
+      int pady = av.charHeight / 5;
+      int charOffset = 0;
+      graphics.setColor(Color.black);
+      graphics.fillRect(x1, y1, av.charWidth, av.charHeight);
+
+      if(av.validCharWidth)
+      {
+        graphics.setColor(Color.white);
+
+        char s = seq.getCharAt(res);
+
+        charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+        graphics.drawString(String.valueOf(s),
+                            charOffset + x1,
+                            (y1 + av.charHeight) - pady);
+      }
+
+    }
+}
index b830d5d..57125c6 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.event.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-import javax.swing.event.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SliderPanel extends GSliderPanel\r
-{\r
-    static JInternalFrame conservationSlider;\r
-    static JInternalFrame PIDSlider;\r
-    AlignmentPanel ap;\r
-    boolean forConservation = true;\r
-    ColourSchemeI cs;\r
-\r
-    /**\r
-     * Creates a new SliderPanel object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     * @param value DOCUMENT ME!\r
-     * @param forConserve DOCUMENT ME!\r
-     * @param cs DOCUMENT ME!\r
-     */\r
-    public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,\r
-        ColourSchemeI cs)\r
-    {\r
-        this.ap = ap;\r
-        this.cs = cs;\r
-        forConservation = forConserve;\r
-        undoButton.setVisible(false);\r
-        applyButton.setVisible(false);\r
-\r
-        if (forConservation)\r
-        {\r
-            label.setText("Enter value to increase conservation visibility");\r
-            slider.setMinimum(0);\r
-            slider.setMaximum(100);\r
-        }\r
-        else\r
-        {\r
-            label.setText("Enter % identity above which to colour residues");\r
-            slider.setMinimum(0);\r
-            slider.setMaximum(100);\r
-        }\r
-\r
-        slider.addChangeListener(new ChangeListener()\r
-            {\r
-                public void stateChanged(ChangeEvent evt)\r
-                {\r
-                    valueField.setText(slider.getValue() + "");\r
-                    valueChanged(slider.getValue());\r
-                }\r
-            });\r
-\r
-        slider.setValue(value);\r
-        valueField.setText(value + "");\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     * @param cs DOCUMENT ME!\r
-     * @param source DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static int setConservationSlider(AlignmentPanel ap,\r
-        ColourSchemeI cs, String source)\r
-    {\r
-        SliderPanel sp = null;\r
-\r
-        if (conservationSlider == null)\r
-        {\r
-            sp = new SliderPanel(ap, cs.getConservationInc(), true, cs);\r
-            conservationSlider = new JInternalFrame();\r
-            conservationSlider.setContentPane(sp);\r
-            conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-        }\r
-        else\r
-        {\r
-            sp = (SliderPanel) conservationSlider.getContentPane();\r
-            sp.cs = cs;\r
-        }\r
-\r
-        conservationSlider.setTitle("Conservation Colour Increment  (" +\r
-            source + ")");\r
-\r
-        if (ap.av.alignment.getGroups() != null)\r
-        {\r
-            sp.setAllGroupsCheckEnabled(true);\r
-        }\r
-        else\r
-        {\r
-            sp.setAllGroupsCheckEnabled(false);\r
-        }\r
-\r
-        return sp.getValue();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public static void showConservationSlider()\r
-    {\r
-        try\r
-        {\r
-            PIDSlider.setClosed(true);\r
-            PIDSlider = null;\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-\r
-        if (!conservationSlider.isVisible())\r
-        {\r
-            Desktop.addInternalFrame(conservationSlider,\r
-                conservationSlider.getTitle(), 420, 90, false);\r
-            conservationSlider.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
-                {\r
-                    public void internalFrameClosed(\r
-                        javax.swing.event.InternalFrameEvent e)\r
-                    {\r
-                        conservationSlider = null;\r
-                    }\r
-                });\r
-            conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     * @param cs DOCUMENT ME!\r
-     * @param source DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs,\r
-        String source)\r
-    {\r
-        SliderPanel pid = null;\r
-\r
-        int threshold = cs.getThreshold();\r
-\r
-        if (PIDSlider == null)\r
-        {\r
-            pid = new SliderPanel(ap, threshold, false, cs);\r
-            PIDSlider = new JInternalFrame();\r
-            PIDSlider.setContentPane(pid);\r
-            PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-        }\r
-        else\r
-        {\r
-            pid = (SliderPanel) PIDSlider.getContentPane();\r
-            pid.cs = cs;\r
-        }\r
-\r
-        PIDSlider.setTitle("Percentage Identity Threshold (" + source + ")");\r
-\r
-        if (ap.av.alignment.getGroups() != null)\r
-        {\r
-            pid.setAllGroupsCheckEnabled(true);\r
-        }\r
-        else\r
-        {\r
-            pid.setAllGroupsCheckEnabled(false);\r
-        }\r
-\r
-        return pid.getValue();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public static void showPIDSlider()\r
-    {\r
-        try\r
-        {\r
-            conservationSlider.setClosed(true);\r
-            conservationSlider = null;\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-\r
-        if (!PIDSlider.isVisible())\r
-        {\r
-            Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), 420, 90,\r
-                false);\r
-            PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-            PIDSlider.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
-                {\r
-                    public void internalFrameClosed(\r
-                        javax.swing.event.InternalFrameEvent e)\r
-                    {\r
-                        PIDSlider = null;\r
-                    }\r
-                });\r
-            PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public void valueChanged(int i)\r
-    {\r
-        if (cs == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        ColourSchemeI toChange = null;\r
-        Vector allGroups = null;\r
-        int groupIndex = 0;\r
-\r
-        if (allGroupsCheck.isSelected())\r
-        {\r
-            allGroups = ap.av.alignment.getGroups();\r
-            groupIndex = allGroups.size() - 1;\r
-        }\r
-        else\r
-        {\r
-            toChange = cs;\r
-        }\r
-\r
-\r
-        while (groupIndex > -1)\r
-        {\r
-            if (allGroups != null)\r
-            {\r
-                toChange = ((SequenceGroup) allGroups.get(groupIndex)).cs;\r
-\r
-                if (toChange == null)\r
-                {\r
-                    groupIndex--;\r
-\r
-                    continue;\r
-                }\r
-            }\r
-\r
-            if (forConservation)\r
-            {\r
-                if (toChange.conservationApplied())\r
-                {\r
-                    toChange.setConservationInc(i);\r
-                }\r
-            }\r
-            else\r
-            {\r
-                toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus());\r
-            }\r
-\r
-            groupIndex--;\r
-        }\r
-\r
-        ap.seqPanel.seqCanvas.repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param b DOCUMENT ME!\r
-     */\r
-    public void setAllGroupsCheckEnabled(boolean b)\r
-    {\r
-        allGroupsCheck.setEnabled(b);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void valueField_actionPerformed(ActionEvent e)\r
-    {\r
-        try\r
-        {\r
-            int i = Integer.parseInt(valueField.getText());\r
-            slider.setValue(i);\r
-        }\r
-        catch (NumberFormatException ex)\r
-        {\r
-            valueField.setText(slider.getValue() + "");\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param value DOCUMENT ME!\r
-     */\r
-    public void setValue(int value)\r
-    {\r
-        slider.setValue(value);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getValue()\r
-    {\r
-        return Integer.parseInt(valueField.getText());\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.jbgui.*;
+
+import jalview.schemes.*;
+
+import java.awt.event.*;
+
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SliderPanel extends GSliderPanel
+{
+    static JInternalFrame conservationSlider;
+    static JInternalFrame PIDSlider;
+    AlignmentPanel ap;
+    boolean forConservation = true;
+    ColourSchemeI cs;
+
+    /**
+     * Creates a new SliderPanel object.
+     *
+     * @param ap DOCUMENT ME!
+     * @param value DOCUMENT ME!
+     * @param forConserve DOCUMENT ME!
+     * @param cs DOCUMENT ME!
+     */
+    public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,
+        ColourSchemeI cs)
+    {
+        this.ap = ap;
+        this.cs = cs;
+        forConservation = forConserve;
+        undoButton.setVisible(false);
+        applyButton.setVisible(false);
+
+        if (forConservation)
+        {
+            label.setText("Enter value to increase conservation visibility");
+            slider.setMinimum(0);
+            slider.setMaximum(100);
+        }
+        else
+        {
+            label.setText("Enter % identity above which to colour residues");
+            slider.setMinimum(0);
+            slider.setMaximum(100);
+        }
+
+        slider.addChangeListener(new ChangeListener()
+            {
+                public void stateChanged(ChangeEvent evt)
+                {
+                    valueField.setText(slider.getValue() + "");
+                    valueChanged(slider.getValue());
+                }
+            });
+
+        slider.setValue(value);
+        valueField.setText(value + "");
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ap DOCUMENT ME!
+     * @param cs DOCUMENT ME!
+     * @param source DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static int setConservationSlider(AlignmentPanel ap,
+        ColourSchemeI cs, String source)
+    {
+        SliderPanel sp = null;
+
+        if (conservationSlider == null)
+        {
+            sp = new SliderPanel(ap, cs.getConservationInc(), true, cs);
+            conservationSlider = new JInternalFrame();
+            conservationSlider.setContentPane(sp);
+            conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+        }
+        else
+        {
+            sp = (SliderPanel) conservationSlider.getContentPane();
+            sp.cs = cs;
+        }
+
+        conservationSlider.setTitle("Conservation Colour Increment  (" +
+            source + ")");
+
+        if (ap.av.alignment.getGroups() != null)
+        {
+            sp.setAllGroupsCheckEnabled(true);
+        }
+        else
+        {
+            sp.setAllGroupsCheckEnabled(false);
+        }
+
+        return sp.getValue();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public static void showConservationSlider()
+    {
+        try
+        {
+            PIDSlider.setClosed(true);
+            PIDSlider = null;
+        }
+        catch (Exception ex)
+        {
+        }
+
+        if (!conservationSlider.isVisible())
+        {
+            Desktop.addInternalFrame(conservationSlider,
+                conservationSlider.getTitle(), 420, 90, false);
+            conservationSlider.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+                {
+                    public void internalFrameClosed(
+                        javax.swing.event.InternalFrameEvent e)
+                    {
+                        conservationSlider = null;
+                    }
+                });
+            conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ap DOCUMENT ME!
+     * @param cs DOCUMENT ME!
+     * @param source DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs,
+        String source)
+    {
+        SliderPanel pid = null;
+
+        int threshold = cs.getThreshold();
+
+        if (PIDSlider == null)
+        {
+            pid = new SliderPanel(ap, threshold, false, cs);
+            PIDSlider = new JInternalFrame();
+            PIDSlider.setContentPane(pid);
+            PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+        }
+        else
+        {
+            pid = (SliderPanel) PIDSlider.getContentPane();
+            pid.cs = cs;
+        }
+
+        PIDSlider.setTitle("Percentage Identity Threshold (" + source + ")");
+
+        if (ap.av.alignment.getGroups() != null)
+        {
+            pid.setAllGroupsCheckEnabled(true);
+        }
+        else
+        {
+            pid.setAllGroupsCheckEnabled(false);
+        }
+
+        return pid.getValue();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public static void showPIDSlider()
+    {
+        try
+        {
+            conservationSlider.setClosed(true);
+            conservationSlider = null;
+        }
+        catch (Exception ex)
+        {
+        }
+
+        if (!PIDSlider.isVisible())
+        {
+            Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), 420, 90,
+                false);
+            PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+            PIDSlider.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+                {
+                    public void internalFrameClosed(
+                        javax.swing.event.InternalFrameEvent e)
+                    {
+                        PIDSlider = null;
+                    }
+                });
+            PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void valueChanged(int i)
+    {
+        if (cs == null)
+        {
+            return;
+        }
+
+        ColourSchemeI toChange = null;
+        Vector allGroups = null;
+        int groupIndex = 0;
+
+        if (allGroupsCheck.isSelected())
+        {
+            allGroups = ap.av.alignment.getGroups();
+            groupIndex = allGroups.size() - 1;
+        }
+        else
+        {
+            toChange = cs;
+        }
+
+
+        while (groupIndex > -1)
+        {
+            if (allGroups != null)
+            {
+                toChange = ((SequenceGroup) allGroups.get(groupIndex)).cs;
+
+                if (toChange == null)
+                {
+                    groupIndex--;
+
+                    continue;
+                }
+            }
+
+            if (forConservation)
+            {
+                if (toChange.conservationApplied())
+                {
+                    toChange.setConservationInc(i);
+                }
+            }
+            else
+            {
+                toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus());
+            }
+
+            groupIndex--;
+        }
+
+        ap.seqPanel.seqCanvas.repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param b DOCUMENT ME!
+     */
+    public void setAllGroupsCheckEnabled(boolean b)
+    {
+        allGroupsCheck.setEnabled(b);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void valueField_actionPerformed(ActionEvent e)
+    {
+        try
+        {
+            int i = Integer.parseInt(valueField.getText());
+            slider.setValue(i);
+        }
+        catch (NumberFormatException ex)
+        {
+            valueField.setText(slider.getValue() + "");
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param value DOCUMENT ME!
+     */
+    public void setValue(int value)
+    {
+        slider.setValue(value);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getValue()
+    {
+        return Integer.parseInt(valueField.getText());
+    }
+
+    public void slider_mouseReleased(MouseEvent e)
+    {
+      if (ap.overviewPanel != null)
+        ap.overviewPanel.updateOverviewImage();
+    }
+
+}
index 05f412f..d819d98 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SplashScreen extends JPanel implements Runnable\r
-{\r
-    boolean visible = true;\r
-    JInternalFrame iframe;\r
-    Image image;\r
-    int fontSize = 11;\r
-    int yoffset = 30;\r
-\r
-    /**\r
-     * Creates a new SplashScreen object.\r
-     *\r
-     * @param iframe DOCUMENT ME!\r
-     * @param i DOCUMENT ME!\r
-     */\r
-    public SplashScreen(JInternalFrame iframe, Image i)\r
-    {\r
-        this.iframe = iframe;\r
-        image = i;\r
-\r
-        Thread t = new Thread(this);\r
-        t.start();\r
-        addMouseListener(new MouseAdapter()\r
-            {\r
-                public void mousePressed(MouseEvent evt)\r
-                {\r
-                    try\r
-                    {\r
-                        closeSplash();\r
-                    }\r
-                    catch (Exception ex)\r
-                    {\r
-                    }\r
-                }\r
-            });\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void run()\r
-    {\r
-        long startTime = System.currentTimeMillis() / 1000;\r
-\r
-        while (visible)\r
-        {\r
-            if (((System.currentTimeMillis() / 1000) - startTime) > 5)\r
-            {\r
-                visible = false;\r
-            }\r
-\r
-            try\r
-            {\r
-                Thread.sleep(1000);\r
-                repaint();\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-            }\r
-        }\r
-\r
-        closeSplash();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void closeSplash()\r
-    {\r
-        try\r
-        {\r
-            iframe.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        g.setColor(Color.white);\r
-        g.fillRect(0, 0, getWidth(), getHeight());\r
-        g.setColor(Color.black);\r
-        g.setFont(new Font("Verdana", Font.BOLD, fontSize + 6));\r
-\r
-        if (image != null)\r
-        {\r
-            g.drawImage(image, 5, yoffset + 12, this);\r
-        }\r
-\r
-        int y = yoffset;\r
-\r
-        g.drawString("Jalview "+jalview.bin.Cache.getProperty("VERSION"), 50, y);\r
-\r
-        FontMetrics fm = g.getFontMetrics();\r
-        int vwidth = fm.stringWidth("Jalview "+jalview.bin.Cache.getProperty("VERSION"));\r
-        g.setFont(new Font("Verdana", Font.BOLD, fontSize + 2));\r
-        g.drawString("Last updated: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"),\r
-                     50 + vwidth +5, y);\r
-\r
-        if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals("Checking"))\r
-        {\r
-          // Displayed when code version and jnlp version do not match\r
-          g.drawString("...Checking latest version...",\r
-                       50, y += fontSize + 10);\r
-          y += 5;\r
-          g.setColor(Color.black);\r
-        }\r
-        else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(\r
-            jalview.bin.Cache.getProperty("VERSION")))\r
-        {\r
-          // Displayed when code version and jnlp version do not match\r
-          g.setColor(Color.red);\r
-          g.drawString("!! Jalview version " +\r
-                       jalview.bin.Cache.getDefault("LATEST_VERSION", "..Checking..")\r
-                       + " is available for download from http://www.jalview.org !!",\r
-                       50, y += fontSize + 10);\r
-          y += 5;\r
-          g.setColor(Color.black);\r
-        }\r
-\r
-        g.setFont(new Font("Verdana", Font.BOLD, fontSize));\r
-        g.drawString("Authors: Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",\r
-            50, y+=fontSize+4);\r
-        g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",\r
-            50,  y+=fontSize+4);\r
-        g.drawString("If  you use JalView, please cite: Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004),",\r
-            50, y+=fontSize+4);\r
-        g.drawString("\"The Jalview Java Alignment Editor\" Bioinformatics,  2004 12; 426-7.",\r
-            50, y+=fontSize+4);\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SplashScreen extends JPanel implements Runnable
+{
+    boolean visible = true;
+    JInternalFrame iframe;
+    Image image;
+    int fontSize = 11;
+    int yoffset = 30;
+
+    /**
+     * Creates a new SplashScreen object.
+     *
+     * @param iframe DOCUMENT ME!
+     * @param i DOCUMENT ME!
+     */
+    public SplashScreen(JInternalFrame iframe, Image i)
+    {
+        this.iframe = iframe;
+        image = i;
+
+        Thread t = new Thread(this);
+        t.start();
+        addMouseListener(new MouseAdapter()
+            {
+                public void mousePressed(MouseEvent evt)
+                {
+                    try
+                    {
+                        closeSplash();
+                    }
+                    catch (Exception ex)
+                    {
+                    }
+                }
+            });
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void run()
+    {
+        long startTime = System.currentTimeMillis() / 1000;
+
+        while (visible)
+        {
+            if (((System.currentTimeMillis() / 1000) - startTime) > 5)
+            {
+                visible = false;
+            }
+
+            try
+            {
+                Thread.sleep(1000);
+                repaint();
+            }
+            catch (Exception ex)
+            {
+            }
+        }
+
+        closeSplash();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void closeSplash()
+    {
+        try
+        {
+            iframe.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+        g.setColor(Color.white);
+        g.fillRect(0, 0, getWidth(), getHeight());
+        g.setColor(Color.black);
+        g.setFont(new Font("Verdana", Font.BOLD, fontSize + 6));
+
+        if (image != null)
+        {
+            g.drawImage(image, 5, yoffset + 12, this);
+        }
+
+        int y = yoffset;
+
+        g.drawString("Jalview "+jalview.bin.Cache.getProperty("VERSION"), 50, y);
+
+        FontMetrics fm = g.getFontMetrics();
+        int vwidth = fm.stringWidth("Jalview "+jalview.bin.Cache.getProperty("VERSION"));
+        g.setFont(new Font("Verdana", Font.BOLD, fontSize + 2));
+        g.drawString("Last updated: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"),
+                     50 + vwidth +5, y);
+
+        if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals("Checking"))
+        {
+          // Displayed when code version and jnlp version do not match
+          g.drawString("...Checking latest version...",
+                       50, y += fontSize + 10);
+          y += 5;
+          g.setColor(Color.black);
+        }
+        else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
+            jalview.bin.Cache.getProperty("VERSION")))
+        {
+          // Displayed when code version and jnlp version do not match
+          g.setColor(Color.red);
+          g.drawString("!! Jalview version " +
+                       jalview.bin.Cache.getDefault("LATEST_VERSION", "..Checking..")
+                       + " is available for download from http://www.jalview.org !!",
+                       50, y += fontSize + 10);
+          y += 5;
+          g.setColor(Color.black);
+        }
+
+        g.setFont(new Font("Verdana", Font.BOLD, fontSize));
+        g.drawString("Authors: Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",
+            50, y+=fontSize+4);
+        g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",
+            50,  y+=fontSize+4);
+        g.drawString("If  you use JalView, please cite: Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004),",
+            50, y+=fontSize+4);
+        g.drawString("\"The Jalview Java Alignment Editor\" Bioinformatics,  2004 20; 426-7.",
+            50, y+=fontSize+4);
+    }
+}
index b4fd746..3495a44 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import jalview.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.awt.print.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class TreeCanvas extends JPanel implements MouseListener, Runnable,\r
-    Printable\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public static final String PLACEHOLDER = " * ";\r
-    NJTree tree;\r
-    JScrollPane scrollPane;\r
-    AlignViewport av;\r
-    Font font;\r
-    FontMetrics fm;\r
-    boolean fitToWindow = true;\r
-    boolean showDistances = false;\r
-    boolean showBootstrap = false;\r
-    boolean markPlaceholders = false;\r
-    int offx = 20;\r
-    int offy;\r
-    float threshold;\r
-    String longestName;\r
-    int labelLength = -1;\r
-\r
-    //RubberbandRectangle rubberband;\r
-    Vector listeners;\r
-    Hashtable nameHash = new Hashtable();\r
-    Hashtable nodeHash = new Hashtable();\r
-\r
-    /**\r
-     * Creates a new TreeCanvas object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     * @param tree DOCUMENT ME!\r
-     * @param scroller DOCUMENT ME!\r
-     * @param label DOCUMENT ME!\r
-     */\r
-    public TreeCanvas(AlignViewport av, JScrollPane scroller)\r
-    {\r
-        this.av = av;\r
-        font = av.getFont();\r
-        scrollPane = scroller;\r
-        addMouseListener(this);\r
-        PaintRefresher.Register(this, av.alignment);\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param sequence DOCUMENT ME!\r
-     */\r
-    public void TreeSelectionChanged(Sequence sequence)\r
-    {\r
-        SequenceGroup selected = av.getSelectionGroup();\r
-\r
-        if (selected == null)\r
-        {\r
-            selected = new SequenceGroup();\r
-            av.setSelectionGroup(selected);\r
-        }\r
-\r
-        selected.setEndRes(av.alignment.getWidth()-1);\r
-        selected.addOrRemove(sequence, true);\r
-\r
-        PaintRefresher.Refresh(this, av.alignment);\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param tree DOCUMENT ME!\r
-     */\r
-    public void setTree(NJTree tree)\r
-    {\r
-        this.tree = tree;\r
-        tree.findHeight(tree.getTopNode());\r
-\r
-        // Now have to calculate longest name based on the leaves\r
-        Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());\r
-        boolean has_placeholders = false;\r
-        longestName = "";\r
-\r
-        for (int i = 0; i < leaves.size(); i++)\r
-        {\r
-          SequenceNode lf = (SequenceNode) leaves.elementAt(i);\r
-\r
-          if (lf.isPlaceholder())\r
-          {\r
-            has_placeholders = true;\r
-          }\r
-\r
-          if (longestName.length() < ( (Sequence) lf.element()).getName()\r
-              .length())\r
-          {\r
-            longestName = TreeCanvas.PLACEHOLDER +\r
-                ( (Sequence) lf.element()).getName();\r
-          }\r
-        }\r
-\r
-        setMarkPlaceholders(has_placeholders);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     * @param node DOCUMENT ME!\r
-     * @param chunk DOCUMENT ME!\r
-     * @param scale DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param offx DOCUMENT ME!\r
-     * @param offy DOCUMENT ME!\r
-     */\r
-    public void drawNode(Graphics g, SequenceNode node, float chunk,\r
-        float scale, int width, int offx, int offy)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            // Drawing leaf node\r
-            float height = node.height;\r
-            float dist = node.dist;\r
-\r
-            int xstart = (int) ((height - dist) * scale) + offx;\r
-            int xend = (int) (height * scale) + offx;\r
-\r
-            int ypos = (int) (node.ycount * chunk) + offy;\r
-\r
-            if (node.element() instanceof SequenceI)\r
-            {\r
-                if (((SequenceI) ((SequenceNode) node).element()).getColor() == Color.white)\r
-                {\r
-                    g.setColor(Color.black);\r
-                }\r
-                else\r
-                {\r
-                    g.setColor(((SequenceI) ((SequenceNode) node).element()).getColor()\r
-                                .darker());\r
-                }\r
-            }\r
-            else\r
-            {\r
-                g.setColor(Color.black);\r
-            }\r
-\r
-            // Draw horizontal line\r
-            g.drawLine(xstart, ypos, xend, ypos);\r
-\r
-            String nodeLabel = "";\r
-\r
-            if (showDistances && (node.dist > 0))\r
-            {\r
-                nodeLabel = new Format("%-.2f").form(node.dist);\r
-            }\r
-\r
-            if (showBootstrap)\r
-            {\r
-                if (showDistances)\r
-                {\r
-                    nodeLabel = nodeLabel + " : ";\r
-                }\r
-\r
-                nodeLabel = nodeLabel + String.valueOf(node.getBootstrap());\r
-            }\r
-\r
-            if (!nodeLabel.equals(""))\r
-            {\r
-                g.drawString(nodeLabel, xstart+2, ypos - 2);\r
-            }\r
-\r
-            String name = (markPlaceholders && node.isPlaceholder())\r
-                ? (PLACEHOLDER + node.getName()) : node.getName();\r
-\r
-            int charWidth = fm.stringWidth(name) + 3;\r
-            int charHeight = font.getSize();\r
-\r
-            Rectangle rect = new Rectangle(xend+10, ypos-charHeight/2,\r
-                    charWidth, charHeight);\r
-\r
-            nameHash.put((SequenceI) node.element(), rect);\r
-\r
-            // Colour selected leaves differently\r
-            SequenceGroup selected = av.getSelectionGroup();\r
-\r
-            if ((selected != null) &&\r
-                    selected.sequences.contains((SequenceI) node.element()))\r
-            {\r
-                g.setColor(Color.gray);\r
-\r
-                g.fillRect(xend + 10, ypos-charHeight/2, charWidth,\r
-                    charHeight);\r
-                g.setColor(Color.white);\r
-            }\r
-\r
-            g.drawString(name, xend + 10, ypos+fm.getDescent());\r
-            g.setColor(Color.black);\r
-        }\r
-        else\r
-        {\r
-            drawNode(g, (SequenceNode) node.left(), chunk, scale, width, offx,\r
-                offy);\r
-            drawNode(g, (SequenceNode) node.right(), chunk, scale, width, offx,\r
-                offy);\r
-\r
-            float height = node.height;\r
-            float dist = node.dist;\r
-\r
-            int xstart = (int) ((height - dist) * scale) + offx;\r
-            int xend = (int) (height * scale) + offx;\r
-            int ypos = (int) (node.ycount * chunk) + offy;\r
-\r
-            g.setColor(((SequenceNode) node).color.darker());\r
-\r
-            // Draw horizontal line\r
-            g.drawLine(xstart, ypos, xend, ypos);\r
-            g.fillRect(xend - 2, ypos - 2, 4, 4);\r
-\r
-            int ystart = (int) (((SequenceNode) node.left()).ycount * chunk) +\r
-                offy;\r
-            int yend = (int) (((SequenceNode) node.right()).ycount * chunk) +\r
-                offy;\r
-\r
-            Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);\r
-            nodeHash.put(node, pos);\r
-\r
-            g.drawLine((int) (height * scale) + offx, ystart,\r
-                (int) (height * scale) + offx, yend);\r
-\r
-            if (showDistances && (node.dist > 0))\r
-            {\r
-                g.drawString(new Format("%-.2f").form(node.dist).trim(), xstart+2,\r
-                    ypos - 2);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param x DOCUMENT ME!\r
-     * @param y DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Object findElement(int x, int y)\r
-    {\r
-        Enumeration keys = nameHash.keys();\r
-\r
-        while (keys.hasMoreElements())\r
-        {\r
-            Object ob = keys.nextElement();\r
-            Rectangle rect = (Rectangle) nameHash.get(ob);\r
-\r
-            if ((x >= rect.x) && (x <= (rect.x + rect.width)) && (y >= rect.y) &&\r
-                    (y <= (rect.y + rect.height)))\r
-            {\r
-                return ob;\r
-            }\r
-        }\r
-\r
-        keys = nodeHash.keys();\r
-\r
-        while (keys.hasMoreElements())\r
-        {\r
-            Object ob = keys.nextElement();\r
-            Rectangle rect = (Rectangle) nodeHash.get(ob);\r
-\r
-            if ((x >= rect.x) && (x <= (rect.x + rect.width)) && (y >= rect.y) &&\r
-                    (y <= (rect.y + rect.height)))\r
-            {\r
-                return ob;\r
-            }\r
-        }\r
-\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param pickBox DOCUMENT ME!\r
-     */\r
-    public void pickNodes(Rectangle pickBox)\r
-    {\r
-        int width = getWidth();\r
-        int height = getHeight();\r
-\r
-        SequenceNode top = tree.getTopNode();\r
-\r
-        float wscale = (float) ((width * .8) - (offx * 2)) / tree.getMaxHeight();\r
-\r
-        if (top.count == 0)\r
-        {\r
-            top.count = ((SequenceNode) top.left()).count +\r
-                ((SequenceNode) top.right()).count;\r
-        }\r
-\r
-        float chunk = (float) (height - (offy)) / top.count;\r
-\r
-        pickNode(pickBox, top, chunk, wscale, width, offx, offy);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param pickBox DOCUMENT ME!\r
-     * @param node DOCUMENT ME!\r
-     * @param chunk DOCUMENT ME!\r
-     * @param scale DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param offx DOCUMENT ME!\r
-     * @param offy DOCUMENT ME!\r
-     */\r
-    public void pickNode(Rectangle pickBox, SequenceNode node, float chunk,\r
-        float scale, int width, int offx, int offy)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            float height = node.height;\r
-            float dist = node.dist;\r
-\r
-            int xstart = (int) ((height - dist) * scale) + offx;\r
-            int xend = (int) (height * scale) + offx;\r
-\r
-            int ypos = (int) (node.ycount * chunk) + offy;\r
-\r
-            if (pickBox.contains(new Point(xend, ypos)))\r
-            {\r
-                if (node.element() instanceof SequenceI)\r
-                {\r
-                    SequenceI seq = (SequenceI) node.element();\r
-                    SequenceGroup sg = av.getSelectionGroup();\r
-\r
-                    if (sg != null)\r
-                    {\r
-                        sg.addOrRemove(seq, true);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        else\r
-        {\r
-            pickNode(pickBox, (SequenceNode) node.left(), chunk, scale, width,\r
-                offx, offy);\r
-            pickNode(pickBox, (SequenceNode) node.right(), chunk, scale, width,\r
-                offx, offy);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param node DOCUMENT ME!\r
-     * @param c DOCUMENT ME!\r
-     */\r
-    public void setColor(SequenceNode node, Color c)\r
-    {\r
-        if (node == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        if ((node.left() == null) && (node.right() == null))\r
-        {\r
-            node.color = c;\r
-\r
-            if (node.element() instanceof SequenceI)\r
-            {\r
-                ((SequenceI) node.element()).setColor(c);\r
-            }\r
-        }\r
-        else\r
-        {\r
-            node.color = c;\r
-            setColor((SequenceNode) node.left(), c);\r
-            setColor((SequenceNode) node.right(), c);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    void startPrinting()\r
-    {\r
-        Thread thread = new Thread(this);\r
-        thread.start();\r
-    }\r
-\r
-    // put printing in a thread to avoid painting problems\r
-    public void run()\r
-    {\r
-        PrinterJob printJob = PrinterJob.getPrinterJob();\r
-        PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
-\r
-        printJob.setPrintable(this, pf);\r
-\r
-        if (printJob.printDialog())\r
-        {\r
-            try\r
-            {\r
-                printJob.print();\r
-            }\r
-            catch (Exception PrintException)\r
-            {\r
-                PrintException.printStackTrace();\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param pg DOCUMENT ME!\r
-     * @param pf DOCUMENT ME!\r
-     * @param pi DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     *\r
-     * @throws PrinterException DOCUMENT ME!\r
-     */\r
-    public int print(Graphics pg, PageFormat pf, int pi)\r
-        throws PrinterException\r
-    {\r
-        pg.setFont(font);\r
-        pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());\r
-\r
-        int pwidth = (int) pf.getImageableWidth();\r
-        int pheight = (int) pf.getImageableHeight();\r
-\r
-        int noPages = getHeight() / pheight;\r
-\r
-        if (pi > noPages)\r
-        {\r
-            return Printable.NO_SUCH_PAGE;\r
-        }\r
-\r
-        if (pwidth > getWidth())\r
-        {\r
-            pwidth = getWidth();\r
-        }\r
-\r
-        if (fitToWindow)\r
-        {\r
-            if (pheight > getHeight())\r
-            {\r
-                pheight = getHeight();\r
-            }\r
-\r
-            noPages = 0;\r
-        }\r
-        else\r
-        {\r
-            FontMetrics fm = pg.getFontMetrics(font);\r
-            int height = fm.getHeight() * nameHash.size();\r
-            pg.translate(0, -pi * pheight);\r
-            pg.setClip(0, pi * pheight, pwidth, (pi * pheight) + pheight);\r
-\r
-            // translate number of pages,\r
-            // height is screen size as this is the\r
-            // non overlapping text size\r
-            pheight = height;\r
-        }\r
-\r
-        draw(pg, pwidth, pheight);\r
-\r
-        return Printable.PAGE_EXISTS;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-        super.paintComponent(g);\r
-        g.setFont(font);\r
-\r
-        if(tree==null)\r
-        {\r
-          g.drawString("Calculating tree....", 20, getHeight()/2);\r
-        }\r
-        else\r
-        {\r
-          fm = g.getFontMetrics(font);\r
-\r
-          if (nameHash.size() == 0)\r
-          {\r
-            repaint();\r
-          }\r
-\r
-          if (fitToWindow ||\r
-              (!fitToWindow &&\r
-               (scrollPane.getHeight() > ( (fm.getHeight() * nameHash.size()) +\r
-                                          offy))))\r
-          {\r
-            draw(g, scrollPane.getWidth(), scrollPane.getHeight());\r
-            setPreferredSize(null);\r
-          }\r
-          else\r
-          {\r
-            setPreferredSize(new Dimension(scrollPane.getWidth(),\r
-                                           fm.getHeight() * nameHash.size()));\r
-            draw(g, scrollPane.getWidth(), fm.getHeight() * nameHash.size());\r
-          }\r
-\r
-          scrollPane.revalidate();\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param fontSize DOCUMENT ME!\r
-     */\r
-    public void setFont(Font font)\r
-    {\r
-        this.font = font;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g1 DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    public void draw(Graphics g1, int width, int height)\r
-    {\r
-        Graphics2D g2 = (Graphics2D) g1;\r
-        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-            RenderingHints.VALUE_ANTIALIAS_ON);\r
-        g2.setColor(Color.white);\r
-        g2.fillRect(0, 0, width, height);\r
-\r
-        g2.setFont(font);\r
-\r
-        offy = font.getSize()+10;\r
-\r
-        fm = g2.getFontMetrics(font);\r
-\r
-        labelLength = fm.stringWidth(longestName) + 20; //20 allows for scrollbar\r
-\r
-        float wscale = (float) (width - labelLength - (offx * 2)) / tree.getMaxHeight();\r
-\r
-        SequenceNode top = tree.getTopNode();\r
-\r
-        if (top.count == 0)\r
-        {\r
-            top.count = ((SequenceNode) top.left()).count +\r
-                ((SequenceNode) top.right()).count;\r
-        }\r
-\r
-        float chunk = (float) (height - (offy)) / top.count;\r
-\r
-        drawNode(g2, tree.getTopNode(), chunk, wscale, width, offx, offy);\r
-\r
-        if (threshold != 0)\r
-        {\r
-            if (av.getCurrentTree() == tree)\r
-            {\r
-                g2.setColor(Color.red);\r
-            }\r
-            else\r
-            {\r
-                g2.setColor(Color.gray);\r
-            }\r
-\r
-            int x = (int) ((threshold * (float) (getWidth() - labelLength -\r
-                (2 * offx))) + offx);\r
-\r
-            g2.drawLine(x, 0, x, getHeight());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseReleased(MouseEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseEntered(MouseEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseExited(MouseEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mouseClicked(MouseEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void mousePressed(MouseEvent e)\r
-    {\r
-        av.setCurrentTree(tree);\r
-\r
-        int x = e.getX();\r
-        int y = e.getY();\r
-\r
-        Object ob = findElement(x, y);\r
-\r
-        if (ob instanceof SequenceI)\r
-        {\r
-            TreeSelectionChanged((Sequence) ob);\r
-            repaint();\r
-\r
-            return;\r
-        }\r
-        else if (ob instanceof SequenceNode)\r
-        {\r
-            SequenceNode tmpnode = (SequenceNode) ob;\r
-            tree.swapNodes(tmpnode);\r
-            tree.reCount(tree.getTopNode());\r
-            tree.findHeight(tree.getTopNode());\r
-        }\r
-        else\r
-        {\r
-            // Find threshold\r
-            if (tree.getMaxHeight() != 0)\r
-            {\r
-                threshold = (float) (x - offx) / (float) (getWidth() -\r
-                    labelLength - (2 * offx));\r
-\r
-                tree.getGroups().removeAllElements();\r
-                tree.groupNodes(tree.getTopNode(), threshold);\r
-                setColor(tree.getTopNode(), Color.black);\r
-\r
-                av.setSelectionGroup(null);\r
-                av.alignment.deleteAllGroups();\r
-\r
-                for (int i = 0; i < tree.getGroups().size(); i++)\r
-                {\r
-                    Color col = new Color((int) (Math.random() * 255),\r
-                            (int) (Math.random() * 255),\r
-                            (int) (Math.random() * 255));\r
-                    setColor((SequenceNode) tree.getGroups().elementAt(i),\r
-                        col.brighter());\r
-\r
-                    Vector l = tree.findLeaves((SequenceNode) tree.getGroups()\r
-                                                                  .elementAt(i),\r
-                            new Vector());\r
-\r
-                    Vector sequences = new Vector();\r
-\r
-                    for (int j = 0; j < l.size(); j++)\r
-                    {\r
-                        SequenceI s1 = (SequenceI) ((SequenceNode) l.elementAt(j)).element();\r
-\r
-                        if (!sequences.contains(s1))\r
-                        {\r
-                            sequences.addElement(s1);\r
-                        }\r
-                    }\r
-\r
-                    ColourSchemeI cs = null;\r
-\r
-                    if (av.getGlobalColourScheme() != null)\r
-                    {\r
-                      if (av.getGlobalColourScheme() instanceof UserColourScheme)\r
-                      {\r
-                        cs = new UserColourScheme(\r
-                            ( (UserColourScheme) av.getGlobalColourScheme()).getColours());\r
-\r
-                      }\r
-                      else\r
-                        cs = ColourSchemeProperty.getColour(sequences,\r
-                                                            av.alignment.getWidth(),\r
-                                                            ColourSchemeProperty.getColourName(\r
-                                                                av.getGlobalColourScheme()));\r
-\r
-                        cs.setThreshold(av.getGlobalColourScheme().getThreshold(),\r
-                                                             av.getIgnoreGapsConsensus());\r
-                    }\r
-\r
-\r
-                    SequenceGroup sg = new SequenceGroup(sequences,\r
-                            "TreeGroup", cs, true, true, false, 0,\r
-                            av.alignment.getWidth());\r
-\r
-\r
-                    if (  av.getGlobalColourScheme()!=null\r
-                       && av.getGlobalColourScheme().conservationApplied())\r
-                    {\r
-                        Conservation c = new Conservation("Group",\r
-                                ResidueProperties.propHash, 3, sg.sequences,\r
-                                sg.getStartRes(), sg.getEndRes());\r
-\r
-                        c.calculate();\r
-                        c.verdict(false, av.ConsPercGaps);\r
-                        sg.cs.setConservation(c);\r
-                    }\r
-\r
-                    av.alignment.addGroup(sg);\r
-                }\r
-            }\r
-        }\r
-\r
-        PaintRefresher.Refresh(this, av.alignment);\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setShowDistances(boolean state)\r
-    {\r
-        this.showDistances = state;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setShowBootstrap(boolean state)\r
-    {\r
-        this.showBootstrap = state;\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param state DOCUMENT ME!\r
-     */\r
-    public void setMarkPlaceholders(boolean state)\r
-    {\r
-        this.markPlaceholders = state;\r
-        repaint();\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.analysis.*;
+
+import jalview.datamodel.*;
+
+import jalview.schemes.*;
+
+import jalview.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.print.*;
+
+import java.util.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class TreeCanvas extends JPanel implements MouseListener, Runnable,
+    Printable
+{
+    /** DOCUMENT ME!! */
+    public static final String PLACEHOLDER = " * ";
+    NJTree tree;
+    JScrollPane scrollPane;
+    AlignViewport av;
+    Font font;
+    FontMetrics fm;
+    boolean fitToWindow = true;
+    boolean showDistances = false;
+    boolean showBootstrap = false;
+    boolean markPlaceholders = false;
+    int offx = 20;
+    int offy;
+    float threshold;
+    String longestName;
+    int labelLength = -1;
+
+    //RubberbandRectangle rubberband;
+    Vector listeners;
+    Hashtable nameHash = new Hashtable();
+    Hashtable nodeHash = new Hashtable();
+
+    /**
+     * Creates a new TreeCanvas object.
+     *
+     * @param av DOCUMENT ME!
+     * @param tree DOCUMENT ME!
+     * @param scroller DOCUMENT ME!
+     * @param label DOCUMENT ME!
+     */
+    public TreeCanvas(AlignViewport av, JScrollPane scroller)
+    {
+        this.av = av;
+        font = av.getFont();
+        scrollPane = scroller;
+        addMouseListener(this);
+        PaintRefresher.Register(this, av.alignment);
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param sequence DOCUMENT ME!
+     */
+    public void TreeSelectionChanged(Sequence sequence)
+    {
+        SequenceGroup selected = av.getSelectionGroup();
+
+        if (selected == null)
+        {
+            selected = new SequenceGroup();
+            av.setSelectionGroup(selected);
+        }
+
+        selected.setEndRes(av.alignment.getWidth()-1);
+        selected.addOrRemove(sequence, true);
+
+        PaintRefresher.Refresh(this, av.alignment);
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param tree DOCUMENT ME!
+     */
+    public void setTree(NJTree tree)
+    {
+        this.tree = tree;
+        tree.findHeight(tree.getTopNode());
+
+        // Now have to calculate longest name based on the leaves
+        Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());
+        boolean has_placeholders = false;
+        longestName = "";
+
+        for (int i = 0; i < leaves.size(); i++)
+        {
+          SequenceNode lf = (SequenceNode) leaves.elementAt(i);
+
+          if (lf.isPlaceholder())
+          {
+            has_placeholders = true;
+          }
+
+          if (longestName.length() < ( (Sequence) lf.element()).getName()
+              .length())
+          {
+            longestName = TreeCanvas.PLACEHOLDER +
+                ( (Sequence) lf.element()).getName();
+          }
+        }
+
+        setMarkPlaceholders(has_placeholders);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     * @param node DOCUMENT ME!
+     * @param chunk DOCUMENT ME!
+     * @param scale DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param offx DOCUMENT ME!
+     * @param offy DOCUMENT ME!
+     */
+    public void drawNode(Graphics g, SequenceNode node, float chunk,
+        float scale, int width, int offx, int offy)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            // Drawing leaf node
+            float height = node.height;
+            float dist = node.dist;
+
+            int xstart = (int) ((height - dist) * scale) + offx;
+            int xend = (int) (height * scale) + offx;
+
+            int ypos = (int) (node.ycount * chunk) + offy;
+
+            if (node.element() instanceof SequenceI)
+            {
+                if (((SequenceI) ((SequenceNode) node).element()).getColor() == Color.white)
+                {
+                    g.setColor(Color.black);
+                }
+                else
+                {
+                    g.setColor(((SequenceI) ((SequenceNode) node).element()).getColor()
+                                .darker());
+                }
+            }
+            else
+            {
+                g.setColor(Color.black);
+            }
+
+            // Draw horizontal line
+            g.drawLine(xstart, ypos, xend, ypos);
+
+            String nodeLabel = "";
+
+            if (showDistances && (node.dist > 0))
+            {
+                nodeLabel = new Format("%-.2f").form(node.dist);
+            }
+
+            if (showBootstrap)
+            {
+                if (showDistances)
+                {
+                    nodeLabel = nodeLabel + " : ";
+                }
+
+                nodeLabel = nodeLabel + String.valueOf(node.getBootstrap());
+            }
+
+            if (!nodeLabel.equals(""))
+            {
+                g.drawString(nodeLabel, xstart+2, ypos - 2);
+            }
+
+            String name = (markPlaceholders && node.isPlaceholder())
+                ? (PLACEHOLDER + node.getName()) : node.getName();
+
+            int charWidth = fm.stringWidth(name) + 3;
+            int charHeight = font.getSize();
+
+            Rectangle rect = new Rectangle(xend+10, ypos-charHeight/2,
+                    charWidth, charHeight);
+
+            nameHash.put((SequenceI) node.element(), rect);
+
+            // Colour selected leaves differently
+            SequenceGroup selected = av.getSelectionGroup();
+
+            if ((selected != null) &&
+                    selected.getSequences(false).contains((SequenceI) node.element()))
+            {
+                g.setColor(Color.gray);
+
+                g.fillRect(xend + 10, ypos-charHeight/2, charWidth,
+                    charHeight);
+                g.setColor(Color.white);
+            }
+
+            g.drawString(name, xend + 10, ypos+fm.getDescent());
+            g.setColor(Color.black);
+        }
+        else
+        {
+            drawNode(g, (SequenceNode) node.left(), chunk, scale, width, offx,
+                offy);
+            drawNode(g, (SequenceNode) node.right(), chunk, scale, width, offx,
+                offy);
+
+            float height = node.height;
+            float dist = node.dist;
+
+            int xstart = (int) ((height - dist) * scale) + offx;
+            int xend = (int) (height * scale) + offx;
+            int ypos = (int) (node.ycount * chunk) + offy;
+
+            g.setColor(((SequenceNode) node).color.darker());
+
+            // Draw horizontal line
+            g.drawLine(xstart, ypos, xend, ypos);
+            g.fillRect(xend - 2, ypos - 2, 4, 4);
+
+            int ystart = (int) (((SequenceNode) node.left()).ycount * chunk) +
+                offy;
+            int yend = (int) (((SequenceNode) node.right()).ycount * chunk) +
+                offy;
+
+            Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
+            nodeHash.put(node, pos);
+
+            g.drawLine((int) (height * scale) + offx, ystart,
+                (int) (height * scale) + offx, yend);
+
+            if (showDistances && (node.dist > 0))
+            {
+                g.drawString(new Format("%-.2f").form(node.dist).trim(), xstart+2,
+                    ypos - 2);
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param x DOCUMENT ME!
+     * @param y DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Object findElement(int x, int y)
+    {
+        Enumeration keys = nameHash.keys();
+
+        while (keys.hasMoreElements())
+        {
+            Object ob = keys.nextElement();
+            Rectangle rect = (Rectangle) nameHash.get(ob);
+
+            if ((x >= rect.x) && (x <= (rect.x + rect.width)) && (y >= rect.y) &&
+                    (y <= (rect.y + rect.height)))
+            {
+                return ob;
+            }
+        }
+
+        keys = nodeHash.keys();
+
+        while (keys.hasMoreElements())
+        {
+            Object ob = keys.nextElement();
+            Rectangle rect = (Rectangle) nodeHash.get(ob);
+
+            if ((x >= rect.x) && (x <= (rect.x + rect.width)) && (y >= rect.y) &&
+                    (y <= (rect.y + rect.height)))
+            {
+                return ob;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pickBox DOCUMENT ME!
+     */
+    public void pickNodes(Rectangle pickBox)
+    {
+        int width = getWidth();
+        int height = getHeight();
+
+        SequenceNode top = tree.getTopNode();
+
+        float wscale = (float) ((width * .8) - (offx * 2)) / tree.getMaxHeight();
+
+        if (top.count == 0)
+        {
+            top.count = ((SequenceNode) top.left()).count +
+                ((SequenceNode) top.right()).count;
+        }
+
+        float chunk = (float) (height - (offy)) / top.count;
+
+        pickNode(pickBox, top, chunk, wscale, width, offx, offy);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pickBox DOCUMENT ME!
+     * @param node DOCUMENT ME!
+     * @param chunk DOCUMENT ME!
+     * @param scale DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param offx DOCUMENT ME!
+     * @param offy DOCUMENT ME!
+     */
+    public void pickNode(Rectangle pickBox, SequenceNode node, float chunk,
+        float scale, int width, int offx, int offy)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            float height = node.height;
+            float dist = node.dist;
+
+            int xstart = (int) ((height - dist) * scale) + offx;
+            int xend = (int) (height * scale) + offx;
+
+            int ypos = (int) (node.ycount * chunk) + offy;
+
+            if (pickBox.contains(new Point(xend, ypos)))
+            {
+                if (node.element() instanceof SequenceI)
+                {
+                    SequenceI seq = (SequenceI) node.element();
+                    SequenceGroup sg = av.getSelectionGroup();
+
+                    if (sg != null)
+                    {
+                        sg.addOrRemove(seq, true);
+                    }
+                }
+            }
+        }
+        else
+        {
+            pickNode(pickBox, (SequenceNode) node.left(), chunk, scale, width,
+                offx, offy);
+            pickNode(pickBox, (SequenceNode) node.right(), chunk, scale, width,
+                offx, offy);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param node DOCUMENT ME!
+     * @param c DOCUMENT ME!
+     */
+    public void setColor(SequenceNode node, Color c)
+    {
+        if (node == null)
+        {
+            return;
+        }
+
+        if ((node.left() == null) && (node.right() == null))
+        {
+            node.color = c;
+
+            if (node.element() instanceof SequenceI)
+            {
+                ((SequenceI) node.element()).setColor(c);
+            }
+        }
+        else
+        {
+            node.color = c;
+            setColor((SequenceNode) node.left(), c);
+            setColor((SequenceNode) node.right(), c);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    void startPrinting()
+    {
+        Thread thread = new Thread(this);
+        thread.start();
+    }
+
+    // put printing in a thread to avoid painting problems
+    public void run()
+    {
+        PrinterJob printJob = PrinterJob.getPrinterJob();
+        PageFormat pf = printJob.pageDialog(printJob.defaultPage());
+
+        printJob.setPrintable(this, pf);
+
+        if (printJob.printDialog())
+        {
+            try
+            {
+                printJob.print();
+            }
+            catch (Exception PrintException)
+            {
+                PrintException.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pg DOCUMENT ME!
+     * @param pf DOCUMENT ME!
+     * @param pi DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     *
+     * @throws PrinterException DOCUMENT ME!
+     */
+    public int print(Graphics pg, PageFormat pf, int pi)
+        throws PrinterException
+    {
+        pg.setFont(font);
+        pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());
+
+        int pwidth = (int) pf.getImageableWidth();
+        int pheight = (int) pf.getImageableHeight();
+
+        int noPages = getHeight() / pheight;
+
+        if (pi > noPages)
+        {
+            return Printable.NO_SUCH_PAGE;
+        }
+
+        if (pwidth > getWidth())
+        {
+            pwidth = getWidth();
+        }
+
+        if (fitToWindow)
+        {
+            if (pheight > getHeight())
+            {
+                pheight = getHeight();
+            }
+
+            noPages = 0;
+        }
+        else
+        {
+            FontMetrics fm = pg.getFontMetrics(font);
+            int height = fm.getHeight() * nameHash.size();
+            pg.translate(0, -pi * pheight);
+            pg.setClip(0, pi * pheight, pwidth, (pi * pheight) + pheight);
+
+            // translate number of pages,
+            // height is screen size as this is the
+            // non overlapping text size
+            pheight = height;
+        }
+
+        draw(pg, pwidth, pheight);
+
+        return Printable.PAGE_EXISTS;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g DOCUMENT ME!
+     */
+    public void paintComponent(Graphics g)
+    {
+        super.paintComponent(g);
+        g.setFont(font);
+
+        if(tree==null)
+        {
+          g.drawString("Calculating tree....", 20, getHeight()/2);
+        }
+        else
+        {
+          fm = g.getFontMetrics(font);
+
+          if (nameHash.size() == 0)
+          {
+            repaint();
+          }
+
+          if (fitToWindow ||
+              (!fitToWindow &&
+               (scrollPane.getHeight() > ( (fm.getHeight() * nameHash.size()) +
+                                          offy))))
+          {
+            draw(g, scrollPane.getWidth(), scrollPane.getHeight());
+            setPreferredSize(null);
+          }
+          else
+          {
+            setPreferredSize(new Dimension(scrollPane.getWidth(),
+                                           fm.getHeight() * nameHash.size()));
+            draw(g, scrollPane.getWidth(), fm.getHeight() * nameHash.size());
+          }
+
+          scrollPane.revalidate();
+        }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param fontSize DOCUMENT ME!
+     */
+    public void setFont(Font font)
+    {
+        this.font = font;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param g1 DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    public void draw(Graphics g1, int width, int height)
+    {
+        Graphics2D g2 = (Graphics2D) g1;
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+            RenderingHints.VALUE_ANTIALIAS_ON);
+        g2.setColor(Color.white);
+        g2.fillRect(0, 0, width, height);
+
+        g2.setFont(font);
+
+        offy = font.getSize()+10;
+
+        fm = g2.getFontMetrics(font);
+
+        labelLength = fm.stringWidth(longestName) + 20; //20 allows for scrollbar
+
+        float wscale = (float) (width - labelLength - (offx * 2)) / tree.getMaxHeight();
+
+        SequenceNode top = tree.getTopNode();
+
+        if (top.count == 0)
+        {
+            top.count = ((SequenceNode) top.left()).count +
+                ((SequenceNode) top.right()).count;
+        }
+
+        float chunk = (float) (height - (offy)) / top.count;
+
+        drawNode(g2, tree.getTopNode(), chunk, wscale, width, offx, offy);
+
+        if (threshold != 0)
+        {
+            if (av.getCurrentTree() == tree)
+            {
+                g2.setColor(Color.red);
+            }
+            else
+            {
+                g2.setColor(Color.gray);
+            }
+
+            int x = (int) ((threshold * (float) (getWidth() - labelLength -
+                (2 * offx))) + offx);
+
+            g2.drawLine(x, 0, x, getHeight());
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseExited(MouseEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void mousePressed(MouseEvent e)
+    {
+        av.setCurrentTree(tree);
+
+        int x = e.getX();
+        int y = e.getY();
+
+        Object ob = findElement(x, y);
+
+        if (ob instanceof SequenceI)
+        {
+            TreeSelectionChanged((Sequence) ob);
+            repaint();
+
+            return;
+        }
+        else if (ob instanceof SequenceNode)
+        {
+            SequenceNode tmpnode = (SequenceNode) ob;
+            tree.swapNodes(tmpnode);
+            tree.reCount(tree.getTopNode());
+            tree.findHeight(tree.getTopNode());
+        }
+        else
+        {
+            // Find threshold
+            if (tree.getMaxHeight() != 0)
+            {
+                threshold = (float) (x - offx) / (float) (getWidth() -
+                    labelLength - (2 * offx));
+
+                tree.getGroups().removeAllElements();
+                tree.groupNodes(tree.getTopNode(), threshold);
+                setColor(tree.getTopNode(), Color.black);
+
+                av.setSelectionGroup(null);
+                av.alignment.deleteAllGroups();
+
+                for (int i = 0; i < tree.getGroups().size(); i++)
+                {
+                    Color col = new Color((int) (Math.random() * 255),
+                            (int) (Math.random() * 255),
+                            (int) (Math.random() * 255));
+                    setColor((SequenceNode) tree.getGroups().elementAt(i),
+                        col.brighter());
+
+                    Vector l = tree.findLeaves((SequenceNode) tree.getGroups()
+                                                                  .elementAt(i),
+                            new Vector());
+
+                    Vector sequences = new Vector();
+
+                    for (int j = 0; j < l.size(); j++)
+                    {
+                        SequenceI s1 = (SequenceI) ((SequenceNode) l.elementAt(j)).element();
+
+                        if (!sequences.contains(s1))
+                        {
+                            sequences.addElement(s1);
+                        }
+                    }
+
+                    ColourSchemeI cs = null;
+
+                    if (av.getGlobalColourScheme() != null)
+                    {
+                      if (av.getGlobalColourScheme() instanceof UserColourScheme)
+                      {
+                        cs = new UserColourScheme(
+                            ( (UserColourScheme) av.getGlobalColourScheme()).getColours());
+
+                      }
+                      else
+                        cs = ColourSchemeProperty.getColour(sequences,
+                                                            av.alignment.getWidth(),
+                                                            ColourSchemeProperty.getColourName(
+                                                                av.getGlobalColourScheme()));
+
+                        cs.setThreshold(av.getGlobalColourScheme().getThreshold(),
+                                                             av.getIgnoreGapsConsensus());
+                    }
+
+
+                    SequenceGroup sg = new SequenceGroup(sequences,
+                            "TreeGroup", cs, true, true, false, 0,
+                            av.alignment.getWidth()-1);
+
+
+                    if (  av.getGlobalColourScheme()!=null
+                       && av.getGlobalColourScheme().conservationApplied())
+                    {
+                        Conservation c = new Conservation("Group",
+                                ResidueProperties.propHash, 3,
+                                sg.getSequences(false),
+                                sg.getStartRes(), sg.getEndRes());
+
+                        c.calculate();
+                        c.verdict(false, av.ConsPercGaps);
+                        sg.cs.setConservation(c);
+                    }
+
+                    av.alignment.addGroup(sg);
+                }
+            }
+        }
+
+        PaintRefresher.Refresh(this, av.alignment);
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param state DOCUMENT ME!
+     */
+    public void setShowDistances(boolean state)
+    {
+        this.showDistances = state;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param state DOCUMENT ME!
+     */
+    public void setShowBootstrap(boolean state)
+    {
+        this.showBootstrap = state;
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param state DOCUMENT ME!
+     */
+    public void setMarkPlaceholders(boolean state)
+    {
+        this.markPlaceholders = state;
+        repaint();
+    }
+}
index 9c1e42e..cc3209e 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.analysis.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.io.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import org.jibble.epsgraphics.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import java.awt.image.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.imageio.*;\r
-\r
-import java.beans.PropertyChangeEvent;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class TreePanel extends GTreePanel\r
-{\r
-    SequenceI[] seq;\r
-    String type;\r
-    String pwtype;\r
-    int start;\r
-    int end;\r
-    TreeCanvas treeCanvas;\r
-    NJTree tree;\r
-\r
-    /**\r
-     * Creates a new TreePanel object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     * @param seqVector DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     * @param pwtype DOCUMENT ME!\r
-     * @param s DOCUMENT ME!\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public TreePanel(AlignViewport av, Vector seqVector, String type,\r
-                     String pwtype, int s, int e)\r
-    {\r
-      super();\r
-      initTreePanel(av, seqVector, type, pwtype, s, e, null);\r
-\r
-      // We know this tree has distances. JBPNote TODO: prolly should add this as a userdefined default\r
-      showDistances(true);\r
-    }\r
-\r
-    /**\r
-     * Creates a new TreePanel object.\r
-     *\r
-     * @param av DOCUMENT ME!\r
-     * @param seqVector DOCUMENT ME!\r
-     * @param newtree DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     * @param pwtype DOCUMENT ME!\r
-     */\r
-    public TreePanel(AlignViewport av, Vector seqVector, NewickFile newtree,\r
-                     String type, String pwtype)\r
-    {\r
-      super();\r
-      initTreePanel(av, seqVector, type, pwtype, 0, seqVector.size(), newtree);\r
-    }\r
-\r
-    public AlignmentI getAlignment()\r
-    {\r
-      return treeCanvas.av.getAlignment();\r
-    }\r
-\r
-\r
-    void initTreePanel(AlignViewport av, Vector seqVector, String type,\r
-                       String pwtype, int s, int e, NewickFile newTree)\r
-    {\r
-\r
-      this.type = type;\r
-      this.pwtype = pwtype;\r
-\r
-      start = s;\r
-      end = e;\r
-\r
-      seq = new Sequence[seqVector.size()];\r
-      seqVector.toArray(seq);\r
-\r
-\r
-      treeCanvas = new TreeCanvas(av, scrollPane);\r
-      scrollPane.setViewportView(treeCanvas);\r
-\r
-      av.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
-      {\r
-        public void propertyChange(PropertyChangeEvent evt)\r
-        {\r
-          if (evt.getPropertyName().equals("alignment"))\r
-          {\r
-            if(tree==null)\r
-              System.out.println("tree is null");\r
-            if(evt.getNewValue()==null)\r
-              System.out.println("new value is null");\r
-\r
-            tree.UpdatePlaceHolders( (Vector) evt.getNewValue());\r
-\r
-            repaint();\r
-          }\r
-        }\r
-      });\r
-\r
-\r
-      TreeLoader tl = new TreeLoader(newTree);\r
-      tl.start();\r
-\r
-    }\r
-\r
-    class TreeLoader extends Thread\r
-    {\r
-      NewickFile newtree;\r
-\r
-      public TreeLoader(NewickFile newtree)\r
-      {\r
-        this.newtree = newtree;\r
-        if (newtree != null)\r
-        {\r
-          // Must be outside run(), as Jalview2XML tries to\r
-          // update distance/bootstrap visibility at the same time\r
-          showBootstrap(newtree.HasBootstrap());\r
-          showDistances(newtree.HasDistances());\r
-        }\r
-      }\r
-\r
-      public void run()\r
-      {\r
-        if(newtree!=null)\r
-          tree = new NJTree(seq, newtree);\r
-        else\r
-          tree = new NJTree(seq, type, pwtype, start, end);\r
-\r
-        tree.reCount(tree.getTopNode());\r
-        tree.findHeight(tree.getTopNode());\r
-        treeCanvas.setTree(tree);\r
-\r
-        treeCanvas.repaint();\r
-\r
-      }\r
-    }\r
-\r
-    public void showDistances(boolean b)\r
-    {\r
-      treeCanvas.setShowDistances(b);\r
-      distanceMenu.setSelected(b);\r
-    }\r
-\r
-    public void showBootstrap(boolean b)\r
-    {\r
-      treeCanvas.setShowBootstrap(b);\r
-      bootstrapMenu.setSelected(b);\r
-    }\r
-\r
-    public void showPlaceholders(boolean b)\r
-    {\r
-      placeholdersMenu.setState(b);\r
-      treeCanvas.setMarkPlaceholders(b);\r
-    }\r
-\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public NJTree getTree()\r
-    {\r
-        return tree;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void textbox_actionPerformed(ActionEvent e)\r
-    {\r
-        CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
-\r
-        StringBuffer buffer = new StringBuffer();\r
-\r
-        if (type.equals("AV"))\r
-        {\r
-            buffer.append("Average distance tree using ");\r
-        }\r
-        else\r
-        {\r
-            buffer.append("Neighbour joining tree using ");\r
-        }\r
-\r
-        if (pwtype.equals("BL"))\r
-        {\r
-            buffer.append("BLOSUM62");\r
-        }\r
-        else\r
-        {\r
-            buffer.append("PID");\r
-        }\r
-\r
-        Desktop.addInternalFrame(cap, buffer.toString(), 500, 100);\r
-\r
-        jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
-        cap.setText(fout.print(tree.isHasBootstrap(), tree.isHasDistances(), tree.isHasRootDistance()));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void saveAsNewick_actionPerformed(ActionEvent e)\r
-    {\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"));\r
-        chooser.setFileView(new JalviewFileView());\r
-        chooser.setDialogTitle("Save tree as newick file");\r
-        chooser.setToolTipText("Save");\r
-\r
-        int value = chooser.showSaveDialog(null);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            String choice = chooser.getSelectedFile().getPath();\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                chooser.getSelectedFile().getParent());\r
-\r
-            try\r
-            {\r
-                jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
-                String output = fout.print(tree.isHasBootstrap(), tree.isHasDistances(), tree.isHasRootDistance());\r
-                java.io.PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(\r
-                            choice));\r
-                out.println(output);\r
-                out.close();\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                ex.printStackTrace();\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void printMenu_actionPerformed(ActionEvent e)\r
-    {\r
-        //Putting in a thread avoids Swing painting problems\r
-        treeCanvas.startPrinting();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void fitToWindow_actionPerformed(ActionEvent e)\r
-    {\r
-        treeCanvas.fitToWindow = fitToWindow.isSelected();\r
-        repaint();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void font_actionPerformed(ActionEvent e)\r
-    {\r
-        if (treeCanvas == null)\r
-        {\r
-            return;\r
-        }\r
-\r
-        new FontChooser(this);\r
-    }\r
-\r
-    public Font getTreeFont()\r
-    {\r
-        return treeCanvas.font;\r
-    }\r
-\r
-    public void setTreeFont(Font font)\r
-    {\r
-      if(treeCanvas!=null)\r
-      treeCanvas.setFont(font);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void distanceMenu_actionPerformed(ActionEvent e)\r
-    {\r
-        treeCanvas.setShowDistances(distanceMenu.isSelected());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void bootstrapMenu_actionPerformed(ActionEvent e)\r
-    {\r
-        treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void placeholdersMenu_actionPerformed(ActionEvent e)\r
-    {\r
-        treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void epsTree_actionPerformed(ActionEvent e)\r
-    {\r
-      boolean accurateText = true;\r
-\r
-      String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",\r
-          "Prompt each time");\r
-\r
-    // If we need to prompt, and if the GUI is visible then\r
-    // Prompt for EPS rendering style\r
-      if (renderStyle.equalsIgnoreCase("Prompt each time")\r
-          && !\r
-          (System.getProperty("java.awt.headless") != null\r
-           && System.getProperty("java.awt.headless").equals("true")))\r
-      {\r
-        EPSOptions eps = new EPSOptions();\r
-        renderStyle = eps.getValue();\r
-\r
-        if (renderStyle==null || eps.cancelled)\r
-          return;\r
-\r
-\r
-      }\r
-\r
-      if (renderStyle.equalsIgnoreCase("text"))\r
-      {\r
-        accurateText = false;\r
-      }\r
-\r
-        int width = treeCanvas.getWidth();\r
-        int height = treeCanvas.getHeight();\r
-\r
-        try\r
-        {\r
-            jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                        "LAST_DIRECTORY"), new String[] { "eps" },\r
-                    new String[] { "Encapsulated Postscript" },\r
-                    "Encapsulated Postscript");\r
-            chooser.setFileView(new jalview.io.JalviewFileView());\r
-            chooser.setDialogTitle("Create EPS file from tree");\r
-            chooser.setToolTipText("Save");\r
-\r
-            int value = chooser.showSaveDialog(this);\r
-\r
-            if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
-            {\r
-                return;\r
-            }\r
-\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                                          chooser.getSelectedFile().getParent());\r
-\r
-            FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
-            EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,\r
-                                                 height);\r
-\r
-            pg.setAccurateTextMode(accurateText);\r
-\r
-            treeCanvas.draw(pg, width, height);\r
-\r
-            pg.flush();\r
-            pg.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void pngTree_actionPerformed(ActionEvent e)\r
-    {\r
-        int width = treeCanvas.getWidth();\r
-        int height = treeCanvas.getHeight();\r
-\r
-        try\r
-        {\r
-            jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                        "LAST_DIRECTORY"), new String[] { "png" },\r
-                    new String[] { "Portable network graphics" },\r
-                    "Portable network graphics");\r
-\r
-            chooser.setFileView(new jalview.io.JalviewFileView());\r
-            chooser.setDialogTitle("Create PNG image from tree");\r
-            chooser.setToolTipText("Save");\r
-\r
-            int value = chooser.showSaveDialog(this);\r
-\r
-            if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
-            {\r
-                return;\r
-            }\r
-\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                chooser.getSelectedFile().getParent());\r
-\r
-            FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
-\r
-            BufferedImage bi = new BufferedImage(width, height,\r
-                    BufferedImage.TYPE_INT_RGB);\r
-            Graphics png = bi.getGraphics();\r
-\r
-            treeCanvas.draw(png, width, height);\r
-\r
-            ImageIO.write(bi, "png", out);\r
-            out.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.analysis.*;
+
+import jalview.datamodel.*;
+
+import jalview.io.*;
+
+import jalview.jbgui.*;
+
+import org.jibble.epsgraphics.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+
+import java.io.*;
+
+import java.util.*;
+
+import javax.imageio.*;
+
+import java.beans.PropertyChangeEvent;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class TreePanel extends GTreePanel
+{
+    String type;
+    String pwtype;
+    TreeCanvas treeCanvas;
+    NJTree tree;
+    AlignViewport av;
+
+    /**
+     * Creates a new TreePanel object.
+     *
+     * @param av DOCUMENT ME!
+     * @param seqVector DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     * @param pwtype DOCUMENT ME!
+     * @param s DOCUMENT ME!
+     * @param e DOCUMENT ME!
+     */
+    public TreePanel(AlignViewport av, String type, String pwtype)
+    {
+      super();
+      initTreePanel(av, type, pwtype, null);
+
+      // We know this tree has distances. JBPNote TODO: prolly should add this as a userdefined default
+      // showDistances(true);
+    }
+
+    /**
+     * Creates a new TreePanel object.
+     *
+     * @param av DOCUMENT ME!
+     * @param seqVector DOCUMENT ME!
+     * @param newtree DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     * @param pwtype DOCUMENT ME!
+     */
+    public TreePanel(AlignViewport av,
+                     String type,
+                     String pwtype,
+                     NewickFile newtree)
+    {
+      super();
+      initTreePanel(av, type, pwtype, newtree);
+    }
+
+    public AlignmentI getAlignment()
+    {
+      return treeCanvas.av.getAlignment();
+    }
+
+
+    void initTreePanel(AlignViewport av, String type,  String pwtype,
+                       NewickFile newTree)
+    {
+
+      this.type = type;
+      this.pwtype = pwtype;
+
+      treeCanvas = new TreeCanvas(av, scrollPane);
+      scrollPane.setViewportView(treeCanvas);
+
+      av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
+      {
+        public void propertyChange(PropertyChangeEvent evt)
+        {
+          if (evt.getPropertyName().equals("alignment"))
+          {
+            if(tree==null)
+              System.out.println("tree is null");
+            if(evt.getNewValue()==null)
+              System.out.println("new value is null");
+
+            tree.UpdatePlaceHolders( (Vector) evt.getNewValue());
+
+            repaint();
+          }
+        }
+      });
+
+      this.av = av;
+
+
+      TreeLoader tl = new TreeLoader(newTree);
+      tl.start();
+
+    }
+
+    class TreeLoader extends Thread
+    {
+      NewickFile newtree;
+      jalview.datamodel.AlignmentView odata=null;
+      public TreeLoader(NewickFile newtree)
+      {
+        this.newtree = newtree;
+        if (newtree != null)
+        {
+          // Must be outside run(), as Jalview2XML tries to
+          // update distance/bootstrap visibility at the same time
+          showBootstrap(newtree.HasBootstrap());
+          showDistances(newtree.HasDistances());
+        }
+      }
+
+      public void run()
+      {
+
+        if(newtree!=null)
+        {
+          if (odata==null) {
+            tree = new NJTree(av.alignment.getSequencesArray(),
+                              newtree);
+          } else {
+            tree = new NJTree(av.alignment.getSequencesArray(), odata, newtree);
+          }
+          if (!tree.hasOriginalSequenceData())
+            allowOriginalSeqData(false);
+        }
+        else
+        {
+          int start, end;
+          SequenceI [] seqs;
+          AlignmentView seqStrings = av.getAlignmentView(av.getSelectionGroup()!=null);
+          if(av.getSelectionGroup()==null)
+          {
+            start = 0;
+            end = av.alignment.getWidth();
+            seqs = av.alignment.getSequencesArray();
+          }
+          else
+          {
+            start = av.getSelectionGroup().getStartRes();
+            end = av.getSelectionGroup().getEndRes()+1;
+            seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+          }
+
+          tree = new NJTree(seqs, seqStrings, type, pwtype, start, end);
+          showDistances(true);
+        }
+
+
+        tree.reCount(tree.getTopNode());
+        tree.findHeight(tree.getTopNode());
+        treeCanvas.setTree(tree);
+        treeCanvas.repaint();
+        av.setCurrentTree(tree);
+
+      }
+    }
+
+    public void showDistances(boolean b)
+    {
+      treeCanvas.setShowDistances(b);
+      distanceMenu.setSelected(b);
+    }
+
+    public void showBootstrap(boolean b)
+    {
+      treeCanvas.setShowBootstrap(b);
+      bootstrapMenu.setSelected(b);
+    }
+
+    public void showPlaceholders(boolean b)
+    {
+      placeholdersMenu.setState(b);
+      treeCanvas.setMarkPlaceholders(b);
+    }
+
+    private void allowOriginalSeqData(boolean b) {
+      originalSeqData.setVisible(b);
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public NJTree getTree()
+    {
+        return tree;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void textbox_actionPerformed(ActionEvent e)
+    {
+        CutAndPasteTransfer cap = new CutAndPasteTransfer();
+
+        StringBuffer buffer = new StringBuffer();
+
+        if (type.equals("AV"))
+        {
+            buffer.append("Average distance tree using ");
+        }
+        else
+        {
+            buffer.append("Neighbour joining tree using ");
+        }
+
+        if (pwtype.equals("BL"))
+        {
+            buffer.append("BLOSUM62");
+        }
+        else
+        {
+            buffer.append("PID");
+        }
+
+        Desktop.addInternalFrame(cap, buffer.toString(), 500, 100);
+
+        jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());
+        cap.setText(fout.print(tree.isHasBootstrap(), tree.isHasDistances(), tree.isHasRootDistance()));
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void saveAsNewick_actionPerformed(ActionEvent e)
+    {
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"));
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Save tree as newick file");
+        chooser.setToolTipText("Save");
+
+        int value = chooser.showSaveDialog(null);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            String choice = chooser.getSelectedFile().getPath();
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                chooser.getSelectedFile().getParent());
+
+            try
+            {
+                jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());
+                String output = fout.print(tree.isHasBootstrap(), tree.isHasDistances(), tree.isHasRootDistance());
+                java.io.PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
+                            choice));
+                out.println(output);
+                out.close();
+            }
+            catch (Exception ex)
+            {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void printMenu_actionPerformed(ActionEvent e)
+    {
+        //Putting in a thread avoids Swing painting problems
+        treeCanvas.startPrinting();
+    }
+
+
+    public void originalSeqData_actionPerformed(ActionEvent e)
+    {
+      if (!tree.hasOriginalSequenceData())
+      {
+        jalview.bin.Cache.log.info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
+        return;
+      }
+      // decide if av alignment is sufficiently different to original data to warrant a new window to be created
+      // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)
+      // or create a selection box around columns in alignment view
+      // test Alignment(SeqCigar[])
+      Object[] alAndColsel = tree.seqData.getAlignmentAndColumnSelection(av.
+          getGapCharacter());
+
+
+      if (alAndColsel != null && alAndColsel[0]!=null)
+       {
+         // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
+
+         Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
+         Alignment dataset = av.getAlignment().getDataset();
+         if (dataset != null)
+         {
+           al.setDataset(dataset);
+         }
+
+         if (true)
+         {
+           // make a new frame!
+           AlignFrame af = new AlignFrame(al, (ColumnSelection) alAndColsel[1]);
+
+           //>>>This is a fix for the moment, until a better solution is found!!<<<
+           // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
+
+       //           af.addSortByOrderMenuItem(ServiceName + " Ordering",
+       //                                     msaorder);
+
+           Desktop.addInternalFrame(af, "Original Data for " + this.title,
+                                    AlignFrame.NEW_WINDOW_WIDTH,
+                                    AlignFrame.NEW_WINDOW_HEIGHT);
+         }
+       }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void fitToWindow_actionPerformed(ActionEvent e)
+    {
+        treeCanvas.fitToWindow = fitToWindow.isSelected();
+        repaint();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void font_actionPerformed(ActionEvent e)
+    {
+        if (treeCanvas == null)
+        {
+            return;
+        }
+
+        new FontChooser(this);
+    }
+
+    public Font getTreeFont()
+    {
+        return treeCanvas.font;
+    }
+
+    public void setTreeFont(Font font)
+    {
+      if(treeCanvas!=null)
+      treeCanvas.setFont(font);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void distanceMenu_actionPerformed(ActionEvent e)
+    {
+        treeCanvas.setShowDistances(distanceMenu.isSelected());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void bootstrapMenu_actionPerformed(ActionEvent e)
+    {
+        treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void placeholdersMenu_actionPerformed(ActionEvent e)
+    {
+        treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void epsTree_actionPerformed(ActionEvent e)
+    {
+      boolean accurateText = true;
+
+      String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
+          "Prompt each time");
+
+    // If we need to prompt, and if the GUI is visible then
+    // Prompt for EPS rendering style
+      if (renderStyle.equalsIgnoreCase("Prompt each time")
+          && !
+          (System.getProperty("java.awt.headless") != null
+           && System.getProperty("java.awt.headless").equals("true")))
+      {
+        EPSOptions eps = new EPSOptions();
+        renderStyle = eps.getValue();
+
+        if (renderStyle==null || eps.cancelled)
+          return;
+
+
+      }
+
+      if (renderStyle.equalsIgnoreCase("text"))
+      {
+        accurateText = false;
+      }
+
+        int width = treeCanvas.getWidth();
+        int height = treeCanvas.getHeight();
+
+        try
+        {
+            jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(
+                        "LAST_DIRECTORY"), new String[] { "eps" },
+                    new String[] { "Encapsulated Postscript" },
+                    "Encapsulated Postscript");
+            chooser.setFileView(new jalview.io.JalviewFileView());
+            chooser.setDialogTitle("Create EPS file from tree");
+            chooser.setToolTipText("Save");
+
+            int value = chooser.showSaveDialog(this);
+
+            if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)
+            {
+                return;
+            }
+
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                                          chooser.getSelectedFile().getParent());
+
+            FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());
+            EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
+                                                 height);
+
+            pg.setAccurateTextMode(accurateText);
+
+            treeCanvas.draw(pg, width, height);
+
+            pg.flush();
+            pg.close();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void pngTree_actionPerformed(ActionEvent e)
+    {
+        int width = treeCanvas.getWidth();
+        int height = treeCanvas.getHeight();
+
+        try
+        {
+            jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(
+                        "LAST_DIRECTORY"), new String[] { "png" },
+                    new String[] { "Portable network graphics" },
+                    "Portable network graphics");
+
+            chooser.setFileView(new jalview.io.JalviewFileView());
+            chooser.setDialogTitle("Create PNG image from tree");
+            chooser.setToolTipText("Save");
+
+            int value = chooser.showSaveDialog(this);
+
+            if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)
+            {
+                return;
+            }
+
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                chooser.getSelectedFile().getParent());
+
+            FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());
+
+            BufferedImage bi = new BufferedImage(width, height,
+                    BufferedImage.TYPE_INT_RGB);
+            Graphics png = bi.getGraphics();
+
+            treeCanvas.draw(png, width, height);
+
+            ImageIO.write(bi, "png", out);
+            out.close();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+}
index 556ae41..a8a7756 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.io.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-import javax.swing.event.*;\r
-\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class UserDefinedColours extends GUserDefinedColours\r
-    implements ChangeListener\r
-{\r
-    AlignmentPanel ap;\r
-    SequenceGroup seqGroup;\r
-    Vector selectedButtons;\r
-    ColourSchemeI oldColourScheme;\r
-    JInternalFrame frame;\r
-    MCview.PDBCanvas pdbcanvas;\r
-\r
-    /**\r
-     * Creates a new UserDefinedColours object.\r
-     *\r
-     * @param ap DOCUMENT ME!\r
-     * @param sg DOCUMENT ME!\r
-     */\r
-    public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)\r
-    {\r
-        super();\r
-        frame = new JInternalFrame();\r
-        frame.setContentPane(this);\r
-        Desktop.addInternalFrame(frame, "User Defined Colours", 720, 370, true);\r
-\r
-        if (System.getProperty("os.name").startsWith("Mac"))\r
-        {\r
-            frame.setSize(760, 370);\r
-        }\r
-\r
-        if (sg != null)\r
-        {\r
-            frame.setTitle(frame.getTitle() + " (" + sg.getName() + ")");\r
-        }\r
-\r
-        colorChooser.getSelectionModel().addChangeListener(this);\r
-\r
-        this.ap = ap;\r
-        seqGroup = sg;\r
-\r
-        if (seqGroup != null)\r
-        {\r
-            oldColourScheme = seqGroup.cs;\r
-        }\r
-        else\r
-        {\r
-            oldColourScheme = ap.av.getGlobalColourScheme();\r
-        }\r
-\r
-        if (oldColourScheme instanceof UserColourScheme)\r
-        {\r
-              schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());\r
-        }\r
-        for (int i = 0; i < 20; i++)\r
-        {\r
-            makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +\r
-                "", ResidueProperties.aa[i]);\r
-        }\r
-\r
-        makeButton("B", "B");\r
-        makeButton("Z", "Z");\r
-        makeButton("X", "X");\r
-        makeButton("Gap", "-");\r
-    }\r
-\r
-    public UserDefinedColours(MCview.PDBCanvas pdb, ColourSchemeI oldcs)\r
-    {\r
-        super();\r
-        frame = new JInternalFrame();\r
-        frame.setContentPane(this);\r
-        Desktop.addInternalFrame(frame, "User Defined Colours", 720, 370, true);\r
-        pdbcanvas = pdb;\r
-\r
-        if (System.getProperty("os.name").startsWith("Mac"))\r
-        {\r
-            frame.setSize(760, 370);\r
-        }\r
-\r
-        colorChooser.getSelectionModel().addChangeListener(this);\r
-\r
-        oldColourScheme = oldcs;\r
-\r
-        if (oldColourScheme instanceof UserColourScheme)\r
-        {\r
-              schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());\r
-        }\r
-        for (int i = 0; i < 20; i++)\r
-        {\r
-            makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +\r
-                "", ResidueProperties.aa[i]);\r
-        }\r
-\r
-        makeButton("B", "B");\r
-        makeButton("Z", "Z");\r
-        makeButton("X", "X");\r
-        makeButton("Gap", "-");\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     */\r
-    public void stateChanged(ChangeEvent evt)\r
-    {\r
-        if (selectedButtons != null)\r
-        {\r
-          JButton button;\r
-          for(int i=0; i<selectedButtons.size(); i++)\r
-          {\r
-            button = (JButton)selectedButtons.elementAt(i);\r
-            button.setBackground(colorChooser.getColor());\r
-            button.setForeground( button.getBackground().brighter().brighter().brighter());\r
-          }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void colourButtonPressed(MouseEvent e)\r
-    {\r
-      if(selectedButtons == null)\r
-        selectedButtons = new Vector();\r
-\r
-      JButton pressed = (JButton) e.getSource();\r
-\r
-      if(e.isShiftDown())\r
-      {\r
-        JButton start, end = (JButton) e.getSource();\r
-        if(selectedButtons.size()>0)\r
-          start = (JButton)selectedButtons.elementAt(selectedButtons.size()-1);\r
-        else\r
-          start = (JButton) e.getSource();\r
-\r
-        int startIndex=0, endIndex=0;\r
-        for(int b=0; b<buttonPanel.getComponentCount(); b++)\r
-        {\r
-          if(buttonPanel.getComponent(b)==start)\r
-            startIndex = b;\r
-          if(buttonPanel.getComponent(b)==end)\r
-            endIndex = b;\r
-        }\r
-\r
-        if(startIndex > endIndex)\r
-        {\r
-          int temp = startIndex;\r
-          startIndex = endIndex;\r
-          endIndex = temp;\r
-        }\r
-\r
-        for(int b=startIndex; b<=endIndex; b++)\r
-        {\r
-          JButton button = (JButton)buttonPanel.getComponent(b);\r
-          if(!selectedButtons.contains(button))\r
-          {\r
-            button.setForeground(button.getBackground().brighter().brighter());\r
-            selectedButtons.add(button);\r
-          }\r
-        }\r
-      }\r
-      else if(!e.isControlDown())\r
-      {\r
-        for(int b=0; b<selectedButtons.size(); b++)\r
-        {\r
-          JButton button = (JButton)selectedButtons.elementAt(b);\r
-          button.setForeground(button.getBackground().darker().darker());\r
-        }\r
-        selectedButtons.clear();\r
-        pressed.setForeground( pressed.getBackground().brighter().brighter());\r
-        selectedButtons.addElement(pressed);\r
-\r
-      }\r
-      else if(e.isControlDown())\r
-      {\r
-        if(selectedButtons.contains(pressed))\r
-        {\r
-          pressed.setForeground(pressed.getBackground().darker().darker());\r
-          selectedButtons.remove(pressed);\r
-        }\r
-        else\r
-        {\r
-          pressed.setForeground( pressed.getBackground().brighter().brighter());\r
-          selectedButtons.addElement(pressed);\r
-        }\r
-      }\r
-\r
-      if(selectedButtons.size()>0)\r
-      colorChooser.setColor( ((JButton)selectedButtons.elementAt(0)).getBackground());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param label DOCUMENT ME!\r
-     * @param aa DOCUMENT ME!\r
-     */\r
-    void makeButton(String label, String aa)\r
-    {\r
-        final JButton button = new JButton();\r
-        Color col = Color.white;\r
-\r
-        try\r
-        {\r
-            col = oldColourScheme.findColour(aa, -1);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        //  ex.printStackTrace();\r
-        }\r
-\r
-        button.setBackground(col);\r
-        button.setText(label);\r
-        button.setForeground(col.darker().darker().darker());\r
-        button.setFont(new java.awt.Font("Verdana", 1, 10));\r
-        button.addMouseListener(new java.awt.event.MouseAdapter()\r
-            {\r
-                public void mouseClicked(MouseEvent e)\r
-                {\r
-                    colourButtonPressed(e);\r
-                }\r
-            });\r
-\r
-        buttonPanel.add(button, null);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void okButton_actionPerformed(ActionEvent e)\r
-    {\r
-        applyButton_actionPerformed(null);\r
-\r
-        try\r
-        {\r
-            frame.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void applyButton_actionPerformed(ActionEvent e)\r
-    {\r
-        UserColourScheme ucs = getSchemeFromGUI();\r
-        ucs.setName(schemeName.getText());\r
-\r
-        if (seqGroup != null)\r
-        {\r
-            seqGroup.cs = ucs;\r
-            ap.repaint();\r
-        }\r
-        else if(ap!=null)\r
-        {\r
-            ap.alignFrame.changeColour(ucs);\r
-        }\r
-        else if(pdbcanvas!=null)\r
-        {\r
-          pdbcanvas.pdb.setColours(ucs);\r
-          pdbcanvas.updateSeqColours();\r
-        }\r
-    }\r
-\r
-    UserColourScheme getSchemeFromGUI()\r
-    {\r
-      Color[] newColours = new Color[24];\r
-\r
-      for (int i = 0; i < 24; i++)\r
-      {\r
-        JButton button = (JButton) buttonPanel.getComponent(i);\r
-        newColours[i] = button.getBackground();\r
-      }\r
-\r
-      UserColourScheme ucs = new UserColourScheme(newColours);\r
-      if(ap!=null)\r
-        ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
-\r
-\r
-      return ucs;\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void loadbutton_actionPerformed(ActionEvent e)\r
-    {\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"), new String[] { "jc" },\r
-                new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
-        chooser.setFileView(new jalview.io.JalviewFileView());\r
-        chooser.setDialogTitle("Load colour scheme");\r
-        chooser.setToolTipText("Load");\r
-\r
-        int value = chooser.showOpenDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            File choice = chooser.getSelectedFile();\r
-            jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());\r
-            String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS",\r
-                choice.getPath());\r
-            if (defaultColours.indexOf(choice.getPath()) == -1)\r
-              defaultColours = defaultColours.concat("|").concat(choice.getPath());\r
-\r
-            jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
-\r
-\r
-            UserColourScheme ucs = loadColours(choice.getAbsolutePath());\r
-            Color[] colors = ucs.getColours();\r
-            schemeName.setText(ucs.getName());\r
-\r
-            for (int i = 0; i < colors.length; i++)\r
-            {\r
-                JButton button = (JButton) buttonPanel.getComponent(i);\r
-                button.setBackground(colors[i]);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static UserColourScheme loadDefaultColours()\r
-    {\r
-        UserColourScheme ret = null;\r
-\r
-        String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");\r
-        if ( colours != null )\r
-        {\r
-          if(colours.indexOf("|")>-1)\r
-            colours = colours.substring(0, colours.indexOf("|"));\r
-\r
-          ret = loadColours(colours);\r
-        }\r
-\r
-        if(ret == null)\r
-        {\r
-          Color[] newColours = new Color[24];\r
-          for (int i = 0; i < 24; i++)\r
-          {\r
-            newColours[i] = Color.white;\r
-          }\r
-          ret =  new UserColourScheme(newColours);\r
-        }\r
-\r
-        return ret;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param file DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    static UserColourScheme loadColours(String file)\r
-    {\r
-         UserColourScheme ucs = null;\r
-         Color[]  newColours = null;\r
-\r
-        try\r
-        {\r
-            InputStreamReader in = new InputStreamReader(new FileInputStream(\r
-                        file), "UTF-8");\r
-\r
-            jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();\r
-            jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
-\r
-            newColours = new Color[jucs.getColourCount()];\r
-\r
-            for (int i = 0; i < 24; i++)\r
-            {\r
-              newColours[i] = new Color(Integer.parseInt(\r
-                  jucs.getColour(i).getRGB(), 16));\r
-            }\r
-            if (newColours != null)\r
-            {\r
-              ucs = new UserColourScheme(newColours);\r
-              ucs.setName( jucs.getSchemeName() );\r
-            }\r
-\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            System.out.println("Error loading User ColourFile\n"+ex);\r
-        }\r
-\r
-\r
-       return ucs;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void savebutton_actionPerformed(ActionEvent e)\r
-    {\r
-      if(schemeName.getText().trim().length()<1)\r
-      {\r
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                              "User colour scheme must have a name!",\r
-                                              "No name for colour scheme",\r
-                                              JOptionPane.WARNING_MESSAGE);\r
-        return;\r
-      }\r
-\r
-      if(userColourSchemes!=null && userColourSchemes.containsKey(schemeName.getText()) )\r
-      {\r
-        int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Colour scheme "+schemeName.getText()+ " exists."\r
-            +"\nContinue saving colour scheme as "+schemeName.getText()+"?",\r
-           "Duplicate scheme name", JOptionPane.YES_NO_OPTION);\r
-        if(reply != JOptionPane.YES_OPTION)\r
-          return;\r
-\r
-         userColourSchemes.remove(schemeName.getText());\r
-      }\r
-        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                    "LAST_DIRECTORY"), new String[] { "jc" },\r
-                new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
-\r
-        chooser.setFileView(new jalview.io.JalviewFileView());\r
-        chooser.setDialogTitle("Save colour scheme");\r
-        chooser.setToolTipText("Save");\r
-\r
-        int value = chooser.showSaveDialog(this);\r
-\r
-        if (value == JalviewFileChooser.APPROVE_OPTION)\r
-        {\r
-            String choice = chooser.getSelectedFile().getPath();\r
-            String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS", choice);\r
-            if(defaultColours.indexOf(choice)==-1)\r
-            {\r
-              if(defaultColours.length()>0)\r
-                defaultColours = defaultColours.concat("|");\r
-              defaultColours = defaultColours.concat(choice);\r
-            }\r
-\r
-            userColourSchemes.put(schemeName.getText(), getSchemeFromGUI());\r
-\r
-            ap.alignFrame.updateUserColourMenu();\r
-\r
-            jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
-\r
-            jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
-            ucs.setSchemeName(schemeName.getText());\r
-            try\r
-            {\r
-                PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
-                            new FileOutputStream(choice), "UTF-8"));\r
-\r
-                for (int i = 0; i < 24; i++)\r
-                {\r
-                    JButton button = (JButton) buttonPanel.getComponent(i);\r
-                    jalview.binding.Colour col = new jalview.binding.Colour();\r
-                    col.setName(button.getText());\r
-                    col.setRGB(jalview.util.Format.getHexString(\r
-                            button.getBackground()));\r
-                    ucs.addColour(col);\r
-                }\r
-\r
-                ucs.marshal(out);\r
-                out.close();\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                ex.printStackTrace();\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void cancelButton_actionPerformed(ActionEvent e)\r
-    {\r
-      if (ap != null)\r
-      {\r
-        if (seqGroup != null)\r
-        {\r
-          seqGroup.cs = oldColourScheme;\r
-        }\r
-        else if (ap != null)\r
-        {\r
-          ap.av.setGlobalColourScheme(oldColourScheme);\r
-        }\r
-        ap.repaint();\r
-      }\r
-\r
-      if(pdbcanvas!=null)\r
-      {\r
-        pdbcanvas.pdb.setColours(oldColourScheme);\r
-      }\r
-\r
-        try\r
-        {\r
-            frame.setClosed(true);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-\r
-    static Hashtable userColourSchemes;\r
-\r
-    public static Hashtable getUserColourSchemes()\r
-    {\r
-      return userColourSchemes;\r
-    }\r
-\r
-    public static void initUserColourSchemes(String files)\r
-    {\r
-      userColourSchemes = new Hashtable();\r
-\r
-      if(files==null || files.length()==0)\r
-        return;\r
-\r
-\r
-      // In case colours can't be loaded, we'll remove them\r
-      // from the default list here.\r
-      StringBuffer coloursFound = new StringBuffer();\r
-      StringTokenizer st = new StringTokenizer(files, "|");\r
-      while (st.hasMoreElements())\r
-      {\r
-        String file = st.nextToken();\r
-        try\r
-        {\r
-          UserColourScheme ucs = loadColours(file);\r
-          if (ucs != null)\r
-          {\r
-            if (coloursFound.length() > 0)\r
-              coloursFound.append("|");\r
-            coloursFound.append(file);\r
-            userColourSchemes.put(ucs.getName(), ucs);\r
-          }\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          System.out.println("Error loading User ColourFile\n" + ex);\r
-        }\r
-      }\r
-      if (!files.equals(coloursFound.toString()))\r
-      {\r
-        if (coloursFound.toString().length() > 1)\r
-          jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",\r
-                                        coloursFound.toString());\r
-        else\r
-          jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
-      }\r
-    }\r
-\r
-    public static void removeColourFromDefaults(String target)\r
-    {\r
-      // The only way to find colours by name is to load them in\r
-      // In case colours can't be loaded, we'll remove them\r
-      // from the default list here.\r
-\r
-      userColourSchemes = new Hashtable();\r
-\r
-      StringBuffer coloursFound = new StringBuffer();\r
-      StringTokenizer st = new StringTokenizer(\r
-           jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");\r
-\r
-      while (st.hasMoreElements())\r
-      {\r
-        String file = st.nextToken();\r
-        try\r
-        {\r
-          UserColourScheme ucs = loadColours(file);\r
-          if (ucs != null && !ucs.getName().equals(target))\r
-          {\r
-            if (coloursFound.length() > 0)\r
-              coloursFound.append("|");\r
-            coloursFound.append(file);\r
-            userColourSchemes.put(ucs.getName(), ucs);\r
-          }\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          System.out.println("Error loading User ColourFile\n" + ex);\r
-        }\r
-      }\r
-\r
-      if (coloursFound.toString().length() > 1)\r
-        jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());\r
-      else\r
-        jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
-\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import jalview.datamodel.*;
+
+import jalview.io.*;
+
+import jalview.jbgui.*;
+
+import jalview.schemes.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import java.io.*;
+
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class UserDefinedColours extends GUserDefinedColours
+    implements ChangeListener
+{
+    AlignmentPanel ap;
+    SequenceGroup seqGroup;
+    Vector selectedButtons;
+    ColourSchemeI oldColourScheme;
+    JInternalFrame frame;
+    MCview.PDBCanvas pdbcanvas;
+    Vector upperCaseButtons;
+    Vector lowerCaseButtons;
+
+
+    /**
+     * Creates a new UserDefinedColours object.
+     *
+     * @param ap DOCUMENT ME!
+     * @param sg DOCUMENT ME!
+     */
+    public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
+    {
+        super();
+        lcaseColour.setEnabled(false);
+
+        this.ap = ap;
+        seqGroup = sg;
+
+        if (seqGroup != null)
+            oldColourScheme = seqGroup.cs;
+        else
+            oldColourScheme = ap.av.getGlobalColourScheme();
+
+        if (oldColourScheme instanceof UserColourScheme)
+        {
+          schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());
+          if(( (UserColourScheme) oldColourScheme).getLowerCaseColours()!=null)
+          {
+            caseSensitive.setSelected(true);
+            lcaseColour.setEnabled(true);
+            resetButtonPanel(true);
+          }
+          else
+            resetButtonPanel(false);
+        }
+        else
+           resetButtonPanel(false);
+
+        showFrame();
+    }
+
+    public UserDefinedColours(MCview.PDBCanvas pdb, ColourSchemeI oldcs)
+    {
+        super();
+        pdbcanvas = pdb;
+
+        colorChooser.getSelectionModel().addChangeListener(this);
+
+        oldColourScheme = oldcs;
+
+        if (oldColourScheme instanceof UserColourScheme)
+        {
+              schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());
+        }
+
+        resetButtonPanel(false);
+
+        showFrame();
+
+    }
+
+    void showFrame()
+    {
+      colorChooser.getSelectionModel().addChangeListener(this);
+      frame = new JInternalFrame();
+      frame.setContentPane(this);
+      Desktop.addInternalFrame(frame, "User Defined Colours", 720, 370, true);
+
+      if (seqGroup != null)
+            frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
+
+      if (System.getProperty("os.name").startsWith("Mac"))
+      {
+        frame.setSize(760, 370);
+      }
+    }
+
+    void resetButtonPanel(boolean caseSensitive)
+    {
+      buttonPanel.removeAll();
+
+
+      if(upperCaseButtons==null)
+        upperCaseButtons = new Vector();
+
+      JButton button;
+      String label;
+      for (int i = 0; i < 20; i++)
+      {
+        if(caseSensitive)
+          label = ResidueProperties.aa[i];
+        else
+          label = ResidueProperties.aa2Triplet.get
+              (ResidueProperties.aa[i]).toString();
+
+        button = makeButton(label,
+                              ResidueProperties.aa[i],
+                              upperCaseButtons, i);
+
+        buttonPanel.add(button);
+      }
+
+        buttonPanel.add(makeButton("B", "B", upperCaseButtons, 20));
+        buttonPanel.add(makeButton("Z", "Z", upperCaseButtons, 21));
+        buttonPanel.add(makeButton("X", "X", upperCaseButtons, 22));
+        buttonPanel.add(makeButton("Gap", "-", upperCaseButtons, 23));
+
+      if(!caseSensitive)
+      {
+        gridLayout.setRows(6);
+        gridLayout.setColumns(4);
+      }
+      else
+      {
+        gridLayout.setRows(7);
+        int cols = 7;
+        gridLayout.setColumns(cols+1);
+
+        if(lowerCaseButtons==null)
+          lowerCaseButtons = new Vector();
+
+
+          for (int i = 0; i < 20; i++)
+          {
+            int row = i / cols + 1;
+            int index = (row * cols) + i;
+            button = makeButton(
+                ResidueProperties.aa[i].toLowerCase(),
+                ResidueProperties.aa[i].toLowerCase(),
+                lowerCaseButtons,
+                i);
+
+            buttonPanel.add(button, index);
+          }
+      }
+
+
+      if(caseSensitive)
+      {
+        buttonPanel.add(makeButton("b", "b", lowerCaseButtons, 20));
+        buttonPanel.add(makeButton("z", "z", lowerCaseButtons, 21));
+        buttonPanel.add(makeButton("x", "x", lowerCaseButtons, 22));
+      }
+
+      buttonPanel.validate();
+      validate();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void stateChanged(ChangeEvent evt)
+    {
+        if (selectedButtons != null)
+        {
+          JButton button=null;
+          for(int i=0; i<selectedButtons.size(); i++)
+          {
+            button = (JButton)selectedButtons.elementAt(i);
+            button.setBackground(colorChooser.getColor());
+            button.setForeground( button.getBackground().brighter().brighter().brighter());
+          }
+          if(button==lcaseColour)
+          {
+            for(int i=0; i<lowerCaseButtons.size(); i++)
+            {
+              button = (JButton)lowerCaseButtons.elementAt(i);
+              button.setBackground(colorChooser.getColor());
+              button.setForeground( button.getBackground().brighter().brighter().brighter());
+            }
+          }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void colourButtonPressed(MouseEvent e)
+    {
+      if(selectedButtons == null)
+        selectedButtons = new Vector();
+
+      JButton pressed = (JButton) e.getSource();
+
+      if(e.isShiftDown())
+      {
+        JButton start, end = (JButton) e.getSource();
+        if(selectedButtons.size()>0)
+          start = (JButton)selectedButtons.elementAt(selectedButtons.size()-1);
+        else
+          start = (JButton) e.getSource();
+
+        int startIndex=0, endIndex=0;
+        for(int b=0; b<buttonPanel.getComponentCount(); b++)
+        {
+          if(buttonPanel.getComponent(b)==start)
+            startIndex = b;
+          if(buttonPanel.getComponent(b)==end)
+            endIndex = b;
+        }
+
+        if(startIndex > endIndex)
+        {
+          int temp = startIndex;
+          startIndex = endIndex;
+          endIndex = temp;
+        }
+
+        for(int b=startIndex; b<=endIndex; b++)
+        {
+          JButton button = (JButton)buttonPanel.getComponent(b);
+          if(!selectedButtons.contains(button))
+          {
+            button.setForeground(button.getBackground().brighter().brighter());
+            selectedButtons.add(button);
+          }
+        }
+      }
+      else if(!e.isControlDown())
+      {
+        for(int b=0; b<selectedButtons.size(); b++)
+        {
+          JButton button = (JButton)selectedButtons.elementAt(b);
+          button.setForeground(button.getBackground().darker().darker());
+        }
+        selectedButtons.clear();
+        pressed.setForeground( pressed.getBackground().brighter().brighter());
+        selectedButtons.addElement(pressed);
+
+      }
+      else if(e.isControlDown())
+      {
+        if(selectedButtons.contains(pressed))
+        {
+          pressed.setForeground(pressed.getBackground().darker().darker());
+          selectedButtons.remove(pressed);
+        }
+        else
+        {
+          pressed.setForeground( pressed.getBackground().brighter().brighter());
+          selectedButtons.addElement(pressed);
+        }
+      }
+
+      if(selectedButtons.size()>0)
+      colorChooser.setColor( ((JButton)selectedButtons.elementAt(0)).getBackground());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param label DOCUMENT ME!
+     * @param aa DOCUMENT ME!
+     */
+    JButton makeButton(String label,
+                       String aa,
+                       Vector caseSensitiveButtons,
+                       int buttonIndex)
+    {
+        final JButton button;
+        Color col;
+
+        if(buttonIndex<caseSensitiveButtons.size())
+        {
+          button = (JButton) caseSensitiveButtons.elementAt(buttonIndex);
+          col = button.getBackground();
+        }
+        else
+        {
+          button = new JButton();
+          button.addMouseListener(new java.awt.event.MouseAdapter()
+          {
+            public void mouseClicked(MouseEvent e)
+            {
+              colourButtonPressed(e);
+            }
+          });
+
+          caseSensitiveButtons.addElement(button);
+
+          col = Color.white;
+
+          try
+          {
+            col = oldColourScheme.findColour(aa, -1);
+          }
+          catch (Exception ex)
+          {    }
+        }
+
+        if(caseSensitive.isSelected())
+          button.setMargin(new java.awt.Insets(2,2,2,2));
+        else
+          button.setMargin(new java.awt.Insets(2,14,2,14));
+
+        button.setBackground(col);
+        button.setText(label);
+        button.setForeground(col.darker().darker().darker());
+        button.setFont(new java.awt.Font("Verdana", Font.BOLD, 10));
+
+        return button;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void okButton_actionPerformed(ActionEvent e)
+    {
+        applyButton_actionPerformed(null);
+
+        try
+        {
+            frame.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void applyButton_actionPerformed(ActionEvent e)
+    {
+        UserColourScheme ucs = getSchemeFromButtons();
+        ucs.setName(schemeName.getText());
+
+        if (seqGroup != null)
+        {
+            seqGroup.cs = ucs;
+            ap.repaint();
+        }
+        else if(ap!=null)
+        {
+            ap.alignFrame.changeColour(ucs);
+        }
+        else if(pdbcanvas!=null)
+        {
+          pdbcanvas.pdb.setColours(ucs);
+          pdbcanvas.updateSeqColours();
+        }
+    }
+
+    UserColourScheme getSchemeFromButtons()
+    {
+
+      Color[] newColours = new Color[24];
+
+      for (int i = 0; i < 24; i++)
+      {
+        JButton button = (JButton) upperCaseButtons.elementAt(i);
+        newColours[i] = button.getBackground();
+      }
+
+      UserColourScheme ucs = new UserColourScheme(newColours);
+
+
+      if(caseSensitive.isSelected())
+      {
+        newColours = new Color[23];
+        for (int i = 0; i < 23; i++)
+        {
+          JButton button = (JButton) lowerCaseButtons.elementAt(i);
+          newColours[i] = button.getBackground();
+        }
+        ucs.setLowerCaseColours(newColours);
+      }
+
+      if(ap!=null)
+        ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
+
+
+      return ucs;
+    }
+
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void loadbutton_actionPerformed(ActionEvent e)
+    {
+      upperCaseButtons = new Vector();
+      lowerCaseButtons = new Vector();
+
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"), new String[] { "jc" },
+                new String[] { "Jalview User Colours" }, "Jalview User Colours");
+        chooser.setFileView(new jalview.io.JalviewFileView());
+        chooser.setDialogTitle("Load colour scheme");
+        chooser.setToolTipText("Load");
+
+        int value = chooser.showOpenDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            File choice = chooser.getSelectedFile();
+            jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+            String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS",
+                choice.getPath());
+            if (defaultColours.indexOf(choice.getPath()) == -1)
+              defaultColours = defaultColours.concat("|").concat(choice.getPath());
+
+            jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
+
+
+            UserColourScheme ucs = loadColours(choice.getAbsolutePath());
+            Color[] colors = ucs.getColours();
+            schemeName.setText(ucs.getName());
+
+            if(ucs.getLowerCaseColours()!=null)
+            {
+              caseSensitive.setSelected(true);
+              lcaseColour.setEnabled(true);
+              resetButtonPanel(true);
+              for (int i = 0; i < lowerCaseButtons.size(); i++)
+              {
+                JButton button = (JButton) lowerCaseButtons.elementAt(i);
+                button.setBackground(ucs.getLowerCaseColours()[i]);
+              }
+
+            }
+            else
+            {
+              caseSensitive.setSelected(false);
+              lcaseColour.setEnabled(false);
+              resetButtonPanel(false);
+            }
+
+            for (int i = 0; i < upperCaseButtons.size(); i++)
+            {
+                JButton button = (JButton) upperCaseButtons.elementAt(i);
+                button.setBackground(colors[i]);
+            }
+
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static UserColourScheme loadDefaultColours()
+    {
+        UserColourScheme ret = null;
+
+        String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");
+        if ( colours != null )
+        {
+          if(colours.indexOf("|")>-1)
+            colours = colours.substring(0, colours.indexOf("|"));
+
+          ret = loadColours(colours);
+        }
+
+        if(ret == null)
+        {
+          Color[] newColours = new Color[24];
+          for (int i = 0; i < 24; i++)
+          {
+            newColours[i] = Color.white;
+          }
+          ret =  new UserColourScheme(newColours);
+        }
+
+        return ret;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param file DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    static UserColourScheme loadColours(String file)
+    {
+         UserColourScheme ucs = null;
+         Color[]  newColours = null;
+        try
+        {
+            InputStreamReader in = new InputStreamReader(new FileInputStream(
+                        file), "UTF-8");
+
+              jalview.schemabinding.version2.JalviewUserColours jucs
+                  = new jalview.schemabinding.version2.JalviewUserColours();
+
+              org.exolab.castor.xml.Unmarshaller unmar
+                  = new org.exolab.castor.xml.Unmarshaller(jucs);
+              jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar.unmarshal( in );
+
+              newColours = new Color[24];
+
+              Color [] lowerCase = null;
+              boolean caseSensitive = false;
+
+
+            String name;
+            int index;
+            for (int i = 0; i < jucs.getColourCount(); i++)
+            {
+              name =  jucs.getColour(i).getName();
+              if(ResidueProperties.aa3Hash.containsKey(name))
+              {
+                index = ((Integer)ResidueProperties.aa3Hash.get(name)).intValue();
+              }
+              else
+              {
+                index = ((Integer)ResidueProperties.aaHash.get(name)).intValue();
+              }
+              if(index == -1)
+                continue;
+
+              if(name.toLowerCase().equals(name))
+              {
+                if(lowerCase==null)
+                   lowerCase = new Color[23];
+                caseSensitive = true;
+                lowerCase[index] = new Color(Integer.parseInt(
+                  jucs.getColour(i).getRGB(), 16));
+              }
+              else
+              {
+                newColours[index] = new Color(Integer.parseInt(
+                    jucs.getColour(i).getRGB(), 16));
+              }
+            }
+
+            if (newColours != null)
+            {
+              ucs = new UserColourScheme(newColours);
+              ucs.setName( jucs.getSchemeName() );
+              if(caseSensitive)
+              {
+                ucs.setLowerCaseColours(lowerCase);
+              }
+            }
+
+        }
+        catch (Exception ex)
+        {
+            //Could be Archive Jalview format
+            try{
+              InputStreamReader in = new InputStreamReader(new FileInputStream(
+                  file), "UTF-8");
+
+              jalview.binding.JalviewUserColours jucs
+                  = new jalview.binding.JalviewUserColours();
+
+              jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
+
+              newColours = new Color[jucs.getColourCount()];
+
+              for (int i = 0; i < 24; i++)
+              {
+                newColours[i] = new Color(Integer.parseInt(
+                    jucs.getColour(i).getRGB(), 16));
+              }
+              if (newColours != null)
+              {
+                ucs = new UserColourScheme(newColours);
+                ucs.setName(jucs.getSchemeName());
+              }
+            }catch(Exception ex2)
+            { ex2.printStackTrace(); }
+
+            if(newColours==null)
+              System.out.println("Error loading User ColourFile\n"+ex);
+        }
+
+       return ucs;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void savebutton_actionPerformed(ActionEvent e)
+    {
+      if(schemeName.getText().trim().length()<1)
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                              "User colour scheme must have a name!",
+                                              "No name for colour scheme",
+                                              JOptionPane.WARNING_MESSAGE);
+        return;
+      }
+
+      if(userColourSchemes!=null && userColourSchemes.containsKey(schemeName.getText()) )
+      {
+        int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Colour scheme "+schemeName.getText()+ " exists."
+            +"\nContinue saving colour scheme as "+schemeName.getText()+"?",
+           "Duplicate scheme name", JOptionPane.YES_NO_OPTION);
+        if(reply != JOptionPane.YES_OPTION)
+          return;
+
+         userColourSchemes.remove(schemeName.getText());
+      }
+        JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
+                    "LAST_DIRECTORY"), new String[] { "jc" },
+                new String[] { "Jalview User Colours" }, "Jalview User Colours");
+
+        chooser.setFileView(new jalview.io.JalviewFileView());
+        chooser.setDialogTitle("Save colour scheme");
+        chooser.setToolTipText("Save");
+
+        int value = chooser.showSaveDialog(this);
+
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+            String choice = chooser.getSelectedFile().getPath();
+            String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS", choice);
+            if(defaultColours.indexOf(choice)==-1)
+            {
+              if(defaultColours.length()>0)
+                defaultColours = defaultColours.concat("|");
+              defaultColours = defaultColours.concat(choice);
+            }
+
+            userColourSchemes.put(schemeName.getText(), getSchemeFromButtons());
+
+            ap.alignFrame.updateUserColourMenu();
+
+            jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
+
+            jalview.schemabinding.version2.JalviewUserColours ucs
+                = new jalview.schemabinding.version2.JalviewUserColours();
+
+            ucs.setSchemeName(schemeName.getText());
+            try
+            {
+                PrintWriter out = new PrintWriter(new OutputStreamWriter(
+                            new FileOutputStream(choice), "UTF-8"));
+
+                for (int i = 0; i < buttonPanel.getComponentCount(); i++)
+                {
+                    JButton button = (JButton) buttonPanel.getComponent(i);
+                    jalview.schemabinding.version2.Colour col
+                        = new jalview.schemabinding.version2.Colour();
+                    col.setName(button.getText());
+                    col.setRGB(jalview.util.Format.getHexString(
+                            button.getBackground()));
+                    ucs.addColour(col);
+                }
+
+                ucs.marshal(out);
+                out.close();
+            }
+            catch (Exception ex)
+            {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void cancelButton_actionPerformed(ActionEvent e)
+    {
+      if (ap != null)
+      {
+        if (seqGroup != null)
+        {
+          seqGroup.cs = oldColourScheme;
+        }
+        else if (ap != null)
+        {
+          ap.av.setGlobalColourScheme(oldColourScheme);
+        }
+        ap.repaint();
+      }
+
+      if(pdbcanvas!=null)
+      {
+        pdbcanvas.pdb.setColours(oldColourScheme);
+      }
+
+        try
+        {
+            frame.setClosed(true);
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+
+    static Hashtable userColourSchemes;
+
+    public static Hashtable getUserColourSchemes()
+    {
+      return userColourSchemes;
+    }
+
+    public static void initUserColourSchemes(String files)
+    {
+      userColourSchemes = new Hashtable();
+
+      if(files==null || files.length()==0)
+        return;
+
+
+      // In case colours can't be loaded, we'll remove them
+      // from the default list here.
+      StringBuffer coloursFound = new StringBuffer();
+      StringTokenizer st = new StringTokenizer(files, "|");
+      while (st.hasMoreElements())
+      {
+        String file = st.nextToken();
+        try
+        {
+          UserColourScheme ucs = loadColours(file);
+          if (ucs != null)
+          {
+            if (coloursFound.length() > 0)
+              coloursFound.append("|");
+            coloursFound.append(file);
+            userColourSchemes.put(ucs.getName(), ucs);
+          }
+        }
+        catch (Exception ex)
+        {
+          System.out.println("Error loading User ColourFile\n" + ex);
+        }
+      }
+      if (!files.equals(coloursFound.toString()))
+      {
+        if (coloursFound.toString().length() > 1)
+          jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
+                                        coloursFound.toString());
+        else
+          jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");
+      }
+    }
+
+    public static void removeColourFromDefaults(String target)
+    {
+      // The only way to find colours by name is to load them in
+      // In case colours can't be loaded, we'll remove them
+      // from the default list here.
+
+      userColourSchemes = new Hashtable();
+
+      StringBuffer coloursFound = new StringBuffer();
+      StringTokenizer st = new StringTokenizer(
+           jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");
+
+      while (st.hasMoreElements())
+      {
+        String file = st.nextToken();
+        try
+        {
+          UserColourScheme ucs = loadColours(file);
+          if (ucs != null && !ucs.getName().equals(target))
+          {
+            if (coloursFound.length() > 0)
+              coloursFound.append("|");
+            coloursFound.append(file);
+            userColourSchemes.put(ucs.getName(), ucs);
+          }
+        }
+        catch (Exception ex)
+        {
+          System.out.println("Error loading User ColourFile\n" + ex);
+        }
+      }
+
+      if (coloursFound.toString().length() > 1)
+        jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());
+      else
+        jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");
+
+    }
+
+    public void caseSensitive_actionPerformed(ActionEvent e)
+    {
+      resetButtonPanel(caseSensitive.isSelected());
+      lcaseColour.setEnabled(caseSensitive.isSelected());
+    }
+
+    public void lcaseColour_actionPerformed(ActionEvent e)
+    {
+      if(selectedButtons==null)
+        selectedButtons = new Vector();
+      else
+        selectedButtons.clear();
+      selectedButtons.add(lcaseColour);
+    }
+
+}
index a260072..b7d54d6 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.gui;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * Base class for web service client thread and gui\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class WebserviceInfo extends GWebserviceInfo\r
-{\r
-    /** Job is Queued */\r
-    public static final int STATE_QUEUING = 0;\r
-\r
-    /** Job is Running */\r
-    public static final int STATE_RUNNING = 1;\r
-\r
-    /** Job has finished with no errors */\r
-    public static final int STATE_STOPPED_OK = 2;\r
-\r
-    /** Job has been cancelled with no errors */\r
-    public static final int STATE_CANCELLED_OK = 3;\r
-\r
-    /** job has stopped because of some error */\r
-    public static final int STATE_STOPPED_ERROR = 4;\r
-\r
-    /** job has failed because of some unavoidable service interruption */\r
-    public static final int STATE_STOPPED_SERVERERROR = 5;\r
-    int currentStatus = STATE_QUEUING;\r
-    Image image;\r
-    int angle = 0;\r
-    String title = "";\r
-    jalview.ws.WSClientI thisService;\r
-    boolean serviceIsCancellable;\r
-\r
-    /**\r
-     * Creates a new WebserviceInfo object.\r
-     *\r
-     * @param title short name and job type\r
-     * @param info reference or other human readable description\r
-     */\r
-    public WebserviceInfo(String title, String info)\r
-    {\r
-        init(title, info, 520, 500);\r
-    }\r
-\r
-    /**\r
-     * Creates a new WebserviceInfo object.\r
-     *\r
-     * @param title DOCUMENT ME!\r
-     * @param info DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    public WebserviceInfo(String title, String info, int width, int height)\r
-    {\r
-        init(title, info, width, height);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public jalview.ws.WSClientI getthisService()\r
-    {\r
-        return thisService;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param newservice DOCUMENT ME!\r
-     */\r
-    public void setthisService(jalview.ws.WSClientI newservice)\r
-    {\r
-        thisService = newservice;\r
-        serviceIsCancellable = newservice.isCancellable();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param title DOCUMENT ME!\r
-     * @param info DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param height DOCUMENT ME!\r
-     */\r
-    void init(String title, String info, int width, int height)\r
-    {\r
-        JInternalFrame frame = new JInternalFrame();\r
-        frame.setContentPane(this);\r
-        Desktop.addInternalFrame(frame, title, width, height);\r
-\r
-        this.title = title;\r
-        setInfoText(info);\r
-\r
-        java.net.URL url = getClass().getResource("/images/logo.gif");\r
-        image = java.awt.Toolkit.getDefaultToolkit().createImage(url);\r
-\r
-        MediaTracker mt = new MediaTracker(this);\r
-        mt.addImage(image, 0);\r
-\r
-        try\r
-        {\r
-            mt.waitForID(0);\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-\r
-        AnimatedPanel ap = new AnimatedPanel();\r
-        titlePanel.add(ap, BorderLayout.CENTER);\r
-\r
-        Thread thread = new Thread(ap);\r
-        thread.start();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param status integer status from state constants\r
-     */\r
-    public void setStatus(int status)\r
-    {\r
-        currentStatus = status;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getInfoText()\r
-    {\r
-        return infoText.getText();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param text DOCUMENT ME!\r
-     */\r
-    public void setInfoText(String text)\r
-    {\r
-        infoText.setText(text);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param text DOCUMENT ME!\r
-     */\r
-    public void appendInfoText(String text)\r
-    {\r
-        infoText.append(text);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String getProgressText()\r
-    {\r
-        return progressText.getText();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param text DOCUMENT ME!\r
-     */\r
-    public void setProgressText(String text)\r
-    {\r
-        progressText.setText(text);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param text DOCUMENT ME!\r
-     */\r
-    public void appendProgressText(String text)\r
-    {\r
-        progressText.append(text);\r
-    }\r
-\r
-    /**\r
-     * Gui action for cancelling the current job, if possible.\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-        if (!serviceIsCancellable)\r
-        {\r
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                "This job cannot be cancelled.\nJust close the window.", "Cancel job",\r
-                JOptionPane.WARNING_MESSAGE);\r
-        }\r
-        else\r
-        {\r
-            thisService.cancelJob();\r
-        }\r
-    }\r
-\r
-    class AnimatedPanel extends JPanel implements Runnable\r
-    {\r
-        long startTime = 0;\r
-\r
-        public void run()\r
-        {\r
-            startTime = System.currentTimeMillis();\r
-\r
-            while (currentStatus < STATE_STOPPED_OK)\r
-            {\r
-                try\r
-                {\r
-                    Thread.sleep(50);\r
-\r
-                    int units = (int) ((System.currentTimeMillis() - startTime) / 10f);\r
-                    angle += units;\r
-                    angle %= 360;\r
-                    startTime = System.currentTimeMillis();\r
-                    repaint();\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
-\r
-            angle = 0;\r
-            cancel.setEnabled(false);\r
-        }\r
-\r
-        synchronized public void paintComponent(Graphics g1)\r
-        {\r
-            Graphics2D g = (Graphics2D) g1;\r
-            g.setColor(Color.white);\r
-            g.fillRect(0, 0, getWidth(), getHeight());\r
-\r
-            if (image != null)\r
-            {\r
-                g.rotate(Math.toRadians(angle), 28, 28);\r
-                g.drawImage(image, 10, 10, this);\r
-                g.rotate(-Math.toRadians(angle), 28, 28);\r
-            }\r
-\r
-            g.setFont(new Font("Arial", Font.BOLD, 12));\r
-            g.setColor(Color.black);\r
-\r
-            switch (currentStatus)\r
-            {\r
-            case STATE_QUEUING:\r
-                g.drawString(title.concat(" - queuing"), 60, 30);\r
-\r
-                break;\r
-\r
-            case STATE_RUNNING:\r
-                g.drawString(title.concat(" - running"), 60, 30);\r
-\r
-                break;\r
-\r
-            case STATE_STOPPED_OK:\r
-                g.drawString(title.concat(" - complete"), 60, 30);\r
-\r
-                break;\r
-\r
-            case STATE_CANCELLED_OK:\r
-                g.drawString(title.concat(" - job cancelled!"), 60, 30);\r
-\r
-                break;\r
-\r
-            case STATE_STOPPED_ERROR:\r
-                g.drawString(title.concat(" - job error!"), 60, 30);\r
-\r
-                break;\r
-\r
-            case STATE_STOPPED_SERVERERROR:\r
-                g.drawString(title.concat(" - Server Error! (try later)"), 60,\r
-                    30);\r
-\r
-                break;\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import javax.swing.*;
+
+import jalview.jbgui.*;
+
+
+/**
+ * Base class for web service client thread and gui
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class WebserviceInfo extends GWebserviceInfo
+{
+
+    /** Job is Queued */
+    public static final int STATE_QUEUING = 0;
+
+    /** Job is Running */
+    public static final int STATE_RUNNING = 1;
+
+    /** Job has finished with no errors */
+    public static final int STATE_STOPPED_OK = 2;
+
+    /** Job has been cancelled with no errors */
+    public static final int STATE_CANCELLED_OK = 3;
+
+    /** job has stopped because of some error */
+    public static final int STATE_STOPPED_ERROR = 4;
+
+    /** job has failed because of some unavoidable service interruption */
+    public static final int STATE_STOPPED_SERVERERROR = 5;
+    int currentStatus = STATE_QUEUING;
+    Image image;
+    int angle = 0;
+    String title = "";
+    jalview.ws.WSClientI thisService;
+    boolean serviceIsCancellable;
+    JInternalFrame frame;
+    JTabbedPane subjobs=null;
+    java.util.Vector jobPanes = null;
+    private boolean serviceCanMergeResults = false;
+    private boolean viewResultsImmediatly = true;
+  // tabbed or not
+    public synchronized int addJobPane() {
+      JScrollPane jobpane = new JScrollPane();
+      JTextArea progressText = new JTextArea();
+      progressText.setFont(new java.awt.Font("Verdana", 0, 10));
+      progressText.setBorder(null);
+      progressText.setEditable(false);
+      progressText.setText("WS Job");
+      progressText.setLineWrap(true);
+      progressText.setWrapStyleWord(true);
+      jobpane.setName("JobPane");
+      jobpane.getViewport().add(progressText, null);
+      jobpane.setBorder(null);
+      if (jobPanes==null) {
+        jobPanes = new Vector();
+      }
+      int newpane = jobPanes.size();
+      jobPanes.add(jobpane);
+
+      if (newpane==0) {
+        this.add(jobpane, BorderLayout.CENTER);
+      } else {
+        if (newpane==1) {
+        // revert to a tabbed pane.
+        JScrollPane firstpane;
+        this.remove(firstpane=(JScrollPane) jobPanes.get(0));
+        subjobs=new JTabbedPane();
+          this.add(subjobs, BorderLayout.CENTER);
+          subjobs.add(firstpane);
+          subjobs.setTitleAt(0, firstpane.getName());
+        }
+        subjobs.add(jobpane);
+      }
+      return newpane; // index for accessor methods below
+    }
+    /**
+     * Creates a new WebserviceInfo object.
+     *
+     * @param title short name and job type
+     * @param info reference or other human readable description
+     */
+    public WebserviceInfo(String title, String info)
+    {
+        init(title, info, 520, 500);
+    }
+
+    /**
+     * Creates a new WebserviceInfo object.
+     *
+     * @param title DOCUMENT ME!
+     * @param info DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    public WebserviceInfo(String title, String info, int width, int height)
+    {
+        init(title, info, width, height);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public jalview.ws.WSClientI getthisService()
+    {
+        return thisService;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param newservice DOCUMENT ME!
+     */
+    public void setthisService(jalview.ws.WSClientI newservice)
+    {
+        thisService = newservice;
+        serviceIsCancellable = newservice.isCancellable();
+        frame.setClosable(!serviceIsCancellable);
+        serviceCanMergeResults = newservice.canMergeResults();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param title DOCUMENT ME!
+     * @param info DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param height DOCUMENT ME!
+     */
+    void init(String title, String info, int width, int height)
+    {
+        frame = new JInternalFrame();
+        frame.setContentPane(this);
+        Desktop.addInternalFrame(frame, title, width, height);
+        frame.setClosable(false);
+
+        this.title = title;
+        setInfoText(info);
+
+        java.net.URL url = getClass().getResource("/images/logo.gif");
+        image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
+
+        MediaTracker mt = new MediaTracker(this);
+        mt.addImage(image, 0);
+
+        try
+        {
+            mt.waitForID(0);
+        }
+        catch (Exception ex)
+        {
+        }
+
+        AnimatedPanel ap = new AnimatedPanel();
+        titlePanel.add(ap, BorderLayout.CENTER);
+
+        Thread thread = new Thread(ap);
+        thread.start();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param status integer status from state constants
+     */
+    public void setStatus(int status)
+    {
+        currentStatus = status;
+    }
+    /**
+     * subjob status indicator
+     * @param jobpane
+     * @param status
+     */
+    public void setStatus(int jobpane, int status) {
+      if (jobpane<0 || jobpane>=jobPanes.size()) {
+        throw new Error("setStatus called for non-existent job pane."+jobpane);
+      }
+      switch (status) {
+      case STATE_QUEUING:
+        setProgressName(jobpane+" - QUEUED", jobpane);
+        break;
+      case STATE_RUNNING:
+        setProgressName(jobpane+" - RUNNING", jobpane);
+        break;
+      case STATE_STOPPED_OK:
+        setProgressName(jobpane+" - FINISHED", jobpane);
+      break;
+      case STATE_CANCELLED_OK:
+        setProgressName(jobpane+" - CANCELLED", jobpane);
+        break;
+      case STATE_STOPPED_ERROR:
+        setProgressName(jobpane+" - BROKEN",jobpane);
+        break;
+      case STATE_STOPPED_SERVERERROR:
+        setProgressName(jobpane+" - ALERT", jobpane);
+        break;
+        default:
+          setProgressName(jobpane+" - UNKNOWN STATE", jobpane);
+      }
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getInfoText()
+    {
+        return infoText.getText();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param text DOCUMENT ME!
+     */
+    public void setInfoText(String text)
+    {
+        infoText.setText(text);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param text DOCUMENT ME!
+     */
+    public void appendInfoText(String text)
+    {
+        infoText.append(text);
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getProgressText(int which)
+    {
+      if (jobPanes == null)
+        addJobPane();
+      return ( (JTextArea) ( (JScrollPane) jobPanes.get(which)).getViewport().
+              getComponent(0)).getText();
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @param text DOCUMENT ME!
+     */
+    public void setProgressText(int which, String text)
+    {
+      if (jobPanes == null)
+        addJobPane();
+      ( (JTextArea) ( (JScrollPane) jobPanes.get(which)).getViewport().
+       getComponent(0)).setText(text);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param text DOCUMENT ME!
+     */
+    public void appendProgressText(int which, String text)
+    {
+      if (jobPanes == null)
+        addJobPane();
+      ( (JTextArea) ( (JScrollPane) jobPanes.get(which)).getViewport().
+       getComponent(0)).append(text);
+    }
+    /**
+     * setProgressText(0, text)
+     */
+    public void setProgressText(String text)
+    {
+      setProgressText(0, text);
+    }
+    /**
+     * appendProgressText(0, text)
+     */
+    public void appendProgressText(String text)
+    {
+      appendProgressText(0, text);
+    }
+    /**
+     * getProgressText(0)
+     */
+    public String getProgressText()
+    {
+      return getProgressText(0);
+    }
+    /**
+     * get the tab title for a subjob
+     * @param which int
+     * @return String
+     */
+    public String getProgressName(int which) {
+      if (jobPanes==null)
+        addJobPane();
+      if (subjobs!=null)
+        return subjobs.getTitleAt(which);
+      else
+        return ((JScrollPane) jobPanes.get(which)).getViewport().getComponent(0).getName();
+    }
+    /**
+     * set the tab title for a subjob
+     * @param name String
+     * @param which int
+     */
+    public void setProgressName(String name, int which) {
+      if (subjobs!=null) {
+        subjobs.setTitleAt(which, name);
+        subjobs.revalidate();
+        subjobs.repaint();
+      }
+      JScrollPane c=(JScrollPane) jobPanes.get(which);
+      c.getViewport().getComponent(0).setName(name);
+      c.repaint();
+    }
+
+    /**
+     * Gui action for cancelling the current job, if possible.
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void cancel_actionPerformed(ActionEvent e)
+    {
+        if (!serviceIsCancellable)
+        {
+            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                "This job cannot be cancelled.\nJust close the window.", "Cancel job",
+                JOptionPane.WARNING_MESSAGE);
+        }
+        else
+        {
+            thisService.cancelJob();
+        }
+        frame.setClosable(true);
+    }
+    /**
+     * Set up GUI for user to get at results - and possibly automatically display
+     * them if viewResultsImmediatly is set.
+     */
+    public void setResultsReady()
+    {
+      frame.setClosable(true);
+      buttonPanel.remove(cancel);
+      buttonPanel.add(showResultsNewFrame);
+      if (serviceCanMergeResults)
+      {
+        buttonPanel.add(mergeResults);
+        buttonPanel.setLayout(new GridLayout(2, 1, 5, 5));
+      }
+      buttonPanel.validate();
+      validate();
+      if (viewResultsImmediatly)
+        showResultsNewFrame.doClick();
+    }
+
+  /**
+   * called when job has finished but no result objects can be passed back to user
+   */
+  public void setFinishedNoResults()
+  {
+    frame.setClosable(true);
+    buttonPanel.remove(cancel);
+    buttonPanel.validate();
+    validate();
+  }
+
+  class AnimatedPanel extends JPanel implements Runnable
+    {
+        long startTime = 0;
+        BufferedImage offscreen;
+
+        public void run()
+        {
+            startTime = System.currentTimeMillis();
+            Graphics2D g = null;
+
+            while (currentStatus < STATE_STOPPED_OK)
+            {
+                try
+                {
+                    Thread.sleep(50);
+
+                    int units = (int) ( (System.currentTimeMillis() - startTime) /
+                                       10f);
+                    angle += units;
+                    angle %= 360;
+                    startTime = System.currentTimeMillis();
+
+                    if (offscreen == null || offscreen.getWidth(this) != getWidth()
+                        || offscreen.getHeight(this) != getHeight())
+                    {
+                      offscreen = new BufferedImage(getWidth(), getHeight(),
+                                                    BufferedImage.TYPE_INT_ARGB);
+                      g = (Graphics2D) offscreen.getGraphics();
+                    }
+
+                    g.setColor(Color.white);
+                    g.fillRect(0, 0, getWidth(), getHeight());
+
+                    g.setFont(new Font("Arial", Font.BOLD, 12));
+                    g.setColor(Color.black);
+
+                    switch (currentStatus)
+                    {
+                      case STATE_QUEUING:
+                        g.drawString(title.concat(" - queuing"), 60, 30);
+
+                        break;
+
+                      case STATE_RUNNING:
+                        g.drawString(title.concat(" - running"), 60, 30);
+
+                        break;
+
+                      case STATE_STOPPED_OK:
+                        g.drawString(title.concat(" - complete"), 60, 30);
+
+                        break;
+
+                      case STATE_CANCELLED_OK:
+                        g.drawString(title.concat(" - job cancelled!"), 60, 30);
+
+                        break;
+
+                      case STATE_STOPPED_ERROR:
+                        g.drawString(title.concat(" - job error!"), 60, 30);
+
+                        break;
+
+                      case STATE_STOPPED_SERVERERROR:
+                        g.drawString(title.concat(" - Server Error! (try later)"),
+                                     60,
+                                     30);
+
+                        break;
+                    }
+
+
+                    if (currentStatus >= STATE_STOPPED_OK)
+                      angle = 0;
+
+                    if (image != null)
+                    {
+                      g.rotate(Math.toRadians(angle), 28, 28);
+                      g.drawImage(image, 10, 10, this);
+                      g.rotate( -Math.toRadians(angle), 28, 28);
+                    }
+
+
+                    repaint();
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+
+            cancel.setEnabled(false);
+        }
+
+        public void paintComponent(Graphics g1)
+        {
+            g1.drawImage(offscreen, 0,0,this);
+        }
+    }
+}
index ceec54b..2854c60 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public abstract class AlignFile extends FileParse\r
-{\r
-    int noSeqs = 0;\r
-    int maxLength = 0;\r
-    Vector seqs;\r
-    Vector headers;\r
-    long start;\r
-    long end;\r
-    boolean jvSuffix = true;\r
-\r
-    /**\r
-     * Creates a new AlignFile object.\r
-     */\r
-    public AlignFile()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Creates a new AlignFile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public AlignFile(String inStr)\r
-    {\r
-        initData();\r
-        System.out.println("is this ever called??");\r
-\r
-        try\r
-        {\r
-            parse();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Constructor which parses the data from a file of some specified type.\r
-     * @param inFile Filename to read from.\r
-     * @param type   What type of file to read from (File, URL)\r
-     */\r
-    public AlignFile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-\r
-        initData();\r
-\r
-        parse();\r
-    }\r
-\r
-    /**\r
-     * Return the seqs Vector\r
-     */\r
-    public Vector getSeqs()\r
-    {\r
-        return seqs;\r
-    }\r
-\r
-    /**\r
-     * Return the Sequences in the seqs Vector as an array of Sequences\r
-     */\r
-    public SequenceI[] getSeqsAsArray()\r
-    {\r
-        SequenceI[] s = new SequenceI[seqs.size()];\r
-\r
-        for (int i = 0; i < seqs.size(); i++)\r
-        {\r
-            s[i] = (SequenceI) seqs.elementAt(i);\r
-        }\r
-\r
-        return s;\r
-    }\r
-\r
-    /**\r
-     * Initialise objects to store sequence data in.\r
-     */\r
-    protected void initData()\r
-    {\r
-        seqs = new Vector();\r
-        headers = new Vector();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     */\r
-    protected void setSeqs(SequenceI[] s)\r
-    {\r
-        seqs = new Vector();\r
-\r
-        for (int i = 0; i < s.length; i++)\r
-        {\r
-            seqs.addElement(s[i]);\r
-        }\r
-    }\r
-\r
-    // Checks whether sequence is valid aa characters\r
-    protected boolean isValidProteinSequence(String sequence)\r
-    {\r
-        for (int i = 0; i < sequence.length(); i++)\r
-            if (!jalview.schemes.ResidueProperties.aaHash.containsKey(\r
-                        String.valueOf(sequence.charAt(i))))\r
-            {\r
-                invalidCharacter = sequence.charAt(i);\r
-                return false;\r
-            }\r
-\r
-        return true;\r
-    }\r
-\r
-    char invalidCharacter;\r
-\r
-    /**\r
-     * This method must be implemented to parse the contents of the file.\r
-     */\r
-    public abstract void parse() throws IOException;\r
-\r
-    /**\r
-     * Print out in alignment file format the Sequences in the seqs Vector.\r
-     */\r
-    public abstract String print();\r
-\r
-    public void addJVSuffix(boolean b)\r
-    {\r
-      jvSuffix = b;\r
-    }\r
-\r
-    /**\r
-     * A general parser for ids.\r
-     *\r
-     * @String id Id to be parsed\r
-     */\r
-    Sequence parseId(String id)\r
-    {\r
-      Sequence seq = null;\r
-      id = id.trim();\r
-      int space = id.indexOf(" ");\r
-      if(space>-1)\r
-      {\r
-        seq = new Sequence(id.substring(0, space),"");\r
-        seq.setDescription(id.substring(space+1));\r
-      }\r
-      else\r
-      {\r
-        seq = new Sequence(id, "");\r
-      }\r
-\r
-      return seq;\r
-    }\r
-\r
-    /**\r
-     * Creates the output id.\r
-     * Adds prefix Uniprot format source|id\r
-     * And suffix Jalview /start-end\r
-     *\r
-     * @String id Id to be parsed\r
-     */\r
-    String printId(SequenceI seq)\r
-    {\r
-     return seq.getDisplayId(jvSuffix);\r
-    }\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import jalview.datamodel.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public abstract class AlignFile extends FileParse
+{
+    int noSeqs = 0;
+    int maxLength = 0;
+    Vector seqs;
+    Vector headers;
+    long start;
+    long end;
+    boolean jvSuffix = true;
+
+    /**
+     * Creates a new AlignFile object.
+     */
+    public AlignFile()
+    {
+    }
+
+
+    /**
+     * Constructor which parses the data from a file of some specified type.
+     * @param inFile Filename to read from.
+     * @param type   What type of file to read from (File, URL)
+     */
+    public AlignFile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+
+        initData();
+
+        parse();
+    }
+
+    /**
+     * Return the seqs Vector
+     */
+    public Vector getSeqs()
+    {
+        return seqs;
+    }
+
+    /**
+     * Return the Sequences in the seqs Vector as an array of Sequences
+     */
+    public SequenceI[] getSeqsAsArray()
+    {
+        SequenceI[] s = new SequenceI[seqs.size()];
+
+        for (int i = 0; i < seqs.size(); i++)
+        {
+            s[i] = (SequenceI) seqs.elementAt(i);
+        }
+
+        return s;
+    }
+
+    /**
+     * Initialise objects to store sequence data in.
+     */
+    protected void initData()
+    {
+        seqs = new Vector();
+        headers = new Vector();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     */
+    protected void setSeqs(SequenceI[] s)
+    {
+        seqs = new Vector();
+
+        for (int i = 0; i < s.length; i++)
+        {
+            seqs.addElement(s[i]);
+        }
+    }
+
+    // Checks whether sequence is valid aa characters
+    protected boolean isValidProteinSequence(String sequence)
+    {
+        for (int i = 0; i < sequence.length(); i++)
+            if (!jalview.schemes.ResidueProperties.aaHash.containsKey(
+                        String.valueOf(sequence.charAt(i))))
+            {
+                invalidCharacter = sequence.charAt(i);
+                return false;
+            }
+
+        return true;
+    }
+
+    char invalidCharacter;
+
+    /**
+     * This method must be implemented to parse the contents of the file.
+     */
+    public abstract void parse() throws IOException;
+
+    /**
+     * Print out in alignment file format the Sequences in the seqs Vector.
+     */
+    public abstract String print();
+
+    public void addJVSuffix(boolean b)
+    {
+      jvSuffix = b;
+    }
+
+    /**
+     * A general parser for ids.
+     *
+     * @String id Id to be parsed
+     */
+    Sequence parseId(String id)
+    {
+      Sequence seq = null;
+      id = id.trim();
+      int space = id.indexOf(" ");
+      if(space>-1)
+      {
+        seq = new Sequence(id.substring(0, space),"");
+        seq.setDescription(id.substring(space+1));
+      }
+      else
+      {
+        seq = new Sequence(id, "");
+      }
+
+      return seq;
+    }
+
+    /**
+     * Creates the output id.
+     * Adds prefix Uniprot format source|id
+     * And suffix Jalview /start-end
+     *
+     * @String id Id to be parsed
+     */
+    String printId(SequenceI seq)
+    {
+     return seq.getDisplayId(jvSuffix);
+    }
+
+}
diff --git a/src/jalview/io/AnnotationReader.java b/src/jalview/io/AnnotationReader.java
deleted file mode 100755 (executable)
index 4325dae..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-package jalview.io;\r
-\r
-import java.io.*;\r
-import jalview.datamodel.*;\r
-import java.util.StringTokenizer;\r
-import jalview.schemes.UserColourScheme;\r
-import java.net.URL;\r
-\r
-public class AnnotationReader\r
-{\r
-  public boolean readAnnotationFile(AlignmentI al, String file)\r
-  {\r
-\r
-    try\r
-    {\r
-      BufferedReader in = null;\r
-      java.io.InputStream is = getClass().getResourceAsStream("/" + file);\r
-      if (is != null)\r
-      {\r
-        in = new BufferedReader(new java.io.InputStreamReader(is));\r
-      }\r
-      else\r
-      {\r
-        try\r
-        {\r
-          URL url = new URL(file);\r
-          in = new BufferedReader(new InputStreamReader(url.openStream()));\r
-        }\r
-        catch (java.net.MalformedURLException ex)\r
-        {\r
-          in = new BufferedReader(new FileReader(file));\r
-        }\r
-      }\r
-\r
-      String line, label, description, token;\r
-      int graphStyle, index;\r
-      SequenceI refSeq = null;\r
-      int refSeqIndex = 0;\r
-      int existingAnnotations = 0;\r
-      if(al.getAlignmentAnnotation()!=null)\r
-       existingAnnotations = al.getAlignmentAnnotation().length;\r
-\r
-      StringTokenizer st;\r
-      Annotation[] annotations;\r
-      AlignmentAnnotation annotation = null;\r
-\r
-      // First confirm this is an Annotation file\r
-      boolean jvAnnotationFile = false;\r
-      while ( (line = in.readLine()) != null)\r
-      {\r
-        if (line.indexOf("#") == 0 )\r
-          continue;\r
-\r
-        if (line.indexOf("JALVIEW_ANNOTATION") > -1)\r
-        {\r
-          jvAnnotationFile = true;\r
-          break;\r
-        }\r
-      }\r
-\r
-      if(!jvAnnotationFile)\r
-      {\r
-        in.close();\r
-        return false;\r
-      }\r
-\r
-      while ( (line = in.readLine()) != null)\r
-      {\r
-        if(line.indexOf("#")==0\r
-           || line.indexOf("JALVIEW_ANNOTATION")>-1\r
-           || line.length()==0)\r
-          continue;\r
-\r
-        st = new StringTokenizer(line, "\t");\r
-        token = st.nextToken();\r
-        if(token.equalsIgnoreCase("COLOUR"))\r
-        {\r
-          colourAnnotations(al, st.nextToken(), st.nextToken());\r
-          continue;\r
-        }\r
-\r
-        if(token.equalsIgnoreCase("COMBINE") )\r
-        {\r
-          combineAnnotations(al, st);\r
-          continue;\r
-        }\r
-\r
-        if (token.equalsIgnoreCase("GRAPHLINE"))\r
-        {\r
-          addLine(al, st);\r
-          continue;\r
-        }\r
-\r
-\r
-        if(token.equalsIgnoreCase("SEQUENCE_REF") )\r
-        {\r
-          refSeq = al.findName(st.nextToken());\r
-          try{\r
-            refSeqIndex = Integer.parseInt(st.nextToken());\r
-          }\r
-          catch(Exception ex)\r
-          {\r
-            refSeqIndex = 0;\r
-          }\r
-\r
-          continue;\r
-        }\r
-\r
-        graphStyle = AlignmentAnnotation.getGraphValueFromString(token);\r
-        label = description = st.nextToken();\r
-\r
-        line = st.nextToken();\r
-        st = new StringTokenizer(line, "|", true);\r
-        annotations = new Annotation[st.countTokens()+refSeqIndex];\r
-        index = refSeqIndex;\r
-        boolean emptyColumn = true;\r
-        while (st.hasMoreElements())\r
-        {\r
-          token = st.nextToken().trim();\r
-\r
-          if(token.equals("|"))\r
-          {\r
-            if(emptyColumn)\r
-              annotations[index++] = parseAnnotation("");\r
-\r
-            emptyColumn = true;\r
-          }\r
-          else\r
-          {\r
-            annotations[index++] = parseAnnotation(token);\r
-            emptyColumn = false;\r
-          }\r
-        }\r
-\r
-       annotation = new AlignmentAnnotation(label,\r
-                                          description,\r
-                                          annotations,\r
-                                          0,\r
-                                          0,\r
-                                          graphStyle);\r
-\r
-       annotation = al.addAnnotation(annotation, refSeq);\r
-       al.setAnnotationIndex(annotation,  al.getAlignmentAnnotation().length - existingAnnotations-1);\r
-      }\r
-\r
-       al.adjustSequenceAnnotations();\r
-\r
-\r
-    }catch(Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-      System.out.println("Problem reading annotation file: "+ex);\r
-      return false;\r
-    }\r
-    return true;\r
-  }\r
-\r
-  Annotation parseAnnotation(String string)\r
-  {\r
-    String desc = "", displayChar="";\r
-    char ss = ' '; // secondaryStructure\r
-    float value = 0;\r
-    StringTokenizer st = new StringTokenizer(string, ",");\r
-    String token;\r
-    while(st.hasMoreTokens())\r
-    {\r
-      token = st.nextToken().trim();\r
-      if(token.length()==0)\r
-        continue;\r
-\r
-      if(value==0)\r
-      {  try{\r
-          value =  new Float(token).floatValue();\r
-        }catch(NumberFormatException ex){}\r
-      }\r
-\r
-      if(token.length()==1)\r
-      {\r
-        // Either this character represents a helix or sheet\r
-        // or an integer which can be displayed\r
-        if(token.equals("H") || token.equals("E"))\r
-        {\r
-          ss = token.charAt(0);\r
-        }\r
-        else //if(value!=0)\r
-        {\r
-          displayChar = token;\r
-        }\r
-      }\r
-      else if(desc.length()<1)\r
-        desc = token;\r
-      else\r
-        displayChar = token;\r
-    }\r
-\r
-    return new Annotation(displayChar, desc, ss, value);\r
-  }\r
-\r
-  void colourAnnotations(AlignmentI al, String label, String colour)\r
-  {\r
-    UserColourScheme ucs = new UserColourScheme(colour);\r
-    Annotation[] annotations;\r
-    for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(label))\r
-      {\r
-        annotations = al.getAlignmentAnnotation()[i].annotations;\r
-        for(int j=0; j<annotations.length; j++)\r
-        {\r
-          if(annotations[j]!=null)\r
-            annotations[j].colour = ucs.findColour("A");\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  void combineAnnotations(AlignmentI al, StringTokenizer st)\r
-  {\r
-    int graphGroup = -1;\r
-    String group = st.nextToken();\r
-    //First make sure we are not overwriting the graphIndex\r
-    for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
-      {\r
-        graphGroup = al.getAlignmentAnnotation()[i].graphGroup +1;\r
-        al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
-        break;\r
-      }\r
-    }\r
-\r
-    //Now update groups\r
-    while(st.hasMoreTokens())\r
-    {\r
-      group = st.nextToken();\r
-      for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
-      {\r
-        if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
-        {\r
-          al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  void addLine(AlignmentI al, StringTokenizer st)\r
-  {\r
-    String group = st.nextToken();\r
-    AlignmentAnnotation annotation = null;\r
-\r
-    for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
-    {\r
-      if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
-      {\r
-        annotation = al.getAlignmentAnnotation()[i];\r
-        break;\r
-      }\r
-    }\r
-\r
-    if(annotation==null)\r
-      return;\r
-    float value = new Float(st.nextToken()).floatValue();\r
-    String label = st.hasMoreTokens() ?  st.nextToken() : null;\r
-    java.awt.Color colour = null;\r
-    if(st.hasMoreTokens())\r
-    {\r
-      UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
-      colour = ucs.findColour("A");\r
-    }\r
-\r
-    annotation.setThreshold(new GraphLine(value, label, colour));\r
-\r
-  }\r
-}\r
index 5f73898..4ac776d 100755 (executable)
-    /*\r
-    * Jalview - A Sequence Alignment Editor and Viewer\r
-    * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-    *\r
-    * This program is free software; you can redistribute it and/or\r
-    * modify it under the terms of the GNU General Public License\r
-    * as published by the Free Software Foundation; either version 2\r
-    * of the License, or (at your option) any later version.\r
-    *\r
-    * This program is distributed in the hope that it will be useful,\r
-    * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-    * GNU General Public License for more details.\r
-    *\r
-    * You should have received a copy of the GNU General Public License\r
-    * along with this program; if not, write to the Free Software\r
-    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-    */\r
-    package jalview.io;\r
-\r
-    import jalview.datamodel.*;\r
-\r
-    import java.util.Vector;\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @author $author$\r
-     * @version $Revision$\r
-     */\r
-    public class AppletFormatAdapter\r
-    {\r
-        /** DOCUMENT ME!! */\r
-        public static final Vector formats = new Vector();\r
-\r
-        public static String INVALID_CHARACTERS = "Contains invalid characters";\r
-\r
-        public static String SUPPORTED_FORMATS = "Formats currently supported are\n" +\r
-                                                 "Fasta, MSF, Clustal, BLC, PIR, MSP, and PFAM";\r
-\r
-        static\r
-        {\r
-            formats.addElement("BLC");\r
-            formats.addElement("CLUSTAL");\r
-            formats.addElement("FASTA");\r
-            formats.addElement("MSF");\r
-            formats.addElement("PileUp");\r
-            formats.addElement("PIR");\r
-            formats.addElement("PFAM");\r
-        }\r
-\r
-\r
-        public static String FILE = "File";\r
-        public static String URL = "URL";\r
-        public static String PASTE = "Paste";\r
-        public static String CLASSLOADER = "ClassLoader";\r
-\r
-        AlignFile afile = null;\r
-\r
-        /**\r
-         * DOCUMENT ME!\r
-         *\r
-         * @param inFile DOCUMENT ME!\r
-         * @param type DOCUMENT ME!\r
-         * @param format DOCUMENT ME!\r
-         *\r
-         * @return DOCUMENT ME!\r
-         */\r
-        public SequenceI[] readFile(String inFile, String type, String format)\r
-            throws java.io.IOException\r
-        {\r
-            try\r
-            {\r
-                if (format.equals("FASTA"))\r
-                {\r
-                    afile = new FastaFile(inFile, type);\r
-                }\r
-                else if (format.equals("MSF"))\r
-                {\r
-                    afile = new MSFfile(inFile, type);\r
-                }\r
-                else if (format.equals("PileUp"))\r
-                {\r
-                    afile = new PileUpfile(inFile, type);\r
-                }\r
-                else if (format.equals("CLUSTAL"))\r
-                {\r
-                    afile = new ClustalFile(inFile, type);\r
-                }\r
-                else if (format.equals("BLC"))\r
-                {\r
-                    afile = new BLCFile(inFile, type);\r
-                }\r
-                else if (format.equals("PIR"))\r
-                {\r
-                    afile = new PIRFile(inFile, type);\r
-                }\r
-                else if (format.equals("PFAM"))\r
-                {\r
-                    afile = new PfamFile(inFile, type);\r
-                }\r
-\r
-\r
-                return afile.getSeqsAsArray();\r
-            }\r
-            catch (Exception e)\r
-            {\r
-              System.err.println("Failed to read alignment using the '" + format +\r
-                                 "' reader.\n"+e);\r
-\r
-              if(e.getMessage()!=null && e.getMessage().startsWith(INVALID_CHARACTERS))\r
-                throw new java.io.IOException(e.getMessage());\r
-\r
-              // Finally test if the user has pasted just the sequence, no id\r
-              if(type.equalsIgnoreCase("Paste"))\r
-              {\r
-                try{\r
-                  // Possible sequence is just residues with no label\r
-                  afile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");\r
-                  return afile.getSeqsAsArray();\r
-                }\r
-                catch(Exception ex)\r
-                {\r
-                  if(ex.toString().startsWith(INVALID_CHARACTERS))\r
-                    throw new java.io.IOException(e.getMessage());\r
-\r
-                  ex.printStackTrace();\r
-                }\r
-              }\r
-\r
-              // If we get to this stage, the format was not supported\r
-              throw new java.io.IOException(SUPPORTED_FORMATS);\r
-            }\r
-        }\r
-\r
-\r
-        /**\r
-         * DOCUMENT ME!\r
-         *\r
-         * @param format DOCUMENT ME!\r
-         * @param seqs DOCUMENT ME!\r
-         *\r
-         * @return DOCUMENT ME!\r
-         */\r
-        public String formatSequences(String format,\r
-                                      Vector seqs,\r
-                                      boolean jvsuffix)\r
-        {\r
-            SequenceI[] s = new SequenceI[seqs.size()];\r
-\r
-            for (int i = 0; i < seqs.size(); i++)\r
-                s[i] = (SequenceI) seqs.elementAt(i);\r
-\r
-            try\r
-            {\r
-                AlignFile afile = null;\r
-\r
-                if (format.equalsIgnoreCase("FASTA"))\r
-                {\r
-                    afile = new FastaFile();\r
-                }\r
-                else if (format.equalsIgnoreCase("MSF"))\r
-                {\r
-                    afile = new MSFfile();\r
-                }\r
-                else if (format.equalsIgnoreCase("PileUp"))\r
-                {\r
-                    afile = new PileUpfile();\r
-                }\r
-                else if (format.equalsIgnoreCase("CLUSTAL"))\r
-                {\r
-                    afile = new ClustalFile();\r
-                }\r
-                else if (format.equalsIgnoreCase("BLC"))\r
-                {\r
-                    afile = new BLCFile();\r
-                }\r
-                else if (format.equalsIgnoreCase("PIR"))\r
-                {\r
-                    afile = new PIRFile();\r
-                }\r
-                else if (format.equalsIgnoreCase("PFAM"))\r
-                {\r
-                    afile = new PfamFile();\r
-                }\r
-\r
-                afile.addJVSuffix(jvsuffix);\r
-\r
-                afile.setSeqs(s);\r
-\r
-                return afile.print();\r
-            }\r
-            catch (Exception e)\r
-            {\r
-                System.err.println("Failed to write alignment as a '" + format +\r
-                    "' file\n");\r
-                e.printStackTrace();\r
-            }\r
-\r
-            return null;\r
-        }\r
-    }\r
+    /*
+    * Jalview - A Sequence Alignment Editor and Viewer
+    * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+    *
+    * This program 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 2
+    * of the License, or (at your option) any later version.
+    *
+    * This program 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 this program; if not, write to the Free Software
+    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+    */
+    package jalview.io;
+
+    import jalview.datamodel.*;
+
+    import java.util.Vector;
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @author $author$
+     * @version $Revision$
+     */
+    public class AppletFormatAdapter
+    {
+        /** DOCUMENT ME!! */
+        public static final String [] READABLE_FORMATS = new String[]
+        {
+            "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", "PDB"
+        };
+
+        public static final String [] WRITEABLE_FORMATS = new String[]
+            {
+            "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM"
+        };
+
+
+        public static String INVALID_CHARACTERS = "Contains invalid characters";
+
+        public static String SUPPORTED_FORMATS = "Formats currently supported are\n" +
+                                                 "Fasta, MSF, Clustal, BLC, PIR, MSP, and PFAM";
+
+
+        public static String FILE = "File";
+        public static String URL = "URL";
+        public static String PASTE = "Paste";
+        public static String CLASSLOADER = "ClassLoader";
+
+
+        AlignFile afile = null;
+        String inFile;
+
+        public static final boolean isValidFormat(String format)
+        {
+          boolean valid = false;
+          for(int i=0; i<READABLE_FORMATS.length; i++)
+            if(READABLE_FORMATS[i].equalsIgnoreCase(format))
+              return true;
+
+          return valid;
+        }
+
+        /**
+         * DOCUMENT ME!
+         *
+         * @param inFile DOCUMENT ME!
+         * @param type DOCUMENT ME!
+         * @param format DOCUMENT ME!
+         *
+         * @return DOCUMENT ME!
+         */
+        public SequenceI[] readFile(String inFile, String type, String format)
+            throws java.io.IOException
+        {
+            this.inFile = inFile;
+            try
+            {
+              if (format.equals("FASTA"))
+              {
+                afile = new FastaFile(inFile, type);
+              }
+              else if (format.equals("MSF"))
+              {
+                afile = new MSFfile(inFile, type);
+              }
+              else if (format.equals("PileUp"))
+              {
+                afile = new PileUpfile(inFile, type);
+              }
+              else if (format.equals("CLUSTAL"))
+              {
+                afile = new ClustalFile(inFile, type);
+              }
+              else if (format.equals("BLC"))
+              {
+                afile = new BLCFile(inFile, type);
+              }
+              else if (format.equals("PIR"))
+              {
+                afile = new PIRFile(inFile, type);
+              }
+              else if (format.equals("PFAM"))
+              {
+                afile = new PfamFile(inFile, type);
+              }
+              else if (format.equals("JnetFile"))
+              {
+                afile = new JPredFile(inFile, type);
+                ( (JPredFile) afile).removeNonSequences();
+              }
+              else if (format.equals("PDB"))
+              {
+                afile = new MCview.PDBfile(inFile, type);
+              }
+              else if (format.equals("STH"))
+              {
+                afile = new StockholmFile(inFile, type);
+              }
+
+
+              return afile.getSeqsAsArray();
+            }
+            catch (Exception e)
+            {
+              e.printStackTrace();
+              System.err.println("Failed to read alignment using the '" + format +
+                                 "' reader.\n"+e);
+
+              if(e.getMessage()!=null && e.getMessage().startsWith(INVALID_CHARACTERS))
+                throw new java.io.IOException(e.getMessage());
+
+              // Finally test if the user has pasted just the sequence, no id
+              if(type.equalsIgnoreCase("Paste"))
+              {
+                try{
+                  // Possible sequence is just residues with no label
+                  afile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
+                  return afile.getSeqsAsArray();
+                }
+                catch(Exception ex)
+                {
+                  if(ex.toString().startsWith(INVALID_CHARACTERS))
+                    throw new java.io.IOException(e.getMessage());
+
+                  ex.printStackTrace();
+                }
+              }
+
+              // If we get to this stage, the format was not supported
+              throw new java.io.IOException(SUPPORTED_FORMATS);
+            }
+        }
+
+
+        /**
+         * DOCUMENT ME!
+         *
+         * @param format DOCUMENT ME!
+         * @param seqs DOCUMENT ME!
+         *
+         * @return DOCUMENT ME!
+         */
+        public String formatSequences(String format,
+                                      Vector seqs,
+                                      boolean jvsuffix)
+        {
+            SequenceI[] s = new SequenceI[seqs.size()];
+
+            for (int i = 0; i < seqs.size(); i++)
+                s[i] = (SequenceI) seqs.elementAt(i);
+
+            try
+            {
+                AlignFile afile = null;
+
+                if (format.equalsIgnoreCase("FASTA"))
+                {
+                    afile = new FastaFile();
+                }
+                else if (format.equalsIgnoreCase("MSF"))
+                {
+                    afile = new MSFfile();
+                }
+                else if (format.equalsIgnoreCase("PileUp"))
+                {
+                    afile = new PileUpfile();
+                }
+                else if (format.equalsIgnoreCase("CLUSTAL"))
+                {
+                    afile = new ClustalFile();
+                }
+                else if (format.equalsIgnoreCase("BLC"))
+                {
+                    afile = new BLCFile();
+                }
+                else if (format.equalsIgnoreCase("PIR"))
+                {
+                    afile = new PIRFile();
+                }
+                else if (format.equalsIgnoreCase("PFAM"))
+                {
+                    afile = new PfamFile();
+                }
+                else if (format.equalsIgnoreCase("STH"))
+                {
+                  afile = new StockholmFile();
+                }
+
+
+                afile.addJVSuffix(jvsuffix);
+
+                afile.setSeqs(s);
+
+                return afile.print();
+            }
+            catch (Exception e)
+            {
+                System.err.println("Failed to write alignment as a '" + format +
+                    "' file\n");
+                e.printStackTrace();
+            }
+
+            return null;
+        }
+    }
index 56d40f9..2176ec8 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class BLCFile extends AlignFile\r
-{\r
-    Vector titles;\r
-\r
-    /**\r
-     * Creates a new BLCFile object.\r
-     */\r
-    public BLCFile()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Creates a new BLCFile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public BLCFile(String inStr)\r
-    {\r
-        super(inStr);\r
-    }\r
-\r
-    /**\r
-     * Creates a new BLCFile object.\r
-     *\r
-     * @param inFile DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public BLCFile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void initData()\r
-    {\r
-        super.initData();\r
-        titles = new Vector();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void parse() throws IOException\r
-    {\r
-        boolean idsFound = false;\r
-        Vector ids = new Vector();\r
-        StringBuffer[] seqstrings;\r
-        Vector starts = new Vector();\r
-        Vector ends = new Vector();\r
-\r
-        String line = null;\r
-\r
-            do\r
-            {\r
-                line = nextLine();\r
-\r
-                // seek end of ids\r
-                if (line.indexOf("*") > -1)\r
-                {\r
-                    idsFound = true;\r
-\r
-                    break;\r
-                }\r
-\r
-                int abracket = line.indexOf(">");\r
-\r
-                if (abracket > -1)\r
-                {\r
-                  if (line.indexOf(" ") > -1) //\r
-                  {\r
-                    line = line.substring(abracket + 1,\r
-                                          line.indexOf(" ", abracket + 1));\r
-                  }\r
-                  else\r
-                    line = line.substring(abracket+1);\r
-\r
-\r
-                  Sequence seq = parseId(line);\r
-                  ids.addElement(seq.getName());\r
-                  starts.addElement(seq.getStart() + "");\r
-                  ends.addElement(seq.getEnd() + "");\r
-                }\r
-            }\r
-            while (!idsFound);\r
-\r
-            int starCol = line.indexOf("*");\r
-            seqstrings = new StringBuffer[ids.size()];\r
-\r
-            for (int i = 0; i < ids.size(); i++)\r
-            {\r
-                if (seqstrings[i] == null)\r
-                {\r
-                    seqstrings[i] = new StringBuffer();\r
-                }\r
-            }\r
-\r
-            while ((line = nextLine()).indexOf("*") == -1)\r
-            {\r
-                for (int i = 0; i < ids.size(); i++)\r
-                {\r
-                    if (line.length() > (i + starCol))\r
-                    {\r
-                        seqstrings[i].append(line.charAt(i + starCol));\r
-                    }\r
-                }\r
-            }\r
-\r
-            for (int i = 0; i < ids.size(); i++)\r
-            {\r
-              Sequence newSeq = new Sequence(ids.elementAt(i).toString(),\r
-                                             seqstrings[i].toString(),\r
-                                             Integer.parseInt(starts.elementAt(i).\r
-                                                              toString()),\r
-                                             Integer.parseInt(ends.elementAt(i).toString()));\r
-\r
-              if (!isValidProteinSequence(newSeq.getSequence()))\r
-              {\r
-                throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
-                               +" : "+ newSeq.getName()\r
-                               +" : "+invalidCharacter);\r
-\r
-              }\r
-\r
-                seqs.addElement(newSeq);\r
-            }\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String print()\r
-    {\r
-        return print(getSeqsAsArray());\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String print(SequenceI[] s)\r
-    {\r
-        StringBuffer out = new StringBuffer();\r
-        /**\r
-         * A general parser for ids. Will look for dbrefs in\r
-         * Uniprot format source|id\r
-         * And also Jalview /start-end\r
-         *\r
-         * @String id Id to be parsed\r
-     */\r
-        int i = 0;\r
-        int max = -1;\r
-\r
-        while ((i < s.length) && (s[i] != null))\r
-        {\r
-            out.append(">" + printId(s[i]) +"\n");\r
-\r
-            if (s[i].getSequence().length() > max)\r
-            {\r
-                max = s[i].getSequence().length();\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        out.append("* iteration 1\n");\r
-\r
-        for (int j = 0; j < max; j++)\r
-        {\r
-            i = 0;\r
-\r
-            while ((i < s.length) && (s[i] != null))\r
-            {\r
-                if (s[i].getSequence().length() > j)\r
-                {\r
-                    out.append(s[i].getSequence().substring(j, j + 1));\r
-                }\r
-                else\r
-                {\r
-                    out.append("-");\r
-                }\r
-\r
-                i++;\r
-            }\r
-\r
-            out.append("\n");\r
-        }\r
-\r
-        out.append("*\n");\r
-\r
-        return out.toString();\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import jalview.datamodel.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class BLCFile extends AlignFile
+{
+    Vector titles;
+
+    /**
+     * Creates a new BLCFile object.
+     */
+    public BLCFile()
+    {
+    }
+
+
+    /**
+     * Creates a new BLCFile object.
+     *
+     * @param inFile DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public BLCFile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void initData()
+    {
+        super.initData();
+        titles = new Vector();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void parse() throws IOException
+    {
+        boolean idsFound = false;
+        Vector ids = new Vector();
+        StringBuffer[] seqstrings;
+        Vector starts = new Vector();
+        Vector ends = new Vector();
+
+        String line = null;
+
+            do
+            {
+                line = nextLine();
+
+                // seek end of ids
+                if (line.indexOf("*") > -1)
+                {
+                    idsFound = true;
+
+                    break;
+                }
+
+                int abracket = line.indexOf(">");
+
+                if (abracket > -1)
+                {
+                  if (line.indexOf(" ") > -1) //
+                  {
+                    line = line.substring(abracket + 1,
+                                          line.indexOf(" ", abracket + 1));
+                  }
+                  else
+                    line = line.substring(abracket+1);
+
+
+                  Sequence seq = parseId(line);
+                  ids.addElement(seq.getName());
+                  starts.addElement(seq.getStart() + "");
+                  ends.addElement(seq.getEnd() + "");
+                }
+            }
+            while (!idsFound);
+
+            int starCol = line.indexOf("*");
+            seqstrings = new StringBuffer[ids.size()];
+
+            for (int i = 0; i < ids.size(); i++)
+            {
+                if (seqstrings[i] == null)
+                {
+                    seqstrings[i] = new StringBuffer();
+                }
+            }
+
+            while ((line = nextLine()).indexOf("*") == -1)
+            {
+                for (int i = 0; i < ids.size(); i++)
+                {
+                    if (line.length() > (i + starCol))
+                    {
+                        seqstrings[i].append(line.charAt(i + starCol));
+                    }
+                }
+            }
+
+            for (int i = 0; i < ids.size(); i++)
+            {
+              Sequence newSeq = new Sequence(ids.elementAt(i).toString(),
+                                             seqstrings[i].toString(),
+                                             Integer.parseInt(starts.elementAt(i).
+                                                              toString()),
+                                             Integer.parseInt(ends.elementAt(i).toString()));
+
+              if (!isValidProteinSequence(newSeq.getSequence()))
+              {
+                throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS
+                               +" : "+ newSeq.getName()
+                               +" : "+invalidCharacter);
+
+              }
+
+                seqs.addElement(newSeq);
+            }
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String print()
+    {
+        return print(getSeqsAsArray());
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String print(SequenceI[] s)
+    {
+        StringBuffer out = new StringBuffer();
+        /**
+         * A general parser for ids. Will look for dbrefs in
+         * Uniprot format source|id
+         * And also Jalview /start-end
+         *
+         * @String id Id to be parsed
+     */
+        int i = 0;
+        int max = -1;
+
+        while ((i < s.length) && (s[i] != null))
+        {
+            out.append(">" + printId(s[i]) +"\n");
+
+            if (s[i].getSequence().length() > max)
+            {
+                max = s[i].getSequence().length();
+            }
+
+            i++;
+        }
+
+        out.append("* iteration 1\n");
+
+        for (int j = 0; j < max; j++)
+        {
+            i = 0;
+
+            while ((i < s.length) && (s[i] != null))
+            {
+                if (s[i].getSequence().length() > j)
+                {
+                    out.append(s[i].getSequence().substring(j, j + 1));
+                }
+                else
+                {
+                    out.append("-");
+                }
+
+                i++;
+            }
+
+            out.append("\n");
+        }
+
+        out.append("*\n");
+
+        return out.toString();
+    }
+}
index 2ea1d2f..58b7dd1 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.util.*;\r
-\r
-public class ClustalFile\r
-    extends AlignFile\r
-{\r
-\r
-  public ClustalFile()\r
-  {\r
-  }\r
-\r
-  public ClustalFile(String inStr)\r
-  {\r
-    super(inStr);\r
-  }\r
-\r
-  public ClustalFile(String inFile, String type)\r
-      throws IOException\r
-  {\r
-    super(inFile, type);\r
-  }\r
-\r
-  public void initData()\r
-  {\r
-    super.initData();\r
-  }\r
-\r
-  public void parse() throws IOException\r
-  {\r
-    int i = 0;\r
-    boolean flag = false;\r
-\r
-    Vector headers = new Vector();\r
-    Hashtable seqhash = new Hashtable();\r
-    StringBuffer tempseq;\r
-    String line, id;\r
-    StringTokenizer str;\r
-\r
-    try\r
-    {\r
-      while ( (line = nextLine()) != null)\r
-      {\r
-        if (line.indexOf(" ") != 0)\r
-        {\r
-          str = new StringTokenizer(line, " ");\r
-\r
-          if (str.hasMoreTokens())\r
-          {\r
-            id = str.nextToken();\r
-\r
-            if (id.equalsIgnoreCase("CLUSTAL"))\r
-            {\r
-              flag = true;\r
-            }\r
-            else\r
-            {\r
-              if (flag)\r
-              {\r
-                if (seqhash.containsKey(id))\r
-                {\r
-                  tempseq = (StringBuffer) seqhash.get(id);\r
-                }\r
-                else\r
-                {\r
-                  tempseq = new StringBuffer();\r
-                  seqhash.put(id, tempseq);\r
-                }\r
-\r
-                if (! (headers.contains(id)))\r
-                {\r
-                  headers.addElement(id);\r
-                }\r
-\r
-                if (str.hasMoreTokens())\r
-                {\r
-                  tempseq.append(str.nextToken());\r
-                }\r
-              }\r
-            }\r
-          }\r
-          else\r
-            flag = true;\r
-        }\r
-      }\r
-    }\r
-    catch (IOException e)\r
-    {\r
-      System.err.println("Exception parsing clustal file " + e);\r
-      e.printStackTrace();\r
-    }\r
-\r
-    if (flag)\r
-    {\r
-      this.noSeqs = headers.size();\r
-\r
-      //Add sequences to the hash\r
-      for (i = 0; i < headers.size(); i++)\r
-      {\r
-        if (seqhash.get(headers.elementAt(i)) != null)\r
-        {\r
-          if (maxLength < seqhash.get(headers.elementAt(i)).toString()\r
-              .length())\r
-          {\r
-            maxLength = seqhash.get(headers.elementAt(i)).toString()\r
-                .length();\r
-          }\r
-\r
-          Sequence newSeq = parseId(headers.elementAt(i).toString());\r
-          newSeq.setSequence( seqhash.get(headers.elementAt(i).toString()).toString() );\r
-\r
-          if (!isValidProteinSequence(newSeq.getSequence()))\r
-          {\r
-              throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
-                                    + " : " + newSeq.getName()\r
-                                    + " : " + invalidCharacter);\r
-          }\r
-\r
-\r
-          seqs.addElement(newSeq);\r
-        }\r
-        else\r
-        {\r
-          System.err.println(\r
-              "Clustal File Reader: Can't find sequence for " +\r
-              headers.elementAt(i));\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  public String print()\r
-  {\r
-    return print(getSeqsAsArray());\r
-  }\r
-\r
-  public String print(SequenceI[] s)\r
-  {\r
-    StringBuffer out = new StringBuffer("CLUSTAL\n\n");\r
-\r
-    int max = 0;\r
-    int maxid = 0;\r
-\r
-    int i = 0;\r
-\r
-    while ( (i < s.length) && (s[i] != null))\r
-    {\r
-      String tmp = printId(s[i]);\r
-\r
-      if (s[i].getSequence().length() > max)\r
-      {\r
-        max = s[i].getSequence().length();\r
-      }\r
-\r
-      if (tmp.length() > maxid)\r
-      {\r
-        maxid = tmp.length();\r
-      }\r
-\r
-      i++;\r
-    }\r
-\r
-    if (maxid < 15)\r
-    {\r
-      maxid = 15;\r
-    }\r
-\r
-    maxid++;\r
-\r
-    int len = 60;\r
-    int nochunks = (max / len) + 1;\r
-\r
-    for (i = 0; i < nochunks; i++)\r
-    {\r
-      int j = 0;\r
-\r
-      while ( (j < s.length) && (s[j] != null))\r
-      {\r
-        out.append(new Format("%-" + maxid + "s").form( printId(s[j]) + " "));\r
-\r
-        int start = i * len;\r
-        int end = start + len;\r
-\r
-        if ( (end < s[j].getSequence().length()) &&\r
-            (start < s[j].getSequence().length()))\r
-        {\r
-          out.append(s[j].getSequence().substring(start, end));\r
-        }\r
-        else\r
-        {\r
-          if (start < s[j].getSequence().length())\r
-          {\r
-            out.append(s[j].getSequence().substring(start));\r
-          }\r
-        }\r
-\r
-        out.append("\n");\r
-        j++;\r
-      }\r
-\r
-      out.append("\n");\r
-    }\r
-\r
-    return out.toString();\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+import java.util.*;
+
+import jalview.datamodel.*;
+import jalview.util.*;
+
+public class ClustalFile
+    extends AlignFile
+{
+
+  public ClustalFile()
+  {
+  }
+
+  public ClustalFile(String inFile, String type)
+      throws IOException
+  {
+    super(inFile, type);
+  }
+
+  public void initData()
+  {
+    super.initData();
+  }
+
+  public void parse() throws IOException
+  {
+    int i = 0;
+    boolean flag = false;
+
+    Vector headers = new Vector();
+    Hashtable seqhash = new Hashtable();
+    StringBuffer tempseq;
+    String line, id;
+    StringTokenizer str;
+
+    try
+    {
+      while ( (line = nextLine()) != null)
+      {
+        if (line.indexOf(" ") != 0)
+        {
+          str = new StringTokenizer(line, " ");
+
+          if (str.hasMoreTokens())
+          {
+            id = str.nextToken();
+
+            if (id.equalsIgnoreCase("CLUSTAL"))
+            {
+              flag = true;
+            }
+            else
+            {
+              if (flag)
+              {
+                if (seqhash.containsKey(id))
+                {
+                  tempseq = (StringBuffer) seqhash.get(id);
+                }
+                else
+                {
+                  tempseq = new StringBuffer();
+                  seqhash.put(id, tempseq);
+                }
+
+                if (! (headers.contains(id)))
+                {
+                  headers.addElement(id);
+                }
+
+                if (str.hasMoreTokens())
+                {
+                  tempseq.append(str.nextToken());
+                }
+              }
+            }
+          }
+          else
+            flag = true;
+        }
+      }
+    }
+    catch (IOException e)
+    {
+      System.err.println("Exception parsing clustal file " + e);
+      e.printStackTrace();
+    }
+
+    if (flag)
+    {
+      this.noSeqs = headers.size();
+
+      //Add sequences to the hash
+      for (i = 0; i < headers.size(); i++)
+      {
+        if (seqhash.get(headers.elementAt(i)) != null)
+        {
+          if (maxLength < seqhash.get(headers.elementAt(i)).toString()
+              .length())
+          {
+            maxLength = seqhash.get(headers.elementAt(i)).toString()
+                .length();
+          }
+
+          Sequence newSeq = parseId(headers.elementAt(i).toString());
+          newSeq.setSequence( seqhash.get(headers.elementAt(i).toString()).toString() );
+
+          if (!isValidProteinSequence(newSeq.getSequence()))
+          {
+              throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS
+                                    + " : " + newSeq.getName()
+                                    + " : " + invalidCharacter);
+          }
+
+
+          seqs.addElement(newSeq);
+        }
+        else
+        {
+          System.err.println(
+              "Clustal File Reader: Can't find sequence for " +
+              headers.elementAt(i));
+        }
+      }
+    }
+  }
+
+  public String print()
+  {
+    return print(getSeqsAsArray());
+  }
+
+  public String print(SequenceI[] s)
+  {
+    StringBuffer out = new StringBuffer("CLUSTAL\n\n");
+
+    int max = 0;
+    int maxid = 0;
+
+    int i = 0;
+
+    while ( (i < s.length) && (s[i] != null))
+    {
+      String tmp = printId(s[i]);
+
+      if (s[i].getSequence().length() > max)
+      {
+        max = s[i].getSequence().length();
+      }
+
+      if (tmp.length() > maxid)
+      {
+        maxid = tmp.length();
+      }
+
+      i++;
+    }
+
+    if (maxid < 15)
+    {
+      maxid = 15;
+    }
+
+    maxid++;
+
+    int len = 60;
+    int nochunks = (max / len) + 1;
+
+    for (i = 0; i < nochunks; i++)
+    {
+      int j = 0;
+
+      while ( (j < s.length) && (s[j] != null))
+      {
+        out.append(new Format("%-" + maxid + "s").form( printId(s[j]) + " "));
+
+        int start = i * len;
+        int end = start + len;
+
+        if ( (end < s[j].getSequence().length()) &&
+            (start < s[j].getSequence().length()))
+        {
+          out.append(s[j].getSequence().substring(start, end));
+        }
+        else
+        {
+          if (start < s[j].getSequence().length())
+          {
+            out.append(s[j].getSequence().substring(start));
+          }
+        }
+
+        out.append("\n");
+        j++;
+      }
+
+      out.append("\n");
+    }
+
+    return out.toString();
+  }
+}
index 0012ffe..517b4f7 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-\r
-import org.apache.axis.AxisFault;\r
-import org.apache.axis.client.*;\r
-import org.apache.axis.encoding.XMLType;\r
-import org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory;\r
-import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory;\r
-\r
-import javax.activation.DataHandler;\r
-\r
-import javax.xml.namespace.QName;\r
-import javax.xml.rpc.ParameterMode;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class EBIFetchClient\r
-{\r
-    Call call;\r
-    String format = "default";\r
-    String style = "raw";\r
-\r
-    /**\r
-     * Creates a new EBIFetchClient object.\r
-     */\r
-    public EBIFetchClient()\r
-    {\r
-        try\r
-        {\r
-            call = (Call) new Service().createCall();\r
-            call.setTargetEndpointAddress(new java.net.URL(\r
-                    "http://www.ebi.ac.uk/ws/services/Dbfetch"));\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String[] getSupportedDBs()\r
-    {\r
-        try\r
-        {\r
-            call.setOperationName(new QName("urn:Dbfetch", "getSupportedDBs"));\r
-            call.setReturnType(XMLType.SOAP_ARRAY);\r
-\r
-            return (String[]) call.invoke(new Object[] {  });\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String[] getSupportedFormats()\r
-    {\r
-        try\r
-        {\r
-            call.setOperationName(new QName("urn:Dbfetch", "getSupportedFormats"));\r
-            call.setReturnType(XMLType.SOAP_ARRAY);\r
-\r
-            return (String[]) call.invoke(new Object[] {  });\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String[] getSupportedStyles()\r
-    {\r
-        try\r
-        {\r
-            call.setOperationName(new QName("urn:Dbfetch", "getSupportedStyles"));\r
-            call.setReturnType(XMLType.SOAP_ARRAY);\r
-\r
-            return (String[]) call.invoke(new Object[] {  });\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    public static void main (String [] args)\r
-    {\r
-      EBIFetchClient ebi = new EBIFetchClient();\r
-      String[] result = ebi.fetchData("uniprot:25K89D_SARPE;G6PblobD_HUMAN",\r
-                           "xml", null);\r
-\r
-     try{\r
-       java.io.PrintWriter out = new java.io.PrintWriter(\r
-      new java.io.FileWriter("out.xml"));\r
-\r
-\r
-       for(int i=0; i<result.length; i++)\r
-       {\r
-         out.println(result[i]);\r
-       }\r
-       out.close();\r
-     }catch(Exception ex){ex.printStackTrace();}\r
-\r
-    }\r
-\r
-\r
-    public File fetchDataAsFile(String ids, String f, String s)\r
-    {\r
-      String [] data = fetchData(ids, f, s);\r
-      File outFile = null;\r
-      try{\r
-        outFile = File.createTempFile("jalview", ".xml");\r
-        outFile.deleteOnExit();\r
-        PrintWriter out = new PrintWriter(new FileOutputStream(outFile));\r
-        int index=0;\r
-        while( index < data.length )\r
-        {\r
-          out.println(data[index]);\r
-          index++;\r
-        }\r
-        out.close();\r
-      }catch(Exception ex){}\r
-      return outFile;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ids DOCUMENT ME!\r
-     * @param f DOCUMENT ME!\r
-     * @param s DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String[] fetchData(String ids, String f, String s)\r
-    {\r
-        // ids should be of the form uniprot:25KD_SARPE;ADHR_DROPS;\r
-        // max 50 ids can be added at one time\r
-        try\r
-        {\r
-            call.setOperationName(new QName("urn:Dbfetch", "fetchData"));\r
-            call.addParameter("query", XMLType.XSD_STRING, ParameterMode.IN);\r
-            call.addParameter("format", XMLType.XSD_STRING, ParameterMode.IN);\r
-            call.addParameter("style", XMLType.XSD_STRING, ParameterMode.IN);\r
-            call.setReturnType(XMLType.SOAP_ARRAY);\r
-\r
-            if (f != null)\r
-            {\r
-                format = f;\r
-            }\r
-\r
-            if (s != null)\r
-            {\r
-                style = s;\r
-            }\r
-\r
-            return (String[]) call.invoke(new Object[] { ids, format, style });\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param arg DOCUMENT ME!\r
-     * @param f DOCUMENT ME!\r
-     * @param s DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String fetchDataFile(String arg, String f, String s)\r
-    {\r
-        if (f != null)\r
-        {\r
-            format = f;\r
-        }\r
-\r
-        if (s != null)\r
-        {\r
-            style = s;\r
-        }\r
-\r
-        call.setOperationName(new QName("urn:Dbfetch", "fetchDataFile"));\r
-        call.addParameter("query", XMLType.XSD_STRING, ParameterMode.IN);\r
-        call.addParameter("format", XMLType.XSD_STRING, ParameterMode.IN);\r
-        call.addParameter("style", XMLType.XSD_STRING, ParameterMode.IN);\r
-\r
-        QName qnameAttachment = new QName("urn:Dbfetch", "DataHandler");\r
-        call.registerTypeMapping(javax.activation.DataSource.class,\r
-            qnameAttachment, JAFDataHandlerSerializerFactory.class,\r
-            JAFDataHandlerDeserializerFactory.class);\r
-\r
-        call.setReturnType(qnameAttachment);\r
-\r
-        try\r
-        {\r
-            Object ret = call.invoke(new Object[] { arg, format, style });\r
-\r
-            if (null == ret)\r
-            {\r
-                System.err.println("Received null ");\r
-                throw new AxisFault("", "Received null", null, null);\r
-            }\r
-\r
-            if (ret instanceof String)\r
-            {\r
-                System.err.println("Received problem response from server: " +\r
-                    ret);\r
-                throw new AxisFault("", (String) ret, null, null);\r
-            }\r
-\r
-            if (!(ret instanceof DataHandler))\r
-            {\r
-                //The wrong type of object that what was expected.\r
-                System.err.println("Received problem response from server:" +\r
-                    ret.getClass().getName());\r
-                throw new AxisFault("",\r
-                    "Received problem response from server:" +\r
-                    ret.getClass().getName(), null, null);\r
-            }\r
-\r
-            //Still here, so far so good.\r
-            DataHandler rdh = (DataHandler) ret;\r
-\r
-            //From here we'll just treat the data resource as file.\r
-            String receivedfileName = rdh.getName(); //Get the filename.\r
-\r
-            if (receivedfileName == null)\r
-            {\r
-                System.err.println("Could not get the file name.");\r
-                throw new AxisFault("", "Could not get the file name.", null,\r
-                    null);\r
-            }\r
-\r
-            if (arg.equalsIgnoreCase("medline"))\r
-            {\r
-                return receivedfileName;\r
-            }\r
-            else if (arg.equalsIgnoreCase("interpro"))\r
-            {\r
-                return receivedfileName;\r
-            }\r
-            else\r
-            {\r
-                System.err.println(receivedfileName);\r
-            }\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-\r
-        return "ERROR";\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import java.io.*;
+
+import org.apache.axis.client.*;
+import org.apache.axis.encoding.XMLType;
+
+import javax.xml.namespace.QName;
+import javax.xml.rpc.ParameterMode;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class EBIFetchClient
+{
+    Call call;
+    String format = "default";
+    String style = "raw";
+
+    /**
+     * Creates a new EBIFetchClient object.
+     */
+    public EBIFetchClient()
+    {
+        try
+        {
+            call = (Call) new Service().createCall();
+            call.setTargetEndpointAddress(new java.net.URL(
+                    "http://www.ebi.ac.uk/ws/services/Dbfetch"));
+        }
+        catch (Exception ex)
+        {
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String[] getSupportedDBs()
+    {
+        try
+        {
+            call.setOperationName(new QName("urn:Dbfetch", "getSupportedDBs"));
+            call.setReturnType(XMLType.SOAP_ARRAY);
+
+            return (String[]) call.invoke(new Object[] {  });
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String[] getSupportedFormats()
+    {
+        try
+        {
+            call.setOperationName(new QName("urn:Dbfetch", "getSupportedFormats"));
+            call.setReturnType(XMLType.SOAP_ARRAY);
+
+            return (String[]) call.invoke(new Object[] {  });
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String[] getSupportedStyles()
+    {
+        try
+        {
+            call.setOperationName(new QName("urn:Dbfetch", "getSupportedStyles"));
+            call.setReturnType(XMLType.SOAP_ARRAY);
+
+            return (String[]) call.invoke(new Object[] {  });
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+    }
+
+    public static void main (String [] args)
+    {
+      EBIFetchClient ebi = new EBIFetchClient();
+      String[] result = ebi.fetchData("uniprot:25KD_SARPE;G6PD_HUMAN",
+                           "xml", null);
+
+     try{
+       java.io.PrintWriter out = new java.io.PrintWriter(
+      new java.io.FileWriter("out.xml"));
+
+
+       for(int i=0; i<result.length; i++)
+       {
+         out.println(result[i]);
+       }
+       out.close();
+     }catch(Exception ex){ex.printStackTrace();}
+
+    }
+
+
+    public File fetchDataAsFile(String ids, String f, String s)
+    {
+      String [] data = fetchData(ids, f, s);
+      File outFile = null;
+      try{
+        outFile = File.createTempFile("jalview", ".xml");
+        outFile.deleteOnExit();
+        PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
+        int index=0;
+        while( index < data.length )
+        {
+          out.println(data[index]);
+          index++;
+        }
+        out.close();
+      }catch(Exception ex){}
+      return outFile;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ids DOCUMENT ME!
+     * @param f DOCUMENT ME!
+     * @param s DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String[] fetchData(String ids, String f, String s)
+    {
+        // ids should be of the form uniprot:25KD_SARPE;ADHR_DROPS;
+        // max 50 ids can be added at one time
+        try
+        {
+            call.setOperationName(new QName("urn:Dbfetch", "fetchData"));
+            call.addParameter("query", XMLType.XSD_STRING, ParameterMode.IN);
+            call.addParameter("format", XMLType.XSD_STRING, ParameterMode.IN);
+            call.addParameter("style", XMLType.XSD_STRING, ParameterMode.IN);
+            call.setReturnType(XMLType.SOAP_ARRAY);
+
+            if (f != null)
+            {
+                format = f;
+            }
+
+            if (s != null)
+            {
+                style = s;
+            }
+
+            return (String[]) call.invoke(new Object[] { ids, format, style });
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+    }
+}
index 6d218f4..47ed528 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.io.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class FastaFile extends AlignFile\r
-{\r
-    /**\r
-     * Creates a new FastaFile object.\r
-     */\r
-    public FastaFile()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Creates a new FastaFile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public FastaFile(String inStr)\r
-    {\r
-        super(inStr);\r
-    }\r
-\r
-    /**\r
-     * Creates a new FastaFile object.\r
-     *\r
-     * @param inFile DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public FastaFile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public void parse() throws IOException\r
-    {\r
-        StringBuffer sb = new StringBuffer();\r
-        int count = 0;\r
-\r
-        String line;\r
-        Sequence seq = null;\r
-\r
-        while ((line = nextLine()) != null)\r
-        {\r
-            line = line.trim();\r
-            if (line.length() > 0)\r
-            {\r
-                if (line.charAt(0)=='>')\r
-                {\r
-                    if (count != 0)\r
-                    {\r
-                      if (!isValidProteinSequence(sb.toString()))\r
-                      {\r
-                        throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
-                                              +" : "+seq.getName()\r
-                                              +" : "+invalidCharacter);\r
-                      }\r
-\r
-                       seq.setSequence(sb.toString());\r
-                       seqs.addElement(seq);\r
-                    }\r
-\r
-                    seq = parseId(line.substring(1));\r
-\r
-                    count++;\r
-                    sb = new StringBuffer();\r
-                }\r
-                else\r
-                {\r
-                    sb.append(line);\r
-                }\r
-            }\r
-        }\r
-\r
-        if (count > 0)\r
-        {\r
-            if (!isValidProteinSequence(sb.toString()))\r
-            {\r
-                throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
-                                      +" : "+seq.getName()\r
-                                      +" : "+invalidCharacter);\r
-            }\r
-\r
-            seq.setSequence(sb.toString());\r
-            seqs.addElement(seq);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param len DOCUMENT ME!\r
-     * @param gaps DOCUMENT ME!\r
-     * @param displayId DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String print(SequenceI[] s)\r
-    {\r
-        int len = 72;\r
-        StringBuffer out = new StringBuffer();\r
-        int i = 0;\r
-\r
-        while ((i < s.length) && (s[i] != null))\r
-        {\r
-            out.append(">" + printId(s[i]));\r
-            if(s[i].getDescription()!=null)\r
-              out.append(" "+s[i].getDescription());\r
-\r
-            out.append("\n");\r
-\r
-            int nochunks = (s[i].getLength() / len) + 1;\r
-\r
-            for (int j = 0; j < nochunks; j++)\r
-            {\r
-                int start = j * len;\r
-                int end = start + len;\r
-\r
-                if (end < s[i].getLength())\r
-                {\r
-                    out.append(s[i].getSequence(start, end) + "\n");\r
-                }\r
-                else if (start < s[i].getLength())\r
-                {\r
-                    out.append(s[i].getSequence(start, s[i].getLength()) + "\n");\r
-                }\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        return out.toString();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String print()\r
-    {\r
-        return print(getSeqsAsArray());\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import jalview.datamodel.*;
+
+import java.io.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class FastaFile extends AlignFile
+{
+    /**
+     * Creates a new FastaFile object.
+     */
+    public FastaFile()
+    {
+    }
+
+    /**
+     * Creates a new FastaFile object.
+     *
+     * @param inFile DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public FastaFile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public void parse() throws IOException
+    {
+        StringBuffer sb = new StringBuffer();
+        int count = 0;
+
+        String line;
+        Sequence seq = null;
+
+        while ((line = nextLine()) != null)
+        {
+            line = line.trim();
+            if (line.length() > 0)
+            {
+                if (line.charAt(0)=='>')
+                {
+                    if (count != 0)
+                    {
+                      if (!isValidProteinSequence(sb.toString()))
+                      {
+                        throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS
+                                              +" : "+seq.getName()
+                                              +" : "+invalidCharacter);
+                      }
+
+                       seq.setSequence(sb.toString());
+                       seqs.addElement(seq);
+                    }
+
+                    seq = parseId(line.substring(1));
+
+                    count++;
+                    sb = new StringBuffer();
+                }
+                else
+                {
+                    sb.append(line);
+                }
+            }
+        }
+
+        if (count > 0)
+        {
+            if (!isValidProteinSequence(sb.toString()))
+            {
+                throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS
+                                      +" : "+seq.getName()
+                                      +" : "+invalidCharacter);
+            }
+
+            seq.setSequence(sb.toString());
+            seqs.addElement(seq);
+        }
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param len DOCUMENT ME!
+     * @param gaps DOCUMENT ME!
+     * @param displayId DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String print(SequenceI[] s)
+    {
+        int len = 72;
+        StringBuffer out = new StringBuffer();
+        int i = 0;
+
+        while ((i < s.length) && (s[i] != null))
+        {
+            out.append(">" + printId(s[i]));
+            if(s[i].getDescription()!=null)
+              out.append(" "+s[i].getDescription());
+
+            out.append("\n");
+
+            int nochunks = (s[i].getLength() / len) + 1;
+
+            for (int j = 0; j < nochunks; j++)
+            {
+                int start = j * len;
+                int end = start + len;
+
+                if (end < s[i].getLength())
+                {
+                    out.append(s[i].getSequence(start, end) + "\n");
+                }
+                else if (start < s[i].getLength())
+                {
+                    out.append(s[i].getSequence(start, s[i].getLength()) + "\n");
+                }
+            }
+
+            i++;
+        }
+
+        return out.toString();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String print()
+    {
+        return print(getSeqsAsArray());
+    }
+}
index 38959a7..4ab9b3b 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-\r
-package jalview.io;\r
-\r
-import jalview.gui.AlignFrame;\r
-import jalview.gui.Jalview2XML;\r
-import javax.swing.JOptionPane;\r
-import jalview.datamodel.Alignment;\r
-import jalview.gui.Desktop;\r
-import jalview.datamodel.SequenceI;\r
-\r
-public class FileLoader\r
-{\r
-  public void LoadFile(String file, String protocol, String format)\r
-  {\r
-    LoadingThread loader = new LoadingThread(file, protocol, format);\r
-    loader.start();\r
-  }\r
-\r
-  public AlignFrame LoadFileWaitTillLoaded(String file, String protocol,\r
-                                                  String format)\r
-  {\r
-    LoadingThread loader = new LoadingThread(file, protocol, format);\r
-    loader.start();\r
-    while (loader.isAlive())\r
-    {\r
-      try\r
-      {\r
-        Thread.sleep(500);\r
-      }\r
-      catch (Exception ex)\r
-      {}\r
-    }\r
-\r
-    return loader.af;\r
-  }\r
-\r
-\r
-  class LoadingThread\r
-    extends Thread\r
-{\r
-  String file;\r
-  String protocol;\r
-  String format;\r
-  AlignFrame af;\r
-\r
-  public LoadingThread(String file, String protocol, String format)\r
-  {\r
-    this.file = file;\r
-    this.protocol = protocol;\r
-    this.format = format;\r
-  }\r
-\r
-  public void run()\r
-  {\r
-    SequenceI[] sequences = null;\r
-\r
-    if (format.equalsIgnoreCase("Jalview"))\r
-    {\r
-      af = Jalview2XML.LoadJalviewAlign(file);\r
-    }\r
-    else\r
-    {\r
-      String errorMessage = AppletFormatAdapter.SUPPORTED_FORMATS;\r
-\r
-      if (FormatAdapter.formats.contains(format))\r
-      {\r
-        try{\r
-          sequences = new FormatAdapter().readFile(file, protocol, format);\r
-        }catch(java.io.IOException ex)\r
-        {\r
-          errorMessage = ex.getMessage();\r
-        }\r
-      }\r
-\r
-      if ( (sequences != null) && (sequences.length > 0))\r
-      {\r
-        af = new AlignFrame(new Alignment(sequences));\r
-        af.currentFileFormat = format;\r
-        af.statusBar.setText("Successfully loaded file " + file);\r
-\r
-        Desktop.addInternalFrame(af, file, AlignFrame.NEW_WINDOW_WIDTH,\r
-                           AlignFrame.NEW_WINDOW_HEIGHT);\r
-\r
-\r
-        try\r
-        {\r
-          af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-        }\r
-      }\r
-      else\r
-      {\r
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                              "Couldn't load file "+file+"\n"\r
-                                              +errorMessage,\r
-                                              "Error loading file",\r
-                                              JOptionPane.WARNING_MESSAGE);\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+
+package jalview.io;
+
+import jalview.gui.AlignFrame;
+import jalview.gui.Jalview2XML;
+import javax.swing.JOptionPane;
+
+import jalview.gui.*;
+import jalview.datamodel.*;
+import java.util.Vector;
+import java.util.StringTokenizer;
+
+public class FileLoader
+{
+  String file;
+  String protocol;
+  String format;
+  AlignViewport viewport;
+
+  public void LoadFile(AlignViewport viewport, String file, String protocol, String format)
+  {
+    this.viewport = viewport;
+    LoadFile(file, protocol, format);
+  }
+
+  public void LoadFile(String file, String protocol, String format)
+  {
+    this.file = file;
+    this.protocol = protocol;
+    this.format = format;
+
+    LoadingThread loader = new LoadingThread();
+    loader.start();
+  }
+
+  public AlignFrame LoadFileWaitTillLoaded(String file, String protocol,
+                                                  String format)
+  {
+    this.file = file;
+    this.protocol = protocol;
+    this.format = format;
+
+    LoadingThread loader = new LoadingThread();
+    loader.start();
+    while (loader.isAlive())
+    {
+      try
+      {
+        Thread.sleep(500);
+      }
+      catch (Exception ex)
+      {}
+    }
+
+    return loader.af;
+  }
+
+
+
+  public void updateRecentlyOpened()
+  {
+    Vector recent = new Vector();
+
+    String type = protocol.equals(FormatAdapter.FILE)
+        ? "RECENT_FILE" : "RECENT_URL";
+
+    String historyItems = jalview.bin.Cache.getProperty(type);
+
+    StringTokenizer st;
+
+    if (historyItems != null)
+    {
+      st = new StringTokenizer(historyItems, "\t");
+
+      while (st.hasMoreTokens())
+      {
+        recent.addElement(st.nextElement().toString().trim());
+      }
+    }
+
+    if (recent.contains(file))
+    {
+      recent.remove(file);
+    }
+
+    StringBuffer newHistory = new StringBuffer(file);
+    for (int i = 0; i < recent.size() && i < 10; i++)
+    {
+      newHistory.append("\t");
+      newHistory.append(recent.elementAt(i));
+    }
+
+    jalview.bin.Cache.setProperty(type, newHistory.toString());
+
+    if(type.equals(FormatAdapter.FILE))
+      jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT", format);
+  }
+
+
+  class LoadingThread
+      extends Thread
+  {
+
+    AlignFrame af;
+
+
+
+    public void run()
+    {
+      if (Desktop.instance != null)
+        Desktop.instance.startLoading(file);
+
+      SequenceI[] sequences = null;
+
+      if (format.equalsIgnoreCase("Jalview"))
+      {
+        af = new Jalview2XML().LoadJalviewAlign(file);
+      }
+      else
+      {
+        String error = AppletFormatAdapter.SUPPORTED_FORMATS;
+
+        if (FormatAdapter.isValidFormat(format))
+        {
+          try
+          {
+            sequences = new FormatAdapter().readFile(file, protocol, format);
+          }
+          catch (java.io.IOException ex)
+          {
+            error = ex.getMessage();
+          }
+        }
+
+        if ( (sequences != null) && (sequences.length > 0))
+        {
+          if(viewport!=null)
+          {
+            for(int i=0; i<sequences.length; i++)
+              viewport.getAlignment().addSequence(sequences[i]);
+
+              viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
+          }
+          else
+          {
+            af = new AlignFrame(new Alignment(sequences));
+            af.currentFileFormat = format;
+            af.statusBar.setText("Successfully loaded file " + file);
+
+            Desktop.addInternalFrame(af, file, AlignFrame.NEW_WINDOW_WIDTH,
+                                     AlignFrame.NEW_WINDOW_HEIGHT);
+
+            try
+            {
+              af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));
+            }
+            catch (java.beans.PropertyVetoException ex)
+            {
+            }
+          }
+        }
+        else
+        {
+          if (Desktop.instance != null)
+            Desktop.instance.stopLoading();
+
+          final String errorMessage = "Couldn't load file "+file+"\n"+error;
+
+          javax.swing.SwingUtilities.invokeLater(new Runnable()
+          {
+            public void run()
+            {
+              JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                                                    errorMessage,
+                                                    "Error loading file",
+                                                    JOptionPane.WARNING_MESSAGE);
+            }
+          });
+        }
+      }
+
+      if (af != null)
+      {
+        updateRecentlyOpened();
+      }
+
+      if (Desktop.instance != null)
+        Desktop.instance.stopLoading();
+
+    }
+  }
+
+}
index adc57cd..b840d73 100755 (executable)
@@ -1,68 +1,68 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.net.*;\r
-\r
-public class FileParse\r
-{\r
-  public File inFile;\r
-  protected String type;\r
-  protected BufferedReader dataIn;\r
-\r
-  public FileParse()\r
-  {\r
-  }\r
-\r
-  public FileParse(String fileStr, String type)\r
-      throws MalformedURLException, IOException\r
-  {\r
-    this.type = type;\r
-\r
-    if (type.equals(AppletFormatAdapter.FILE))\r
-    {\r
-      this.inFile = new File(fileStr);\r
-      dataIn = new BufferedReader(new FileReader(fileStr));\r
-    }\r
-    else if (type.equals(AppletFormatAdapter.URL))\r
-    {\r
-      URL url = new URL(fileStr);\r
-      dataIn = new BufferedReader(new InputStreamReader(url.openStream()));\r
-    }\r
-   else if (type.equals(AppletFormatAdapter.PASTE))\r
-    {\r
-      dataIn = new BufferedReader(new StringReader(fileStr));\r
-    }\r
-    else if (type.equals(AppletFormatAdapter.CLASSLOADER))\r
-    {\r
-      java.io.InputStream is = getClass().getResourceAsStream("/" + fileStr);\r
-      if (is != null)\r
-      {\r
-        dataIn = new BufferedReader(new java.io.InputStreamReader(is));\r
-      }\r
-    }\r
-  }\r
-\r
-  public String nextLine()\r
-      throws IOException\r
-  {\r
-    return dataIn.readLine();\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+import java.net.*;
+
+public class FileParse
+{
+  public File inFile;
+  protected String type;
+  protected BufferedReader dataIn;
+
+  public FileParse()
+  {
+  }
+
+  public FileParse(String fileStr, String type)
+      throws MalformedURLException, IOException
+  {
+    this.type = type;
+
+    if (type.equals(AppletFormatAdapter.FILE))
+    {
+      this.inFile = new File(fileStr);
+      dataIn = new BufferedReader(new FileReader(fileStr));
+    }
+    else if (type.equals(AppletFormatAdapter.URL))
+    {
+      URL url = new URL(fileStr);
+      dataIn = new BufferedReader(new InputStreamReader(url.openStream()));
+    }
+   else if (type.equals(AppletFormatAdapter.PASTE))
+    {
+      dataIn = new BufferedReader(new StringReader(fileStr));
+    }
+    else if (type.equals(AppletFormatAdapter.CLASSLOADER))
+    {
+      java.io.InputStream is = getClass().getResourceAsStream("/" + fileStr);
+      if (is != null)
+      {
+        dataIn = new BufferedReader(new java.io.InputStreamReader(is));
+      }
+    }
+  }
+
+  public String nextLine()
+      throws IOException
+  {
+    return dataIn.readLine();
+  }
+}
index 0c8554a..e85f012 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.util.Vector;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class FormatAdapter extends AppletFormatAdapter\r
-{\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param format DOCUMENT ME!\r
-     * @param seqs DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String formatSequences(String format, Vector seqs)\r
-    {\r
-        SequenceI[] s = new SequenceI[seqs.size()];\r
-\r
-        for (int i = 0; i < seqs.size(); i++)\r
-            s[i] = (SequenceI) seqs.elementAt(i);\r
-\r
-        try\r
-        {\r
-            AlignFile afile = null;\r
-\r
-            if (format.equalsIgnoreCase("FASTA"))\r
-            {\r
-                afile = new FastaFile();\r
-                afile.addJVSuffix(\r
-                    jalview.bin.Cache.getDefault("FASTA_JVSUFFIX", true));\r
-            }\r
-            else if (format.equalsIgnoreCase("MSF"))\r
-            {\r
-              afile = new MSFfile();\r
-              afile.addJVSuffix(\r
-                  jalview.bin.Cache.getDefault("MSF_JVSUFFIX", true));\r
-            }\r
-            else if (format.equalsIgnoreCase("PileUp"))\r
-            {\r
-                afile = new PileUpfile();\r
-                afile.addJVSuffix(\r
-                    jalview.bin.Cache.getDefault("PILEUP_JVSUFFIX", true));\r
-            }\r
-            else if (format.equalsIgnoreCase("CLUSTAL"))\r
-            {\r
-                afile = new ClustalFile();\r
-                afile.addJVSuffix(\r
-                    jalview.bin.Cache.getDefault("CLUSTAL_JVSUFFIX", true));\r
-            }\r
-            else if (format.equalsIgnoreCase("BLC"))\r
-            {\r
-                afile = new BLCFile();\r
-                afile.addJVSuffix(\r
-                    jalview.bin.Cache.getDefault("BLC_JVSUFFIX", true));\r
-            }\r
-            else if (format.equalsIgnoreCase("PIR"))\r
-            {\r
-                afile = new PIRFile();\r
-                afile.addJVSuffix(\r
-                    jalview.bin.Cache.getDefault("PIR_JVSUFFIX", true));\r
-            }\r
-            else if (format.equalsIgnoreCase("PFAM"))\r
-            {\r
-                afile = new PfamFile();\r
-                afile.addJVSuffix(\r
-                    jalview.bin.Cache.getDefault("PFAM_JVSUFFIX", true));\r
-            }\r
-\r
-            afile.setSeqs(s);\r
-\r
-            return afile.print();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            System.err.println("Failed to write alignment as a '" + format +\r
-                "' file\n");\r
-            e.printStackTrace();\r
-        }\r
-\r
-        return null;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import jalview.datamodel.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class FormatAdapter extends AppletFormatAdapter
+{
+
+    public String formatSequences(String format,
+                                  SequenceI [] seqs,
+                                  String [] omitHiddenColumns)
+    {
+      if(omitHiddenColumns!=null)
+      {
+        SequenceI [] tmp = new SequenceI[seqs.length];
+        for(int i=0; i<seqs.length; i++)
+          tmp [i] = new Sequence(
+              seqs[i].getName(), omitHiddenColumns[i],
+              seqs[i].getStart(), seqs[i].getEnd());
+
+        seqs = tmp;
+      }
+
+      return formatSequences(format, seqs);
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param format DOCUMENT ME!
+     * @param seqs DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String formatSequences(String format,
+                                  SequenceI [] seqs)
+    {
+
+        try
+        {
+            AlignFile afile = null;
+
+            if (format.equalsIgnoreCase("FASTA"))
+            {
+                afile = new FastaFile();
+                afile.addJVSuffix(
+                    jalview.bin.Cache.getDefault("FASTA_JVSUFFIX", true));
+            }
+            else if (format.equalsIgnoreCase("MSF"))
+            {
+              afile = new MSFfile();
+              afile.addJVSuffix(
+                  jalview.bin.Cache.getDefault("MSF_JVSUFFIX", true));
+            }
+            else if (format.equalsIgnoreCase("PileUp"))
+            {
+                afile = new PileUpfile();
+                afile.addJVSuffix(
+                    jalview.bin.Cache.getDefault("PILEUP_JVSUFFIX", true));
+            }
+            else if (format.equalsIgnoreCase("CLUSTAL"))
+            {
+                afile = new ClustalFile();
+                afile.addJVSuffix(
+                    jalview.bin.Cache.getDefault("CLUSTAL_JVSUFFIX", true));
+            }
+            else if (format.equalsIgnoreCase("BLC"))
+            {
+                afile = new BLCFile();
+                afile.addJVSuffix(
+                    jalview.bin.Cache.getDefault("BLC_JVSUFFIX", true));
+            }
+            else if (format.equalsIgnoreCase("PIR"))
+            {
+                afile = new PIRFile();
+                afile.addJVSuffix(
+                    jalview.bin.Cache.getDefault("PIR_JVSUFFIX", true));
+            }
+            else if (format.equalsIgnoreCase("PFAM"))
+            {
+                afile = new PfamFile();
+                afile.addJVSuffix(
+                    jalview.bin.Cache.getDefault("PFAM_JVSUFFIX", true));
+            }
+
+            afile.setSeqs(seqs);
+
+            return afile.print();
+        }
+        catch (Exception e)
+        {
+            System.err.println("Failed to write alignment as a '" + format +
+                "' file\n");
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+}
index beb8829..6b58087 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.gui.*;\r
-\r
-public class HTMLOutput\r
-{\r
-  AlignViewport av;\r
-  SequenceRenderer sr;\r
-  FeatureRenderer fr;\r
-  Color color;\r
-\r
-  public HTMLOutput(AlignViewport av, SequenceRenderer sr, FeatureRenderer fr)\r
-  {\r
-    this.av = av;\r
-    this.sr = sr;\r
-    this.fr = fr;\r
-\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
-        getProperty(\r
-            "LAST_DIRECTORY"), new String[]\r
-        {"html"},\r
-        new String[]\r
-        {"HTML files"}, "HTML files");\r
-\r
-    chooser.setFileView(new JalviewFileView());\r
-    chooser.setDialogTitle("Save as HTML");\r
-    chooser.setToolTipText("Save");\r
-\r
-    int value = chooser.showSaveDialog(null);\r
-\r
-    if (value == JalviewFileChooser.APPROVE_OPTION)\r
-    {\r
-      String choice = chooser.getSelectedFile().getPath();\r
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                                    chooser.getSelectedFile().getParent());\r
-\r
-      try\r
-      {\r
-        PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(\r
-            choice));\r
-        out.println("<HTML>");\r
-        out.println("<style type=\"text/css\">");\r
-        out.println("<!--");\r
-        out.print("td {font-family: \"" + av.getFont().getFamily() +\r
-                  "\", \"" + av.getFont().getName() + "\", mono; " +\r
-                  "font-size: " + av.getFont().getSize() + "px; ");\r
-\r
-        if (av.getFont().getStyle() == Font.BOLD)\r
-        {\r
-          out.print("font-weight: BOLD; ");\r
-        }\r
-\r
-        if (av.getFont().getStyle() == Font.ITALIC)\r
-        {\r
-          out.print("font-style: italic; ");\r
-        }\r
-\r
-        out.println("text-align: center; }");\r
-\r
-        out.println("-->");\r
-        out.println("</style>");\r
-        out.println("<BODY>");\r
-\r
-        if (av.getWrapAlignment())\r
-        {\r
-          drawWrappedAlignment(out);\r
-        }\r
-        else\r
-        {\r
-          drawUnwrappedAlignment(out);\r
-        }\r
-\r
-        out.println("\n</body>\n</html>");\r
-        out.close();\r
-        jalview.util.BrowserLauncher.openURL("file:///" + choice);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-  }\r
-\r
-  void drawUnwrappedAlignment(PrintWriter out)\r
-  {\r
-    out.println("<table border=\"1\"><tr><td>\n");\r
-    out.println(\r
-        "<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");\r
-\r
-    //////////////\r
-    SequenceI seq;\r
-    AlignmentI alignment = av.getAlignment();\r
-\r
-    // draws the top row, the measure rule\r
-    out.println("<tr><td colspan=\"6\"></td>");\r
-\r
-    int i = 0;\r
-\r
-    for (i = 10; i < (alignment.getWidth() - 10); i += 10)\r
-    {\r
-      out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");\r
-    }\r
-\r
-    out.println("<td colspan=\"3\"></td><td colspan=\"3\">" + i +\r
-                "<br>|</td>");\r
-    out.println("</tr>");\r
-\r
-    for (i = 0; i < alignment.getHeight(); i++)\r
-    {\r
-      seq = alignment.getSequenceAt(i);\r
-\r
-      String id = seq.getDisplayId(av.getShowJVSuffix());\r
-\r
-      out.println("<tr><td nowrap>" + id +\r
-                    "&nbsp;&nbsp;</td>");\r
-\r
-\r
-      for (int res = 0; res < seq.getLength(); res++)\r
-      {\r
-        if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))\r
-        {\r
-          color = sr.getResidueBoxColour(seq, res);\r
-\r
-          color = fr.findFeatureColour(color, seq, res);\r
-        }\r
-        else\r
-            color = Color.white;\r
-\r
-\r
-       if (color.getRGB() < -1)\r
-        {\r
-          out.println("<td bgcolor=\"#" +\r
-                      jalview.util.Format.getHexString(color) + "\">" +\r
-                      seq.getCharAt(res) + "</td>");\r
-        }\r
-        else\r
-        {\r
-          out.println("<td>" + seq.getCharAt(res) + "</td>");\r
-        }\r
-      }\r
-\r
-      out.println("</tr>");\r
-    }\r
-\r
-    //////////////\r
-    out.println("</table>");\r
-    out.println("</td></tr></table>");\r
-  }\r
-\r
-  void drawWrappedAlignment(PrintWriter out)\r
-  {\r
-    ////////////////////////////////////\r
-    /// How many sequences and residues can we fit on a printable page?\r
-    AlignmentI al = av.getAlignment();\r
-    SequenceI seq;\r
-    String r;\r
-    String g;\r
-    String b;\r
-\r
-    out.println("<table border=\"1\"><tr><td>\n");\r
-    out.println(\r
-        "<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");\r
-\r
-    for (int startRes = 0; startRes < al.getWidth();\r
-         startRes += av.getWrappedWidth())\r
-    {\r
-      int endRes = startRes + av.getWrappedWidth();\r
-\r
-      if (endRes > al.getWidth())\r
-      {\r
-        endRes = al.getWidth();\r
-      }\r
-\r
-      if(av.getScaleAboveWrapped())\r
-      {\r
-        out.println("<tr>");\r
-\r
-        if (av.getScaleLeftWrapped())\r
-          out.println("<td colspan=\"7\">&nbsp;</td>");\r
-        else\r
-          out.println("<td colspan=\"6\">&nbsp;</td>");\r
-\r
-\r
-        for (int i = startRes + 10; i < endRes; i += 10)\r
-        {\r
-          out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");\r
-        }\r
-\r
-        out.println("</tr>");\r
-      }\r
-\r
-      int startPos, endPos;\r
-      for (int s = 0; s < al.getHeight(); s++)\r
-      {\r
-        out.println("<tr>");\r
-        seq = al.getSequenceAt(s);\r
-\r
-        startPos = seq.findPosition( startRes );\r
-        endPos =   seq.findPosition( endRes )-1;\r
-\r
-        String id = seq.getDisplayId(av.getShowJVSuffix());\r
-\r
-        out.println("<td nowrap>" + id +\r
-                      "&nbsp;&nbsp;</td>");\r
-\r
-\r
-        if(av.getScaleLeftWrapped())\r
-        {\r
-          if(startPos > seq.getEnd() || endPos==0)\r
-            out.println("<td nowrap>&nbsp;</td>");\r
-          else\r
-            out.println("<td nowrap>" + startPos +\r
-                      "&nbsp;&nbsp;</td>");\r
-        }\r
-\r
-\r
-        for (int res = startRes; res < endRes; res++)\r
-        {\r
-          if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))\r
-          {\r
-            color = sr.getResidueBoxColour(seq, res);\r
-\r
-            color = fr.findFeatureColour(color, seq, res);\r
-          }\r
-          else\r
-            color = Color.white;\r
-\r
-          if (color.getRGB() < -1)\r
-          {\r
-            r = Integer.toHexString(color.getRed());\r
-\r
-            if (r.length() < 2)\r
-            {\r
-              r = "0" + r;\r
-            }\r
-\r
-            g = Integer.toHexString(color.getGreen());\r
-\r
-            if (g.length() < 2)\r
-            {\r
-              g = "0" + g;\r
-            }\r
-\r
-            b = Integer.toHexString(color.getBlue());\r
-\r
-            if (b.length() < 2)\r
-            {\r
-              b = "0" + b;\r
-            }\r
-\r
-            out.println("<td bgcolor=\"#" + r + g + b + "\">" +\r
-                        seq.getCharAt(res) + "</td>");\r
-          }\r
-          else\r
-          {\r
-            out.println("<td>" + seq.getCharAt(res) + "</td>");\r
-          }\r
-\r
-\r
-        }\r
-\r
-        if(av.getScaleRightWrapped() &&\r
-           endRes < startRes + av.getWrappedWidth())\r
-        {\r
-         out.println("<td colspan=\""+ (startRes+av.getWrappedWidth()-endRes) +"\">"\r
-                     +"&nbsp;&nbsp;</td>");\r
-       }\r
-\r
-\r
-        if(av.getScaleRightWrapped() && startPos<endPos)\r
-        {\r
-          out.println("<td nowrap>&nbsp;" + endPos +\r
-                      "&nbsp;&nbsp;</td>");\r
-        }\r
-\r
-\r
-        out.println("</tr>");\r
-      }\r
-\r
-      if (endRes < al.getWidth())\r
-      {\r
-        out.println("<tr><td height=\"5\"></td></tr>");\r
-      }\r
-    }\r
-\r
-    out.println("</table>");\r
-    out.println("</table>");\r
-  }\r
-\r
-  public static String getImageMapHTML()\r
-  {\r
-    return new String(\r
-      "<html>\n"\r
-      +"<head>\n"\r
-      +"<script language=\"JavaScript\">\n"\r
-      +"var ns4 = document.layers;\n"\r
-      +"var ns6 = document.getElementById && !document.all;\n"\r
-      +"var ie4 = document.all;\n"\r
-      +"offsetX = 0;\n"\r
-      +"offsetY = 20;\n"\r
-      +"var toolTipSTYLE=\"\";\n"\r
-      +"function initToolTips()\n"\r
-      +"{\n"\r
-      +"  if(ns4||ns6||ie4)\n"\r
-      +"  {\n"\r
-      +"    if(ns4) toolTipSTYLE = document.toolTipLayer;\n"\r
-      +"    else if(ns6) toolTipSTYLE = document.getElementById(\"toolTipLayer\").style;\n"\r
-      +"    else if(ie4) toolTipSTYLE = document.all.toolTipLayer.style;\n"\r
-      +"    if(ns4) document.captureEvents(Event.MOUSEMOVE);\n"\r
-      +"    else\n"\r
-      +"    {\n"\r
-      +"      toolTipSTYLE.visibility = \"visible\";\n"\r
-      +"      toolTipSTYLE.display = \"none\";\n"\r
-      +"    }\n"\r
-      +"    document.onmousemove = moveToMouseLoc;\n"\r
-      +"  }\n"\r
-      +"}\n"\r
-      +"function toolTip(msg, fg, bg)\n"\r
-      +"{\n"\r
-      +"  if(toolTip.arguments.length < 1) // hide\n"\r
-      +"  {\n"\r
-      +"    if(ns4) toolTipSTYLE.visibility = \"hidden\";\n"\r
-      +"    else toolTipSTYLE.display = \"none\";\n"\r
-      +"  }\n"\r
-      +"  else // show\n"\r
-      +"  {\n"\r
-      +"    if(!fg) fg = \"#555555\";\n"\r
-      +"    if(!bg) bg = \"#FFFFFF\";\n"\r
-      +"    var content =\n"\r
-      +"    '<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\" bgcolor=\"' + fg + '\"><td>' +\n"\r
-      +"    '<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\" bgcolor=\"' + bg + \n"\r
-      +"    '\"><td align=\"center\"><font face=\"sans-serif\" color=\"' + fg +\n"\r
-      +"    '\" size=\"-2\">&nbsp;' + msg +\n"\r
-      +"    '&nbsp;</font></td></table></td></table>';\n"\r
-      +"    if(ns4)\n"\r
-      +"    {\n"\r
-      +"      toolTipSTYLE.document.write(content);\n"\r
-      +"      toolTipSTYLE.document.close();\n"\r
-      +"      toolTipSTYLE.visibility = \"visible\";\n"\r
-      +"    }\n"\r
-      +"    if(ns6)\n"\r
-      +"    {\n"\r
-      +"      document.getElementById(\"toolTipLayer\").innerHTML = content;\n"\r
-      +"      toolTipSTYLE.display='block'\n"\r
-      +"    }\n"\r
-      +"    if(ie4)\n"\r
-      +"    {\n"\r
-      +"      document.all(\"toolTipLayer\").innerHTML=content;\n"\r
-      +"      toolTipSTYLE.display='block'\n"\r
-      +"    }\n"\r
-      +"  }\n"\r
-      +"}\n"\r
-      +"function moveToMouseLoc(e)\n"\r
-      +"{\n"\r
-      +"  if(ns4||ns6)\n"\r
-      +"  {\n"\r
-      +"    x = e.pageX;\n"\r
-      +"    y = e.pageY;\n"\r
-      +"  }\n"\r
-      +"  else\n"\r
-      +"  {\n"\r
-      +"    x = event.x + document.body.scrollLeft;\n"\r
-      +"    y = event.y + document.body.scrollTop;\n"\r
-      +"  }\n"\r
-      +"  toolTipSTYLE.left = x + offsetX;\n"\r
-      +"  toolTipSTYLE.top = y + offsetY;\n"\r
-      +"  return true;\n"\r
-      +"}\n"\r
-      +"</script>\n"\r
-      +"</head>\n"\r
-      +"<body>\n"\r
-      +"<div id=\"toolTipLayer\" style=\"position:absolute; visibility: hidden\"></div>\n"\r
-      +"<script language=\"JavaScript\"><!--\n"\r
-      +"initToolTips(); //--></script>\n");\r
-\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+import jalview.gui.*;
+
+public class HTMLOutput
+{
+  AlignViewport av;
+  SequenceRenderer sr;
+  FeatureRenderer fr;
+  Color color;
+
+  public HTMLOutput(AlignViewport av, SequenceRenderer sr, FeatureRenderer fr1)
+  {
+    this.av = av;
+    this.sr = sr;
+
+    fr = new FeatureRenderer(av);
+    fr.transferSettings(fr1);
+
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+        getProperty(
+            "LAST_DIRECTORY"), new String[]
+        {"html"},
+        new String[]
+        {"HTML files"}, "HTML files");
+
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle("Save as HTML");
+    chooser.setToolTipText("Save");
+
+    int value = chooser.showSaveDialog(null);
+
+    if (value == JalviewFileChooser.APPROVE_OPTION)
+    {
+      String choice = chooser.getSelectedFile().getPath();
+      jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                                    chooser.getSelectedFile().getParent());
+
+      try
+      {
+        PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
+            choice));
+        out.println("<HTML>");
+        out.println("<style type=\"text/css\">");
+        out.println("<!--");
+        out.print("td {font-family: \"" + av.getFont().getFamily() +
+                  "\", \"" + av.getFont().getName() + "\", mono; " +
+                  "font-size: " + av.getFont().getSize() + "px; ");
+
+        if (av.getFont().getStyle() == Font.BOLD)
+        {
+          out.print("font-weight: BOLD; ");
+        }
+
+        if (av.getFont().getStyle() == Font.ITALIC)
+        {
+          out.print("font-style: italic; ");
+        }
+
+        out.println("text-align: center; }");
+
+        out.println("-->");
+        out.println("</style>");
+        out.println("<BODY>");
+
+        if (av.getWrapAlignment())
+        {
+          drawWrappedAlignment(out);
+        }
+        else
+        {
+          drawUnwrappedAlignment(out);
+        }
+
+        out.println("\n</body>\n</html>");
+        out.close();
+        jalview.util.BrowserLauncher.openURL("file:///" + choice);
+      }
+      catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+  }
+
+  void drawUnwrappedAlignment(PrintWriter out)
+  {
+    out.println("<table border=\"1\"><tr><td>\n");
+    out.println(
+        "<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");
+
+    //////////////
+    SequenceI seq;
+    AlignmentI alignment = av.getAlignment();
+
+    // draws the top row, the measure rule
+    out.println("<tr><td colspan=\"6\"></td>");
+
+    int i = 0;
+
+    for (i = 10; i < (alignment.getWidth() - 10); i += 10)
+    {
+      out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");
+    }
+
+    out.println("<td colspan=\"3\"></td><td colspan=\"3\">" + i +
+                "<br>|</td>");
+    out.println("</tr>");
+
+    for (i = 0; i < alignment.getHeight(); i++)
+    {
+      seq = alignment.getSequenceAt(i);
+
+      String id = seq.getDisplayId(av.getShowJVSuffix());
+
+      out.println("<tr><td nowrap>" + id +
+                    "&nbsp;&nbsp;</td>");
+
+
+      for (int res = 0; res < seq.getLength(); res++)
+      {
+        if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))
+        {
+          color = sr.getResidueBoxColour(seq, res);
+
+          color = fr.findFeatureColour(color, seq, res);
+        }
+        else
+            color = Color.white;
+
+
+       if (color.getRGB() < -1)
+        {
+          out.println("<td bgcolor=\"#" +
+                      jalview.util.Format.getHexString(color) + "\">" +
+                      seq.getCharAt(res) + "</td>");
+        }
+        else
+        {
+          out.println("<td>" + seq.getCharAt(res) + "</td>");
+        }
+      }
+
+      out.println("</tr>");
+    }
+
+    //////////////
+    out.println("</table>");
+    out.println("</td></tr></table>");
+  }
+
+  void drawWrappedAlignment(PrintWriter out)
+  {
+    ////////////////////////////////////
+    /// How many sequences and residues can we fit on a printable page?
+    AlignmentI al = av.getAlignment();
+    SequenceI seq;
+    String r;
+    String g;
+    String b;
+
+    out.println("<table border=\"1\"><tr><td>\n");
+    out.println(
+        "<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");
+
+    for (int startRes = 0; startRes < al.getWidth();
+         startRes += av.getWrappedWidth())
+    {
+      int endRes = startRes + av.getWrappedWidth();
+
+      if (endRes > al.getWidth())
+      {
+        endRes = al.getWidth();
+      }
+
+      if(av.getScaleAboveWrapped())
+      {
+        out.println("<tr>");
+
+        if (av.getScaleLeftWrapped())
+          out.println("<td colspan=\"7\">&nbsp;</td>");
+        else
+          out.println("<td colspan=\"6\">&nbsp;</td>");
+
+
+        for (int i = startRes + 10; i < endRes; i += 10)
+        {
+          out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");
+        }
+
+        out.println("</tr>");
+      }
+
+      int startPos, endPos;
+      for (int s = 0; s < al.getHeight(); s++)
+      {
+        out.println("<tr>");
+        seq = al.getSequenceAt(s);
+
+        startPos = seq.findPosition( startRes );
+        endPos =   seq.findPosition( endRes )-1;
+
+        String id = seq.getDisplayId(av.getShowJVSuffix());
+
+        out.println("<td nowrap>" + id +
+                      "&nbsp;&nbsp;</td>");
+
+
+        if(av.getScaleLeftWrapped())
+        {
+          if(startPos > seq.getEnd() || endPos==0)
+            out.println("<td nowrap>&nbsp;</td>");
+          else
+            out.println("<td nowrap>" + startPos +
+                      "&nbsp;&nbsp;</td>");
+        }
+
+
+        for (int res = startRes; res < endRes; res++)
+        {
+          if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))
+          {
+            color = sr.getResidueBoxColour(seq, res);
+
+            color = fr.findFeatureColour(color, seq, res);
+          }
+          else
+            color = Color.white;
+
+          if (color.getRGB() < -1)
+          {
+            r = Integer.toHexString(color.getRed());
+
+            if (r.length() < 2)
+            {
+              r = "0" + r;
+            }
+
+            g = Integer.toHexString(color.getGreen());
+
+            if (g.length() < 2)
+            {
+              g = "0" + g;
+            }
+
+            b = Integer.toHexString(color.getBlue());
+
+            if (b.length() < 2)
+            {
+              b = "0" + b;
+            }
+
+            out.println("<td bgcolor=\"#" + r + g + b + "\">" +
+                        seq.getCharAt(res) + "</td>");
+          }
+          else
+          {
+            out.println("<td>" + seq.getCharAt(res) + "</td>");
+          }
+
+
+        }
+
+        if(av.getScaleRightWrapped() &&
+           endRes < startRes + av.getWrappedWidth())
+        {
+         out.println("<td colspan=\""+ (startRes+av.getWrappedWidth()-endRes) +"\">"
+                     +"&nbsp;&nbsp;</td>");
+       }
+
+
+        if(av.getScaleRightWrapped() && startPos<endPos)
+        {
+          out.println("<td nowrap>&nbsp;" + endPos +
+                      "&nbsp;&nbsp;</td>");
+        }
+
+
+        out.println("</tr>");
+      }
+
+      if (endRes < al.getWidth())
+      {
+        out.println("<tr><td height=\"5\"></td></tr>");
+      }
+    }
+
+    out.println("</table>");
+    out.println("</table>");
+  }
+
+  public static String getImageMapHTML()
+  {
+    return new String(
+      "<html>\n"
+      +"<head>\n"
+      +"<script language=\"JavaScript\">\n"
+      +"var ns4 = document.layers;\n"
+      +"var ns6 = document.getElementById && !document.all;\n"
+      +"var ie4 = document.all;\n"
+      +"offsetX = 0;\n"
+      +"offsetY = 20;\n"
+      +"var toolTipSTYLE=\"\";\n"
+      +"function initToolTips()\n"
+      +"{\n"
+      +"  if(ns4||ns6||ie4)\n"
+      +"  {\n"
+      +"    if(ns4) toolTipSTYLE = document.toolTipLayer;\n"
+      +"    else if(ns6) toolTipSTYLE = document.getElementById(\"toolTipLayer\").style;\n"
+      +"    else if(ie4) toolTipSTYLE = document.all.toolTipLayer.style;\n"
+      +"    if(ns4) document.captureEvents(Event.MOUSEMOVE);\n"
+      +"    else\n"
+      +"    {\n"
+      +"      toolTipSTYLE.visibility = \"visible\";\n"
+      +"      toolTipSTYLE.display = \"none\";\n"
+      +"    }\n"
+      +"    document.onmousemove = moveToMouseLoc;\n"
+      +"  }\n"
+      +"}\n"
+      +"function toolTip(msg, fg, bg)\n"
+      +"{\n"
+      +"  if(toolTip.arguments.length < 1) // hide\n"
+      +"  {\n"
+      +"    if(ns4) toolTipSTYLE.visibility = \"hidden\";\n"
+      +"    else toolTipSTYLE.display = \"none\";\n"
+      +"  }\n"
+      +"  else // show\n"
+      +"  {\n"
+      +"    if(!fg) fg = \"#555555\";\n"
+      +"    if(!bg) bg = \"#FFFFFF\";\n"
+      +"    var content =\n"
+      +"    '<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\" bgcolor=\"' + fg + '\"><td>' +\n"
+      +"    '<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\" bgcolor=\"' + bg + \n"
+      +"    '\"><td align=\"center\"><font face=\"sans-serif\" color=\"' + fg +\n"
+      +"    '\" size=\"-2\">&nbsp;' + msg +\n"
+      +"    '&nbsp;</font></td></table></td></table>';\n"
+      +"    if(ns4)\n"
+      +"    {\n"
+      +"      toolTipSTYLE.document.write(content);\n"
+      +"      toolTipSTYLE.document.close();\n"
+      +"      toolTipSTYLE.visibility = \"visible\";\n"
+      +"    }\n"
+      +"    if(ns6)\n"
+      +"    {\n"
+      +"      document.getElementById(\"toolTipLayer\").innerHTML = content;\n"
+      +"      toolTipSTYLE.display='block'\n"
+      +"    }\n"
+      +"    if(ie4)\n"
+      +"    {\n"
+      +"      document.all(\"toolTipLayer\").innerHTML=content;\n"
+      +"      toolTipSTYLE.display='block'\n"
+      +"    }\n"
+      +"  }\n"
+      +"}\n"
+      +"function moveToMouseLoc(e)\n"
+      +"{\n"
+      +"  if(ns4||ns6)\n"
+      +"  {\n"
+      +"    x = e.pageX;\n"
+      +"    y = e.pageY;\n"
+      +"  }\n"
+      +"  else\n"
+      +"  {\n"
+      +"    x = event.x + document.body.scrollLeft;\n"
+      +"    y = event.y + document.body.scrollTop;\n"
+      +"  }\n"
+      +"  toolTipSTYLE.left = x + offsetX;\n"
+      +"  toolTipSTYLE.top = y + offsetY;\n"
+      +"  return true;\n"
+      +"}\n"
+      +"</script>\n"
+      +"</head>\n"
+      +"<body>\n"
+      +"<div id=\"toolTipLayer\" style=\"position:absolute; visibility: hidden\"></div>\n"
+      +"<script language=\"JavaScript\"><!--\n"
+      +"initToolTips(); //--></script>\n");
+
+  }
+}
index 2040769..ff10547 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-\r
-import java.net.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class IdentifyFile\r
-{\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param file DOCUMENT ME!\r
-     * @param protocol DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String Identify(String file, String protocol)\r
-    {\r
-        String reply = "PFAM";\r
-        String error =  "FILE NOT FOUND";\r
-        try\r
-        {\r
-            BufferedReader reader = null;\r
-\r
-            if (protocol.equals(AppletFormatAdapter.FILE))\r
-            {\r
-              reader = new BufferedReader(new FileReader(file));\r
-            }\r
-            else if (protocol.equals(AppletFormatAdapter.URL))\r
-            {\r
-              error = "URL NOT FOUND";\r
-              URL url = new URL(file);\r
-              reader = new BufferedReader(new InputStreamReader(\r
-                  url.openStream()));\r
-\r
-            }\r
-            else if (protocol.equals(AppletFormatAdapter.PASTE))\r
-            {\r
-              reader = new BufferedReader(new StringReader(file));\r
-            }\r
-            else if (protocol.equals(AppletFormatAdapter.CLASSLOADER))\r
-            {\r
-              java.io.InputStream is = getClass().getResourceAsStream("/" +\r
-                  file);\r
-              reader = new BufferedReader(new java.io.InputStreamReader(is));\r
-            }\r
-\r
-            String data;\r
-\r
-            while ((data = reader.readLine()) != null)\r
-            {\r
-                data = data.toUpperCase();\r
-\r
-                if ((data.indexOf("#") == 0) || (data.length() < 1))\r
-                {\r
-                    continue;\r
-                }\r
-\r
-                if (data.indexOf("PILEUP") > -1)\r
-                {\r
-                    reply = "PileUp";\r
-\r
-                    break;\r
-                }\r
-\r
-                if ((data.indexOf("//") == 0) ||\r
-                        ((data.indexOf("!!") > -1) &&\r
-                        (data.indexOf("!!") < data.indexOf(\r
-                            "_MULTIPLE_ALIGNMENT "))))\r
-                {\r
-                    reply = "MSF";\r
-\r
-                    break;\r
-                }\r
-                else if (data.indexOf("CLUSTAL") > -1)\r
-                {\r
-                    reply = "CLUSTAL";\r
-\r
-                    break;\r
-                }\r
-                else if ((data.indexOf(">P1;") > -1) ||\r
-                        (data.indexOf(">DL;") > -1))\r
-                {\r
-                    reply = "PIR";\r
-\r
-                    break;\r
-                }\r
-                else if (data.indexOf(">") > -1)\r
-                {\r
-                    // could be BLC file, read next line to confirm\r
-                    data = reader.readLine();\r
-\r
-                    if (data.indexOf(">") > -1 || data.indexOf("*") >-1 )\r
-                    {\r
-                        reply = "BLC";\r
-                    }\r
-                    else\r
-                    {\r
-                        reply = "FASTA";\r
-                    }\r
-\r
-                    break;\r
-                }\r
-            }\r
-\r
-            reader.close();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            System.err.println("File Identification failed!\n" + ex);\r
-            return error;\r
-        }\r
-        return reply;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import java.io.*;
+
+import java.net.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdentifyFile
+{
+    /**
+     * DOCUMENT ME!
+     *
+     * @param file DOCUMENT ME!
+     * @param protocol DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String Identify(String file, String protocol)
+    {
+        String reply = "PFAM";
+        String error =  "FILE NOT FOUND";
+        try
+        {
+            BufferedReader reader = null;
+
+            if (protocol.equals(AppletFormatAdapter.FILE))
+            {
+              reader = new BufferedReader(new FileReader(file));
+            }
+            else if (protocol.equals(AppletFormatAdapter.URL))
+            {
+              error = "URL NOT FOUND";
+              URL url = new URL(file);
+              reader = new BufferedReader(new InputStreamReader(
+                  url.openStream()));
+
+            }
+            else if (protocol.equals(AppletFormatAdapter.PASTE))
+            {
+              reader = new BufferedReader(new StringReader(file));
+            }
+            else if (protocol.equals(AppletFormatAdapter.CLASSLOADER))
+            {
+              java.io.InputStream is = getClass().getResourceAsStream("/" +
+                  file);
+              reader = new BufferedReader(new java.io.InputStreamReader(is));
+            }
+
+            String data;
+
+            while ((data = reader.readLine()) != null)
+            {
+                data = data.toUpperCase();
+
+                if ( (data.indexOf("# STOCKHOLM") > -1))
+                {
+                  reply = "STH";
+
+                  break;
+                }
+
+                if ((data.indexOf("#") == 0) || (data.length() < 1))
+                {
+                    continue;
+                }
+
+                if (data.indexOf("PILEUP") > -1)
+                {
+                    reply = "PileUp";
+
+                    break;
+                }
+
+                if ((data.indexOf("//") == 0) ||
+                        ((data.indexOf("!!") > -1) &&
+                        (data.indexOf("!!") < data.indexOf(
+                            "_MULTIPLE_ALIGNMENT "))))
+                {
+                    reply = "MSF";
+
+                    break;
+                }
+                else if (data.indexOf("CLUSTAL") > -1)
+                {
+                    reply = "CLUSTAL";
+
+                    break;
+                }
+                else if ((data.indexOf(">P1;") > -1) ||
+                        (data.indexOf(">DL;") > -1))
+                {
+                    reply = "PIR";
+
+                    break;
+                }
+                else if (data.indexOf(">") > -1)
+                {
+                    // could be BLC file, read next line to confirm
+                    data = reader.readLine();
+
+                    if (data.indexOf(">") > -1 || data.indexOf("*") >-1 )
+                    {
+                        reply = "BLC";
+                    }
+                    else
+                    {
+                        reply = "FASTA";
+                    }
+
+                    break;
+                  }
+                  else if (data.indexOf("HEADER") > -1 ||
+                           data.indexOf("ATOM") > -1)
+                  {
+                    reply = "PDB";
+                    break;
+                  }
+                  else if (data.indexOf(":") < data.indexOf(",")) //  && data.indexOf(",")<data.indexOf(",", data.indexOf(",")))
+                  {
+                    // file looks like a concise JNet file
+                    reply = "JnetFile";
+                    break;
+                  }
+            }
+
+            reader.close();
+        }
+        catch (Exception ex)
+        {
+            System.err.println("File Identification failed!\n" + ex);
+            return error;
+        }
+
+        return reply;
+    }
+}
index f5ba7d6..5c2f4e6 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-\r
-/**\r
- * PredFile.java\r
- * JalviewX / Vamsas Project\r
- * JPred.seq.concise reader\r
- */\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class JPredFile extends AlignFile\r
-{\r
-    Vector ids;\r
-    Vector conf;\r
-    Hashtable Scores; // Hash of names and score vectors\r
-    Hashtable Symscores; // indexes of symbol annotation properties in sequenceI vector\r
-    private int QuerySeqPosition;\r
-\r
-    /**\r
-     * Creates a new JPredFile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public JPredFile(String inStr)\r
-    {\r
-        super(inStr);\r
-    }\r
-\r
-    /**\r
-     * Creates a new JPredFile object.\r
-     *\r
-     * @param inFile DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public JPredFile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param QuerySeqPosition DOCUMENT ME!\r
-     */\r
-    public void setQuerySeqPosition(int QuerySeqPosition)\r
-    {\r
-        this.QuerySeqPosition = QuerySeqPosition;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int getQuerySeqPosition()\r
-    {\r
-        return QuerySeqPosition;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Hashtable getScores()\r
-    {\r
-        return Scores;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Hashtable getSymscores()\r
-    {\r
-        return Symscores;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void initData()\r
-    {\r
-        super.initData();\r
-        Scores = new Hashtable();\r
-        ids = null;\r
-        conf = null;\r
-    }\r
-\r
-    /**\r
- * parse a JPred concise file into a sequence-alignment like object.\r
- */\r
-    public void parse() throws IOException\r
-    {\r
-        // JBPNote log.System.out.println("all read in ");\r
-        String line;\r
-        QuerySeqPosition = -1;\r
-        noSeqs = 0;\r
-\r
-        Vector seq_entries = new Vector();\r
-        Vector ids = new Vector();\r
-        Hashtable Symscores = new Hashtable();\r
-\r
-        while ((line = nextLine()) != null)\r
-        {\r
-            // Concise format allows no comments or non comma-formatted data\r
-            StringTokenizer str = new StringTokenizer(line, ":");\r
-            String id = "";\r
-\r
-            if (!str.hasMoreTokens())\r
-            {\r
-                continue;\r
-            }\r
-\r
-            id = str.nextToken();\r
-\r
-            String seqsym = str.nextToken();\r
-            StringTokenizer symbols = new StringTokenizer(seqsym, ",");\r
-\r
-            // decide if we have more than just alphanumeric symbols\r
-            int numSymbols = symbols.countTokens();\r
-\r
-            if (numSymbols == 0)\r
-            {\r
-                continue;\r
-            }\r
-\r
-            if (seqsym.length() != (2 * numSymbols))\r
-            {\r
-                // Set of scalars for some property\r
-                if (Scores.containsKey(id))\r
-                {\r
-                    int i = 1;\r
-\r
-                    while (Scores.containsKey(id + "_" + i))\r
-                    {\r
-                        i++;\r
-                    }\r
-\r
-                    id = id + "_" + i;\r
-                }\r
-\r
-                Vector scores = new Vector();\r
-\r
-                // Typecheck from first entry\r
-                int i = 0;\r
-                String ascore = "dead";\r
-\r
-                try\r
-                {\r
-                    // store elements as floats...\r
-                    while (symbols.hasMoreTokens())\r
-                    {\r
-                        ascore = symbols.nextToken();\r
-\r
-                        Float score = new Float(ascore);\r
-                        scores.addElement((Object) score);\r
-                    }\r
-\r
-                    Scores.put(id, scores);\r
-                }\r
-                catch (Exception e)\r
-                {\r
-                    // or just keep them as strings\r
-                    i = scores.size();\r
-\r
-                    for (int j = 0; j < i; j++)\r
-                    {\r
-                        scores.set(j,\r
-                            (Object) ((Float) scores.get(j)).toString());\r
-                    }\r
-\r
-                    scores.addElement((Object) ascore);\r
-\r
-                    while (symbols.hasMoreTokens())\r
-                    {\r
-                        ascore = symbols.nextToken();\r
-                        scores.addElement((Object) ascore);\r
-                    }\r
-\r
-                    Scores.put(id, scores);\r
-                }\r
-            }\r
-            else if (id.equals("jnetconf"))\r
-            {\r
-                // log.debug System.out.println("here");\r
-                id = "Prediction Confidence";\r
-                this.conf = new Vector(numSymbols);\r
-\r
-                for (int i = 0; i < numSymbols; i++)\r
-                {\r
-                    conf.set(i, (Object) symbols.nextToken());\r
-                }\r
-            }\r
-            else\r
-            {\r
-                // Sequence or a prediction string (rendered as sequence)\r
-                StringBuffer newseq = new StringBuffer();\r
-\r
-                for (int i = 0; i < numSymbols; i++)\r
-                {\r
-                    newseq.append(symbols.nextToken());\r
-                }\r
-\r
-                if (id.indexOf(";") > -1)\r
-                {\r
-                    seq_entries.addElement(newseq);\r
-\r
-                    int i = 1;\r
-                    String name = id.substring(id.indexOf(";") + 1);\r
-\r
-                    while (ids.lastIndexOf(name) > -1)\r
-                    {\r
-                        name = id.substring(id.indexOf(";") + 1) + "_" + ++i;\r
-                    }\r
-\r
-                    ids.addElement(name);\r
-\r
-                    noSeqs++;\r
-                }\r
-                else\r
-                {\r
-                    if (id.equals("JNETPRED"))\r
-                    {\r
-                        id = "Predicted Secondary Structure";\r
-                    }\r
-\r
-                    seq_entries.addElement(newseq.toString());\r
-                    ids.addElement(id);\r
-                    Symscores.put((Object) id,\r
-                        (Object) new Integer(ids.size() - 1));\r
-                }\r
-            }\r
-        }\r
-\r
-        if (noSeqs < 1)\r
-        {\r
-            throw new IOException(\r
-                "JpredFile Parser: No sequence in the prediction!");\r
-        }\r
-\r
-        maxLength = seq_entries.elementAt(0).toString().length();\r
-\r
-        for (int i = 0; i < ids.size(); i++)\r
-        {\r
-            // Add all sequence like objects\r
-            Sequence newSeq = new Sequence(ids.elementAt(i).toString(),\r
-                    seq_entries.elementAt(i).toString(), 1,\r
-                    seq_entries.elementAt(i).toString().length());\r
-\r
-            if (!Symscores.containsKey(ids.elementAt(i)) &&\r
-                    !isValidProteinSequence(newSeq.getSequence()))\r
-            {\r
-                throw new IOException("JPredConcise: "\r
-                                      +AppletFormatAdapter.INVALID_CHARACTERS +" : "\r
-                                      +ids.elementAt(i).toString() + ")");\r
-            }\r
-\r
-            if (maxLength != seq_entries.elementAt(i).toString().length())\r
-            {\r
-                throw new IOException("JPredConcise: Entry (" +\r
-                    ids.elementAt(i).toString() +\r
-                    ") has an unexpected number of columns");\r
-            }\r
-\r
-            if (newSeq.getName().startsWith("QUERY") &&\r
-                    (QuerySeqPosition == -1))\r
-            {\r
-                QuerySeqPosition = seqs.size();\r
-            }\r
-\r
-            seqs.addElement(newSeq);\r
-        }\r
-    }\r
-\r
-    /**\r
- * print\r
- *\r
- * @return String\r
-   */\r
-    public String print()\r
-    {\r
-        return "Not Supported";\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param args DOCUMENT ME!\r
-     */\r
-    public static void main(String[] args)\r
-    {\r
-        try\r
-        {\r
-            JPredFile blc = new JPredFile(args[0], "File");\r
-\r
-            for (int i = 0; i < blc.seqs.size(); i++)\r
-            {\r
-                System.out.println(((Sequence) blc.seqs.elementAt(i)).getName() +\r
-                    "\n" + ((Sequence) blc.seqs.elementAt(i)).getSequence() +\r
-                    "\n");\r
-            }\r
-        }\r
-        catch (java.io.IOException e)\r
-        {\r
-            System.err.println("Exception " + e);\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-}\r
-\r
-\r
-/*\r
- StringBuffer out = new StringBuffer();\r
-\r
- out.append("START PRED\n");\r
- for (int i = 0; i < s[0].sequence.length(); i++)\r
- {\r
-  out.append(s[0].sequence.substring(i, i + 1) + " ");\r
-  out.append(s[1].sequence.substring(i, i + 1) + " ");\r
-  out.append(s[1].score[0].elementAt(i) + " ");\r
-  out.append(s[1].score[1].elementAt(i) + " ");\r
-  out.append(s[1].score[2].elementAt(i) + " ");\r
-  out.append(s[1].score[3].elementAt(i) + " ");\r
-\r
-  out.append("\n");\r
- }\r
- out.append("END PRED\n");\r
- return out.toString();\r
- }\r
-\r
-    public static void main(String[] args)\r
- {\r
-  try\r
-  {\r
-    BLCFile blc = new BLCFile(args[0], "File");\r
-    DrawableSequence[] s = new DrawableSequence[blc.seqs.size()];\r
-    for (int i = 0; i < blc.seqs.size(); i++)\r
-    {\r
-      s[i] = new DrawableSequence( (Sequence) blc.seqs.elementAt(i));\r
-    }\r
-    String out = BLCFile.print(s);\r
-\r
-    AlignFrame af = new AlignFrame(null, s);\r
-    af.resize(700, 500);\r
-    af.show();\r
-    System.out.println(out);\r
-  }\r
-  catch (java.io.IOException e)\r
-  {\r
-    System.out.println("Exception " + e);\r
-  }\r
- }\r
-\r
- }\r
- */\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+
+/**
+ * PredFile.java
+ * JalviewX / Vamsas Project
+ * JPred.seq.concise reader
+ */
+package jalview.io;
+
+import java.io.*;
+import java.util.*;
+
+import jalview.datamodel.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class JPredFile extends AlignFile
+{
+    Vector ids;
+    Vector conf;
+    Hashtable Scores; // Hash of names and score vectors
+    Hashtable Symscores; // indexes of symbol annotation properties in sequenceI vector
+    private int QuerySeqPosition;
+
+
+    /**
+     * Creates a new JPredFile object.
+     *
+     * @param inFile DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public JPredFile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param QuerySeqPosition DOCUMENT ME!
+     */
+    public void setQuerySeqPosition(int QuerySeqPosition)
+    {
+        this.QuerySeqPosition = QuerySeqPosition;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getQuerySeqPosition()
+    {
+        return QuerySeqPosition;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Hashtable getScores()
+    {
+        return Scores;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Hashtable getSymscores()
+    {
+        return Symscores;
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void initData()
+    {
+        super.initData();
+        Scores = new Hashtable();
+        ids = null;
+        conf = null;
+    }
+
+    /**
+ * parse a JPred concise file into a sequence-alignment like object.
+ */
+    public void parse() throws IOException
+    {
+        // JBPNote log.System.out.println("all read in ");
+        String line;
+        QuerySeqPosition = -1;
+        noSeqs = 0;
+
+        Vector seq_entries = new Vector();
+        Vector ids = new Vector();
+        Hashtable Symscores = new Hashtable();
+
+        while ((line = nextLine()) != null)
+        {
+            // Concise format allows no comments or non comma-formatted data
+            StringTokenizer str = new StringTokenizer(line, ":");
+            String id = "";
+
+            if (!str.hasMoreTokens())
+            {
+                continue;
+            }
+
+            id = str.nextToken();
+
+            String seqsym = str.nextToken();
+            StringTokenizer symbols = new StringTokenizer(seqsym, ",");
+
+            // decide if we have more than just alphanumeric symbols
+            int numSymbols = symbols.countTokens();
+
+            if (numSymbols == 0)
+            {
+                continue;
+            }
+
+            if (seqsym.length() != (2 * numSymbols))
+            {
+                // Set of scalars for some property
+                if (Scores.containsKey(id))
+                {
+                    int i = 1;
+
+                    while (Scores.containsKey(id + "_" + i))
+                    {
+                        i++;
+                    }
+
+                    id = id + "_" + i;
+                }
+
+                Vector scores = new Vector();
+
+                // Typecheck from first entry
+                int i = 0;
+                String ascore = "dead";
+
+                try
+                {
+                    // store elements as floats...
+                    while (symbols.hasMoreTokens())
+                    {
+                        ascore = symbols.nextToken();
+
+                        Float score = new Float(ascore);
+                        scores.addElement((Object) score);
+                    }
+
+                    Scores.put(id, scores);
+                }
+                catch (Exception e)
+                {
+                    // or just keep them as strings
+                    i = scores.size();
+
+                    for (int j = 0; j < i; j++)
+                    {
+                        scores.setElementAt(
+                            (Object) ((Float) scores.elementAt(j)).toString(), j);
+                    }
+
+                    scores.addElement((Object) ascore);
+
+                    while (symbols.hasMoreTokens())
+                    {
+                        ascore = symbols.nextToken();
+                        scores.addElement((Object) ascore);
+                    }
+
+                    Scores.put(id, scores);
+                }
+            }
+            else if (id.equals("jnetconf"))
+            {
+                // log.debug System.out.println("here");
+                id = "Prediction Confidence";
+                this.conf = new Vector(numSymbols);
+
+                for (int i = 0; i < numSymbols; i++)
+                {
+                    conf.setElementAt( symbols.nextToken(), i);
+                }
+            }
+            else
+            {
+                // Sequence or a prediction string (rendered as sequence)
+                StringBuffer newseq = new StringBuffer();
+
+                for (int i = 0; i < numSymbols; i++)
+                {
+                    newseq.append(symbols.nextToken());
+                }
+
+                if (id.indexOf(";") > -1)
+                {
+                    seq_entries.addElement(newseq);
+
+                    int i = 1;
+                    String name = id.substring(id.indexOf(";") + 1);
+
+                    while (ids.lastIndexOf(name) > -1)
+                    {
+                        name = id.substring(id.indexOf(";") + 1) + "_" + ++i;
+                    }
+
+                    ids.addElement(name);
+
+                    noSeqs++;
+                }
+                else
+                {
+                    if (id.equals("JNETPRED"))
+                    {
+                        id = "Predicted Secondary Structure";
+                    }
+
+                    seq_entries.addElement(newseq.toString());
+                    ids.addElement(id);
+                    Symscores.put((Object) id,
+                        (Object) new Integer(ids.size() - 1));
+                }
+            }
+        }
+        /* leave it to the parser user to actually check this.
+        if (noSeqs < 1)
+        {
+            throw new IOException(
+                "JpredFile Parser: No sequence in the prediction!");
+        }*/
+
+        maxLength = seq_entries.elementAt(0).toString().length();
+
+        for (int i = 0; i < ids.size(); i++)
+        {
+            // Add all sequence like objects
+            Sequence newSeq = new Sequence(ids.elementAt(i).toString(),
+                    seq_entries.elementAt(i).toString(), 1,
+                    seq_entries.elementAt(i).toString().length());
+
+            if (!Symscores.containsKey(ids.elementAt(i)) &&
+                    !isValidProteinSequence(newSeq.getSequence()))
+            {
+                throw new IOException("JPredConcise: "
+                                      +AppletFormatAdapter.INVALID_CHARACTERS +" : "
+                                      +ids.elementAt(i).toString() + ")");
+            }
+
+            if (maxLength != seq_entries.elementAt(i).toString().length())
+            {
+                throw new IOException("JPredConcise: Entry (" +
+                    ids.elementAt(i).toString() +
+                    ") has an unexpected number of columns");
+            }
+
+            if (newSeq.getName().startsWith("QUERY") &&
+                    (QuerySeqPosition == -1))
+            {
+                QuerySeqPosition = seqs.size();
+            }
+
+            seqs.addElement(newSeq);
+        }
+    }
+
+    /**
+ * print
+ *
+ * @return String
+   */
+    public String print()
+    {
+        return "Not Supported";
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param args DOCUMENT ME!
+     */
+    public static void main(String[] args)
+    {
+        try
+        {
+            JPredFile blc = new JPredFile(args[0], "File");
+
+            for (int i = 0; i < blc.seqs.size(); i++)
+            {
+                System.out.println(((Sequence) blc.seqs.elementAt(i)).getName() +
+                    "\n" + ((Sequence) blc.seqs.elementAt(i)).getSequence() +
+                    "\n");
+            }
+        }
+        catch (java.io.IOException e)
+        {
+            System.err.println("Exception " + e);
+            e.printStackTrace();
+        }
+    }
+    Vector annotSeqs=null;
+  /**
+   * removeNonSequences
+   */
+  public void removeNonSequences()
+  {
+    if (annotSeqs!=null)
+      return;
+    annotSeqs = new Vector();
+    Vector newseqs = new Vector();
+    int i=0;
+    int j=seqs.size();
+    for (; i<QuerySeqPosition; i++)
+        annotSeqs.addElement(seqs.elementAt(i));
+      // check that no stray annotations have been added at the end.
+      {
+        SequenceI sq = (SequenceI) seqs.elementAt(j-1);
+        if (sq.getName().toUpperCase().startsWith("JPRED")) {
+          annotSeqs.addElement(sq);
+          seqs.removeElementAt(--j);
+        }
+      }
+    for (; i<j; i++)
+        newseqs.addElement(seqs.elementAt(i));
+
+    seqs.removeAllElements();
+    seqs = newseqs;
+  }
+}
+
+
+/*
+ StringBuffer out = new StringBuffer();
+
+ out.append("START PRED\n");
+ for (int i = 0; i < s[0].sequence.length(); i++)
+ {
+  out.append(s[0].sequence.substring(i, i + 1) + " ");
+  out.append(s[1].sequence.substring(i, i + 1) + " ");
+  out.append(s[1].score[0].elementAt(i) + " ");
+  out.append(s[1].score[1].elementAt(i) + " ");
+  out.append(s[1].score[2].elementAt(i) + " ");
+  out.append(s[1].score[3].elementAt(i) + " ");
+
+  out.append("\n");
+ }
+ out.append("END PRED\n");
+ return out.toString();
+ }
+
+    public static void main(String[] args)
+ {
+  try
+  {
+    BLCFile blc = new BLCFile(args[0], "File");
+    DrawableSequence[] s = new DrawableSequence[blc.seqs.size()];
+    for (int i = 0; i < blc.seqs.size(); i++)
+    {
+      s[i] = new DrawableSequence( (Sequence) blc.seqs.elementAt(i));
+    }
+    String out = BLCFile.print(s);
+
+    AlignFrame af = new AlignFrame(null, s);
+    af.resize(700, 500);
+    af.show();
+    System.out.println(out);
+  }
+  catch (java.io.IOException e)
+  {
+    System.out.println("Exception " + e);
+  }
+ }
+
+ }
+ */
index 2bac0de..28b336c 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-//////////////////////////////////////////////////////////////////\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.awt.*;\r
-import javax.swing.*;\r
-\r
-public class JalviewFileChooser\r
-    extends JFileChooser\r
-{\r
-\r
-  public JalviewFileChooser(String dir)\r
-  {\r
-    super(dir);\r
-  }\r
-\r
-  public JalviewFileChooser(String dir, String[] suffix, String[] desc,\r
-                            String selected)\r
-  {\r
-    super(dir);\r
-\r
-    JalviewFileFilter chosen = null;\r
-\r
-    for (int i = 0; i < suffix.length; i++)\r
-    {\r
-      JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);\r
-      addChoosableFileFilter(jvf);\r
-\r
-      if ( (selected != null) && selected.equalsIgnoreCase(desc[i]))\r
-      {\r
-        chosen = jvf;\r
-      }\r
-    }\r
-\r
-    if (chosen != null)\r
-    {\r
-      setFileFilter(chosen);\r
-    }\r
-  }\r
-\r
-  public void setFileFilter(javax.swing.filechooser.FileFilter filter)\r
-  {\r
-    super.setFileFilter(filter);\r
-\r
-    try{\r
-      if(getUI() instanceof javax.swing.plaf.basic.BasicFileChooserUI)\r
-      {\r
-        final javax.swing.plaf.basic.BasicFileChooserUI ui = (javax.swing.plaf.\r
-            basic.BasicFileChooserUI) getUI();\r
-        final String name = ui.getFileName().trim();\r
-\r
-        if ( (name == null) || (name.length() == 0))\r
-        {\r
-          return;\r
-        }\r
-\r
-        EventQueue.invokeLater(new Thread()\r
-        {\r
-          public void run()\r
-          {\r
-            String currentName = ui.getFileName();\r
-            if ( (currentName == null) || (currentName.length() == 0))\r
-            {\r
-              ui.setFileName(name);\r
-            }\r
-          }\r
-        });\r
-      }\r
-    }catch(Exception ex)\r
-    {\r
-      // Some platforms do not have BasicFileChooserUI\r
-    }\r
-  }\r
-\r
-\r
-  public String getSelectedFormat()\r
-  {\r
-    if(getFileFilter()==null)\r
-    {\r
-      return null;\r
-    }\r
-\r
-    String format = getFileFilter().getDescription();\r
-\r
-    if (format.toUpperCase().startsWith("JALVIEW"))\r
-    {\r
-      format = "Jalview";\r
-    }\r
-    else if (format.toUpperCase().startsWith("FASTA"))\r
-    {\r
-      format = "FASTA";\r
-    }\r
-    else if (format.toUpperCase().startsWith("MSF"))\r
-    {\r
-      format = "MSF";\r
-    }\r
-    else if (format.toUpperCase().startsWith("CLUSTAL"))\r
-    {\r
-      format = "CLUSTAL";\r
-    }\r
-    else if (format.toUpperCase().startsWith("BLC"))\r
-    {\r
-      format = "BLC";\r
-    }\r
-    else if (format.toUpperCase().startsWith("PIR"))\r
-    {\r
-      format = "PIR";\r
-    }\r
-    else if (format.toUpperCase().startsWith("PFAM"))\r
-    {\r
-      format = "PFAM";\r
-    }\r
-\r
-    return format;\r
-  }\r
-\r
-  public int showSaveDialog(Component parent)\r
-      throws HeadlessException\r
-  {\r
-    setDialogType(SAVE_DIALOG);\r
-\r
-    int ret = showDialog(parent, null);\r
-\r
-    if (getFileFilter() instanceof JalviewFileFilter)\r
-    {\r
-      JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();\r
-\r
-      if (!jvf.accept(getSelectedFile()))\r
-      {\r
-        String withExtension = getSelectedFile() + "." +\r
-            jvf.getAcceptableExtension();\r
-        setSelectedFile(new File(withExtension));\r
-      }\r
-    }\r
-\r
-    if ( (ret == JalviewFileChooser.APPROVE_OPTION) &&\r
-        getSelectedFile().exists())\r
-    {\r
-      int confirm = JOptionPane.showConfirmDialog(parent,\r
-                                                  "Overwrite existing file?",\r
-                                                  "File exists",\r
-                                                  JOptionPane.YES_NO_OPTION);\r
-\r
-      if (confirm != JOptionPane.YES_OPTION)\r
-      {\r
-        ret = JalviewFileChooser.CANCEL_OPTION;\r
-      }\r
-    }\r
-\r
-    return ret;\r
-  }\r
-}\r
-\r
-\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+//////////////////////////////////////////////////////////////////
+package jalview.io;
+
+import java.io.*;
+import java.awt.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.util.*;
+
+public class JalviewFileChooser
+    extends JFileChooser
+{
+
+  public JalviewFileChooser(String dir)
+  {
+    super(dir);
+    setAccessory(new RecentlyOpened());
+  }
+
+  public JalviewFileChooser(String dir,
+                            String[] suffix,
+                            String[] desc,
+                            String selected,
+                            boolean selectAll)
+  {
+    super(dir);
+    init( suffix, desc, selected, selectAll);
+  }
+
+  public JalviewFileChooser(String dir,
+                            String[] suffix,
+                            String[] desc,
+                            String selected)
+  {
+    super(dir);
+    init( suffix, desc, selected, true);
+  }
+
+  void init(String[] suffix,
+            String[] desc,
+            String selected,
+            boolean selectAll)
+  {
+
+    JalviewFileFilter chosen = null;
+
+    //SelectAllFilter needs to be set first before adding further
+    //file filters to fix bug on Mac OSX
+    setAcceptAllFileFilterUsed(selectAll);
+
+    for (int i = 0; i < suffix.length; i++)
+    {
+      JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);
+      addChoosableFileFilter(jvf);
+
+      if ( (selected != null) && selected.equalsIgnoreCase(desc[i]))
+      {
+        chosen = jvf;
+      }
+    }
+
+    if (chosen != null)
+    {
+      setFileFilter(chosen);
+    }
+
+    setAccessory(new RecentlyOpened());
+  }
+
+
+  public void setFileFilter(javax.swing.filechooser.FileFilter filter)
+  {
+    super.setFileFilter(filter);
+
+
+    try{
+      if(getUI() instanceof javax.swing.plaf.basic.BasicFileChooserUI)
+      {
+        final javax.swing.plaf.basic.BasicFileChooserUI ui = (javax.swing.plaf.
+            basic.BasicFileChooserUI) getUI();
+        final String name = ui.getFileName().trim();
+
+        if ( (name == null) || (name.length() == 0))
+        {
+          return;
+        }
+
+        EventQueue.invokeLater(new Thread()
+        {
+          public void run()
+          {
+            String currentName = ui.getFileName();
+            if ( (currentName == null) || (currentName.length() == 0))
+            {
+              ui.setFileName(name);
+            }
+          }
+        });
+      }
+    }catch(Exception ex)
+    {
+      ex.printStackTrace();
+      // Some platforms do not have BasicFileChooserUI
+    }
+  }
+
+  public String getSelectedFormat()
+  {
+    if(getFileFilter()==null)
+    {
+      return null;
+    }
+
+    String format = getFileFilter().getDescription();
+
+    if (format.toUpperCase().startsWith("JALVIEW"))
+    {
+      format = "Jalview";
+    }
+    else if (format.toUpperCase().startsWith("FASTA"))
+    {
+      format = "FASTA";
+    }
+    else if (format.toUpperCase().startsWith("MSF"))
+    {
+      format = "MSF";
+    }
+    else if (format.toUpperCase().startsWith("CLUSTAL"))
+    {
+      format = "CLUSTAL";
+    }
+    else if (format.toUpperCase().startsWith("BLC"))
+    {
+      format = "BLC";
+    }
+    else if (format.toUpperCase().startsWith("PIR"))
+    {
+      format = "PIR";
+    }
+    else if (format.toUpperCase().startsWith("PFAM"))
+    {
+      format = "PFAM";
+    }
+
+    return format;
+  }
+
+  public int showSaveDialog(Component parent)
+      throws HeadlessException
+  {
+    this.setAccessory(null);
+
+
+    setDialogType(SAVE_DIALOG);
+
+    int ret = showDialog(parent, "Save");
+
+    if (getFileFilter() instanceof JalviewFileFilter)
+    {
+      JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();
+
+      if (!jvf.accept(getSelectedFile()))
+      {
+        String withExtension = getSelectedFile() + "." +
+            jvf.getAcceptableExtension();
+        setSelectedFile(new File(withExtension));
+      }
+    }
+
+    if ( (ret == JalviewFileChooser.APPROVE_OPTION) &&
+        getSelectedFile().exists())
+    {
+      int confirm = JOptionPane.showConfirmDialog(parent,
+                                                  "Overwrite existing file?",
+                                                  "File exists",
+                                                  JOptionPane.YES_NO_OPTION);
+
+      if (confirm != JOptionPane.YES_OPTION)
+      {
+        ret = JalviewFileChooser.CANCEL_OPTION;
+      }
+    }
+
+    return ret;
+  }
+
+  void recentListSelectionChanged(String selection)
+  {
+    setSelectedFile(null);
+
+    File file = new File(selection);
+    if (getFileFilter() instanceof JalviewFileFilter)
+    {
+      JalviewFileFilter jvf = (JalviewFileFilter)this.getFileFilter();
+
+      if (!jvf.accept(file))
+      {
+        setFileFilter(getChoosableFileFilters()[0]);
+      }
+    }
+
+     setSelectedFile( file );
+  }
+
+  class RecentlyOpened extends JPanel
+  {
+    JList list;
+    public RecentlyOpened()
+    {
+      String historyItems = jalview.bin.Cache.getProperty("RECENT_FILE");
+      StringTokenizer st;
+      Vector recent = new Vector();
+
+      if (historyItems != null)
+      {
+        st = new StringTokenizer(historyItems, "\t");
+
+        while (st.hasMoreTokens())
+        {
+          recent.addElement(st.nextElement());
+        }
+      }
+
+      list = new JList(recent);
+
+      DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
+      dlcr.setHorizontalAlignment(DefaultListCellRenderer.RIGHT);
+      list.setCellRenderer(dlcr);
+
+
+      list.addMouseListener(new MouseAdapter()
+          {
+            public void mousePressed(MouseEvent evt)
+            {
+              recentListSelectionChanged(list.getSelectedValue().toString());
+            }
+          });
+
+      this.setBorder(new javax.swing.border.TitledBorder("Recently Opened"));
+
+      final JScrollPane scroller = new JScrollPane(list);
+      scroller.setPreferredSize(new Dimension(130, 200));
+      this.add(scroller);
+
+      javax.swing.SwingUtilities.invokeLater(new Runnable()
+      {
+        public void run()
+        {
+          scroller.getHorizontalScrollBar().setValue(
+              scroller.getHorizontalScrollBar().getMaximum());
+        }
+      });
+
+
+    }
+
+  }
+}
+
+
+
+
+
index 3252a98..534a079 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import javax.swing.filechooser.FileFilter;\r
-\r
-public class JalviewFileFilter\r
-    extends FileFilter\r
-{\r
-  public static Hashtable suffixHash = new Hashtable();\r
-  private Hashtable filters = null;\r
-  private String description = "no description";\r
-  private String fullDescription = "full description";\r
-  private boolean useExtensionsInDescription = true;\r
-\r
-  public JalviewFileFilter(String extension, String description)\r
-  {\r
-    StringTokenizer st = new StringTokenizer(extension, ",");\r
-\r
-    while (st.hasMoreElements())\r
-    {\r
-      addExtension(st.nextToken().trim());\r
-    }\r
-\r
-    setDescription(description);\r
-  }\r
-\r
-  public JalviewFileFilter(String[] filts)\r
-  {\r
-    this(filts, null);\r
-  }\r
-\r
-  public JalviewFileFilter(String[] filts, String description)\r
-  {\r
-    for (int i = 0; i < filts.length; i++)\r
-    {\r
-      // add filters one by one\r
-      addExtension(filts[i]);\r
-    }\r
-\r
-    if (description != null)\r
-    {\r
-      setDescription(description);\r
-    }\r
-  }\r
-\r
-  public String getAcceptableExtension()\r
-  {\r
-    return filters.keys().nextElement().toString();\r
-  }\r
-\r
-  // takes account of the fact that database is a directory\r
-  public boolean accept(File f)\r
-  {\r
-    if (f != null)\r
-    {\r
-      String extension = getExtension(f);\r
-\r
-      if (f.isDirectory())\r
-      {\r
-          return true;\r
-      }\r
-\r
-      if ( (extension != null) && (filters.get(getExtension(f)) != null))\r
-      {\r
-        return true;\r
-      }\r
-    }\r
-\r
-    return false;\r
-  }\r
-\r
-  public String getExtension(File f)\r
-  {\r
-    if (f != null)\r
-    {\r
-      String filename = f.getName();\r
-      int i = filename.lastIndexOf('.');\r
-\r
-      if ( (i > 0) && (i < (filename.length() - 1)))\r
-      {\r
-        return filename.substring(i + 1).toLowerCase();\r
-      }\r
-\r
-      ;\r
-    }\r
-\r
-    return "";\r
-  }\r
-\r
-  public void addExtension(String extension)\r
-  {\r
-    if (filters == null)\r
-    {\r
-      filters = new Hashtable(5);\r
-    }\r
-\r
-    filters.put(extension.toLowerCase(), this);\r
-    fullDescription = null;\r
-  }\r
-\r
-  public String getDescription()\r
-  {\r
-    if (fullDescription == null)\r
-    {\r
-      if ( (description == null) || isExtensionListInDescription())\r
-      {\r
-        fullDescription = (description == null) ? "(" : (description +\r
-            " (");\r
-\r
-        // build the description from the extension list\r
-        Enumeration extensions = filters.keys();\r
-\r
-        if (extensions != null)\r
-        {\r
-          fullDescription += ("." +\r
-                              (String) extensions.nextElement());\r
-\r
-          while (extensions.hasMoreElements())\r
-          {\r
-            fullDescription += (", " +\r
-                                (String) extensions.nextElement());\r
-          }\r
-        }\r
-\r
-        fullDescription += ")";\r
-      }\r
-      else\r
-      {\r
-        fullDescription = description;\r
-      }\r
-    }\r
-\r
-    return fullDescription;\r
-  }\r
-\r
-  public void setDescription(String description)\r
-  {\r
-    this.description = description;\r
-    fullDescription = null;\r
-  }\r
-\r
-  public void setExtensionListInDescription(boolean b)\r
-  {\r
-    useExtensionsInDescription = b;\r
-    fullDescription = null;\r
-  }\r
-\r
-  public boolean isExtensionListInDescription()\r
-  {\r
-    return useExtensionsInDescription;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+import java.util.*;
+
+import javax.swing.filechooser.FileFilter;
+
+public class JalviewFileFilter
+    extends FileFilter
+{
+  public static Hashtable suffixHash = new Hashtable();
+  private Hashtable filters = null;
+  private String description = "no description";
+  private String fullDescription = "full description";
+  private boolean useExtensionsInDescription = true;
+
+  public JalviewFileFilter(String extension, String description)
+  {
+    StringTokenizer st = new StringTokenizer(extension, ",");
+
+    while (st.hasMoreElements())
+    {
+      addExtension(st.nextToken().trim());
+    }
+
+    setDescription(description);
+  }
+
+  public JalviewFileFilter(String[] filts)
+  {
+    this(filts, null);
+  }
+
+  public JalviewFileFilter(String[] filts, String description)
+  {
+    for (int i = 0; i < filts.length; i++)
+    {
+      // add filters one by one
+      addExtension(filts[i]);
+    }
+
+    if (description != null)
+    {
+      setDescription(description);
+    }
+  }
+
+  public String getAcceptableExtension()
+  {
+    return filters.keys().nextElement().toString();
+  }
+
+  // takes account of the fact that database is a directory
+  public boolean accept(File f)
+  {
+    if (f != null)
+    {
+      String extension = getExtension(f);
+
+      if (f.isDirectory())
+      {
+          return true;
+      }
+
+      if ( (extension != null) && (filters.get(getExtension(f)) != null))
+      {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  public String getExtension(File f)
+  {
+    if (f != null)
+    {
+      String filename = f.getName();
+      int i = filename.lastIndexOf('.');
+
+      if ( (i > 0) && (i < (filename.length() - 1)))
+      {
+        return filename.substring(i + 1).toLowerCase();
+      }
+
+      ;
+    }
+
+    return "";
+  }
+
+  public void addExtension(String extension)
+  {
+    if (filters == null)
+    {
+      filters = new Hashtable(5);
+    }
+
+    filters.put(extension.toLowerCase(), this);
+    fullDescription = null;
+  }
+
+  public String getDescription()
+  {
+    if (fullDescription == null)
+    {
+      if ( (description == null) || isExtensionListInDescription())
+      {
+        fullDescription = (description == null) ? "(" : (description +
+            " (");
+
+        // build the description from the extension list
+        Enumeration extensions = filters.keys();
+
+        if (extensions != null)
+        {
+          fullDescription += ("." +
+                              (String) extensions.nextElement());
+
+          while (extensions.hasMoreElements())
+          {
+            fullDescription += (", " +
+                                (String) extensions.nextElement());
+          }
+        }
+
+        fullDescription += ")";
+      }
+      else
+      {
+        fullDescription = description;
+      }
+    }
+
+    return fullDescription;
+  }
+
+  public void setDescription(String description)
+  {
+    this.description = description;
+    fullDescription = null;
+  }
+
+  public void setExtensionListInDescription(boolean b)
+  {
+    useExtensionsInDescription = b;
+    fullDescription = null;
+  }
+
+  public boolean isExtensionListInDescription()
+  {
+    return useExtensionsInDescription;
+  }
+}
index 04189e1..3d1706d 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-import javax.swing.filechooser.*;\r
-\r
-public class JalviewFileView\r
-    extends FileView\r
-{\r
-  static Hashtable alignSuffix = new Hashtable();\r
-\r
-  static\r
-  {\r
-    alignSuffix.put("fasta", "Fasta file");\r
-    alignSuffix.put("fa", "Fasta file");\r
-    alignSuffix.put("fastq", "Fasta file");\r
-    alignSuffix.put("blc", "BLC file");\r
-    alignSuffix.put("msf", "MSF file");\r
-    alignSuffix.put("pfam", "PFAM file");\r
-    alignSuffix.put("aln", "Clustal file");\r
-    alignSuffix.put("pir", "PIR file");\r
-    alignSuffix.put("jar", "Jalview file");\r
-  }\r
-\r
-  public String getTypeDescription(File f)\r
-  {\r
-    String extension = getExtension(f);\r
-    String type = null;\r
-\r
-    if (extension != null)\r
-    {\r
-      if (alignSuffix.containsKey(extension))\r
-      {\r
-        type = alignSuffix.get(extension).toString();\r
-      }\r
-    }\r
-\r
-    return type;\r
-  }\r
-\r
-  public Icon getIcon(File f)\r
-  {\r
-    String extension = getExtension(f);\r
-    Icon icon = null;\r
-\r
-    if (extension != null)\r
-    {\r
-      if (alignSuffix.containsKey(extension))\r
-      {\r
-        icon = createImageIcon("/images/file.png");\r
-      }\r
-    }\r
-\r
-    return icon;\r
-  }\r
-\r
-  /*\r
-   * Get the extension of a file.\r
-   */\r
-  public static String getExtension(File f)\r
-  {\r
-    String ext = null;\r
-    String s = f.getName();\r
-    int i = s.lastIndexOf('.');\r
-\r
-    if ( (i > 0) && (i < (s.length() - 1)))\r
-    {\r
-      ext = s.substring(i + 1).toLowerCase();\r
-    }\r
-\r
-    return ext;\r
-  }\r
-\r
-  /** Returns an ImageIcon, or null if the path was invalid. */\r
-  protected static ImageIcon createImageIcon(String path)\r
-  {\r
-    java.net.URL imgURL = JalviewFileView.class.getResource(path);\r
-\r
-    if (imgURL != null)\r
-    {\r
-      return new ImageIcon(imgURL);\r
-    }\r
-    else\r
-    {\r
-      System.err.println(\r
-          "JalviewFileView.createImageIcon: Couldn't find file: " + path);\r
-\r
-      return null;\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.filechooser.*;
+
+public class JalviewFileView
+    extends FileView
+{
+  static Hashtable alignSuffix = new Hashtable();
+
+  static
+  {
+    alignSuffix.put("fasta", "Fasta file");
+    alignSuffix.put("fa", "Fasta file");
+    alignSuffix.put("fastq", "Fasta file");
+    alignSuffix.put("blc", "BLC file");
+    alignSuffix.put("msf", "MSF file");
+    alignSuffix.put("pfam", "PFAM file");
+    alignSuffix.put("aln", "Clustal file");
+    alignSuffix.put("pir", "PIR file");
+    alignSuffix.put("jar", "Jalview file");
+  }
+
+  public String getTypeDescription(File f)
+  {
+    String extension = getExtension(f);
+    String type = null;
+
+    if (extension != null)
+    {
+      if (alignSuffix.containsKey(extension))
+      {
+        type = alignSuffix.get(extension).toString();
+      }
+    }
+
+    return type;
+  }
+
+  public Icon getIcon(File f)
+  {
+    String extension = getExtension(f);
+    Icon icon = null;
+
+    if (extension != null)
+    {
+      if (alignSuffix.containsKey(extension))
+      {
+        icon = createImageIcon("/images/file.png");
+      }
+    }
+
+    return icon;
+  }
+
+  /*
+   * Get the extension of a file.
+   */
+  public static String getExtension(File f)
+  {
+    String ext = null;
+    String s = f.getName();
+    int i = s.lastIndexOf('.');
+
+    if ( (i > 0) && (i < (s.length() - 1)))
+    {
+      ext = s.substring(i + 1).toLowerCase();
+    }
+
+    return ext;
+  }
+
+  /** Returns an ImageIcon, or null if the path was invalid. */
+  protected static ImageIcon createImageIcon(String path)
+  {
+    java.net.URL imgURL = JalviewFileView.class.getResource(path);
+
+    if (imgURL != null)
+    {
+      return new ImageIcon(imgURL);
+    }
+    else
+    {
+      System.err.println(
+          "JalviewFileView.createImageIcon: Couldn't find file: " + path);
+
+      return null;
+    }
+  }
+}
index bae4342..753b6ab 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.util.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class MSFfile extends AlignFile\r
-{\r
-\r
-\r
-    /**\r
-     * Creates a new MSFfile object.\r
-     */\r
-    public MSFfile()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Creates a new MSFfile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public MSFfile(String inStr)\r
-    {\r
-        super(inStr);\r
-    }\r
-\r
-    /**\r
-     * Creates a new MSFfile object.\r
-     *\r
-     * @param inFile DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public MSFfile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void parse() throws IOException\r
-    {\r
-        int i = 0;\r
-        boolean seqFlag = false;\r
-        String key = new String();\r
-        Vector headers = new Vector();\r
-        Hashtable seqhash = new Hashtable();\r
-        String line;\r
-\r
-        try\r
-        {\r
-            while ((line = nextLine()) != null)\r
-            {\r
-                StringTokenizer str = new StringTokenizer(line);\r
-\r
-                while (str.hasMoreTokens())\r
-                {\r
-                    String inStr = str.nextToken();\r
-\r
-                    //If line has header information add to the headers vector\r
-                    if (inStr.indexOf("Name:") != -1)\r
-                    {\r
-                        key = str.nextToken();\r
-                        headers.addElement(key);\r
-                    }\r
-\r
-                    //if line has // set SeqFlag to 1 so we know sequences are coming\r
-                    if (inStr.indexOf("//") != -1)\r
-                    {\r
-                        seqFlag = true;\r
-                    }\r
-\r
-                    //Process lines as sequence lines if seqFlag is set\r
-                    if ((inStr.indexOf("//") == -1) && (seqFlag == true))\r
-                    {\r
-                        //seqeunce id is the first field\r
-                        key = inStr;\r
-\r
-                        StringBuffer tempseq;\r
-\r
-                        //Get sequence from hash if it exists\r
-                        if (seqhash.containsKey(key))\r
-                        {\r
-                            tempseq = (StringBuffer) seqhash.get(key);\r
-                        }\r
-                        else\r
-                        {\r
-                            tempseq = new StringBuffer();\r
-                            seqhash.put(key, tempseq);\r
-                        }\r
-\r
-                        //loop through the rest of the words\r
-                        while (str.hasMoreTokens())\r
-                        {\r
-                            //append the word to the sequence\r
-                            tempseq.append(str.nextToken());\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        catch (IOException e)\r
-        {\r
-            System.err.println("Exception parsing MSFFile " + e);\r
-            e.printStackTrace();\r
-        }\r
-\r
-        this.noSeqs = headers.size();\r
-\r
-        //Add sequences to the hash\r
-        for (i = 0; i < headers.size(); i++)\r
-        {\r
-            if (seqhash.get(headers.elementAt(i)) != null)\r
-            {\r
-                String head = headers.elementAt(i).toString();\r
-                String seq = seqhash.get(head).toString();\r
-\r
-                if (maxLength < head.length())\r
-                {\r
-                    maxLength = head.length();\r
-                }\r
-\r
-                // Replace ~ with a sensible gap character\r
-                seq = seq.replace('~', '-');\r
-                if (!isValidProteinSequence(seq))\r
-                {\r
-                    throw new IOException(AppletFormatAdapter.\r
-                                          INVALID_CHARACTERS\r
-                                          + " : " + head\r
-                                          + " : " + invalidCharacter);\r
-                }\r
-\r
-\r
-                Sequence newSeq = parseId(head);\r
-\r
-                newSeq.setSequence(seq);\r
-\r
-                seqs.addElement(newSeq);\r
-            }\r
-            else\r
-            {\r
-                System.err.println("MSFFile Parser: Can't find sequence for " +\r
-                    headers.elementAt(i));\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seq DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public int checkSum(String seq)\r
-    {\r
-        int check = 0;\r
-        String sequence = seq.toUpperCase();\r
-\r
-        for (int i = 0; i < sequence.length(); i++)\r
-        {\r
-            try\r
-            {\r
-\r
-                    int value = sequence.charAt(i);\r
-                    if (value!=-1)\r
-                    {\r
-                        check += (i % 57 +1) * value;\r
-                    }\r
-            }\r
-            catch (Exception e)\r
-            {\r
-                System.err.println("Exception during MSF Checksum calculation");\r
-                e.printStackTrace();\r
-            }\r
-        }\r
-\r
-        return check % 10000;\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param is_NA DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String print(SequenceI[] seqs)\r
-    {\r
-\r
-      boolean is_NA = jalview.util.Comparison.isNucleotide(seqs);\r
-\r
-      SequenceI [] s = new SequenceI[seqs.length];\r
-\r
-        StringBuffer out = new StringBuffer("!!" + (is_NA ? "NA" : "AA") +\r
-                "_MULTIPLE_ALIGNMENT 1.0\n\n"); // TODO: JBPNote : Jalview doesn't remember NA or AA yet.\r
-\r
-        int max = 0;\r
-        int maxid = 0;\r
-        int i = 0;\r
-\r
-        while ((i < seqs.length) && (seqs[i] != null))\r
-        {\r
-          // Replace all internal gaps with . and external spaces with ~\r
-          s[i] =new Sequence(seqs[i].getName(),seqs[i].getSequence().replace('-', '.'));\r
-\r
-          StringBuffer sb = new StringBuffer(s[i].getSequence());\r
-          for (int ii = 0; ii < sb.length(); ii++)\r
-          {\r
-            if (sb.charAt(ii) == '.')\r
-            {\r
-              sb.setCharAt(ii, '~');\r
-            }\r
-            else\r
-              break;\r
-          }\r
-\r
-          for (int ii = sb.length() - 1; ii > 0; ii--)\r
-          {\r
-            if (sb.charAt(ii) == '.')\r
-            {\r
-              sb.setCharAt(ii,'~');\r
-            }\r
-            else\r
-              break;\r
-          }\r
-\r
-            s[i].setSequence(sb.toString());\r
-\r
-            if (s[i].getSequence().length() > max)\r
-            {\r
-                max = s[i].getSequence().length();\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        Format maxLenpad = new Format("%" + (new String("" + max)).length() +\r
-                "d");\r
-        Format maxChkpad = new Format("%" + (new String("1" + max)).length() +\r
-                "d");\r
-        i = 0;\r
-\r
-        int bigChecksum = 0;\r
-        int [] checksums = new int[s.length];\r
-        while ( i < s.length )\r
-        {\r
-          checksums[i] = checkSum(s[i].getSequence());\r
-          bigChecksum += checksums[i];\r
-          i++;\r
-        }\r
-\r
-        long maxNB = 0;\r
-        out.append("   MSF: " + s[0].getSequence().length() + "   Type: " +\r
-            (is_NA ? "N" : "P") + "    Check:  " + (bigChecksum%10000) + "   ..\n\n\n");\r
-\r
-        String[] nameBlock = new String[s.length];\r
-        String[] idBlock = new String[s.length];\r
-\r
-        i=0;\r
-        while ((i < s.length) && (s[i] != null))\r
-        {\r
-\r
-            nameBlock[i] = new String("  Name: " + printId(s[i])+" ");\r
-\r
-            idBlock[i] = new String("Len: " +\r
-                    maxLenpad.form(s[i].getSequence().length()) + "  Check: " +\r
-                    maxChkpad.form(checksums[i]) + "  Weight: 1.00\n");\r
-\r
-            if (s[i].getName().length() > maxid)\r
-            {\r
-                maxid = s[i].getName().length();\r
-            }\r
-\r
-            if (nameBlock[i].length() > maxNB)\r
-            {\r
-                maxNB = nameBlock[i].length();\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        if (maxid < 10)\r
-        {\r
-            maxid = 10;\r
-        }\r
-\r
-        if (maxNB < 15)\r
-        {\r
-            maxNB = 15;\r
-        }\r
-\r
-        Format nbFormat = new Format("%-" + maxNB + "s");\r
-\r
-        for (i = 0; (i < s.length) && (s[i] != null); i++)\r
-        {\r
-            out.append(nbFormat.form(nameBlock[i]) + idBlock[i]);\r
-        }\r
-\r
-        maxid++;\r
-        out.append("\n\n//\n\n");\r
-\r
-        int len = 50;\r
-\r
-        int nochunks = (max / len) + 1;\r
-\r
-        if ((max % len) == 0)\r
-        {\r
-            nochunks--;\r
-        }\r
-\r
-        for (i = 0; i < nochunks; i++)\r
-        {\r
-            int j = 0;\r
-\r
-            while ((j < s.length) && (s[j] != null))\r
-            {\r
-                String name = printId( s[j] );\r
-\r
-                out.append(new Format("%-" + maxid + "s").form(name+" "));\r
-\r
-\r
-                for (int k = 0; k < 5; k++)\r
-                {\r
-                    int start = (i * 50) + (k * 10);\r
-                    int end = start + 10;\r
-\r
-                    if ((end < s[j].getSequence().length()) &&\r
-                            (start < s[j].getSequence().length()))\r
-                    {\r
-                        out.append(s[j].getSequence().substring(start, end));\r
-\r
-                        if (k < 4)\r
-                        {\r
-                             out.append(" ");\r
-                        }\r
-                        else\r
-                        {\r
-                            out.append("\n");\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        if (start < s[j].getSequence().length())\r
-                        {\r
-                            out.append(s[j].getSequence().substring(start));\r
-                            out.append("\n");\r
-                        }\r
-                        else\r
-                        {\r
-                            if (k == 0)\r
-                            {\r
-                                out.append("\n");\r
-                            }\r
-                        }\r
-                    }\r
-                }\r
-\r
-                j++;\r
-            }\r
-\r
-            out.append("\n");\r
-        }\r
-\r
-        return out.toString();\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public String print()\r
-    {\r
-        return print(getSeqsAsArray());\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import jalview.datamodel.*;
+
+import jalview.util.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class MSFfile extends AlignFile
+{
+
+
+    /**
+     * Creates a new MSFfile object.
+     */
+    public MSFfile()
+    {
+    }
+
+
+    /**
+     * Creates a new MSFfile object.
+     *
+     * @param inFile DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public MSFfile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void parse() throws IOException
+    {
+        int i = 0;
+        boolean seqFlag = false;
+        String key = new String();
+        Vector headers = new Vector();
+        Hashtable seqhash = new Hashtable();
+        String line;
+
+        try
+        {
+            while ((line = nextLine()) != null)
+            {
+                StringTokenizer str = new StringTokenizer(line);
+
+                while (str.hasMoreTokens())
+                {
+                    String inStr = str.nextToken();
+
+                    //If line has header information add to the headers vector
+                    if (inStr.indexOf("Name:") != -1)
+                    {
+                        key = str.nextToken();
+                        headers.addElement(key);
+                    }
+
+                    //if line has // set SeqFlag to 1 so we know sequences are coming
+                    if (inStr.indexOf("//") != -1)
+                    {
+                        seqFlag = true;
+                    }
+
+                    //Process lines as sequence lines if seqFlag is set
+                    if ((inStr.indexOf("//") == -1) && (seqFlag == true))
+                    {
+                        //seqeunce id is the first field
+                        key = inStr;
+
+                        StringBuffer tempseq;
+
+                        //Get sequence from hash if it exists
+                        if (seqhash.containsKey(key))
+                        {
+                            tempseq = (StringBuffer) seqhash.get(key);
+                        }
+                        else
+                        {
+                            tempseq = new StringBuffer();
+                            seqhash.put(key, tempseq);
+                        }
+
+                        //loop through the rest of the words
+                        while (str.hasMoreTokens())
+                        {
+                            //append the word to the sequence
+                            tempseq.append(str.nextToken());
+                        }
+                    }
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            System.err.println("Exception parsing MSFFile " + e);
+            e.printStackTrace();
+        }
+
+        this.noSeqs = headers.size();
+
+        //Add sequences to the hash
+        for (i = 0; i < headers.size(); i++)
+        {
+            if (seqhash.get(headers.elementAt(i)) != null)
+            {
+                String head = headers.elementAt(i).toString();
+                String seq = seqhash.get(head).toString();
+
+                if (maxLength < head.length())
+                {
+                    maxLength = head.length();
+                }
+
+                // Replace ~ with a sensible gap character
+                seq = seq.replace('~', '-');
+                if (!isValidProteinSequence(seq))
+                {
+                    throw new IOException(AppletFormatAdapter.
+                                          INVALID_CHARACTERS
+                                          + " : " + head
+                                          + " : " + invalidCharacter);
+                }
+
+
+                Sequence newSeq = parseId(head);
+
+                newSeq.setSequence(seq);
+
+                seqs.addElement(newSeq);
+            }
+            else
+            {
+                System.err.println("MSFFile Parser: Can't find sequence for " +
+                    headers.elementAt(i));
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seq DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int checkSum(String seq)
+    {
+        int check = 0;
+        String sequence = seq.toUpperCase();
+
+        for (int i = 0; i < sequence.length(); i++)
+        {
+            try
+            {
+
+                    int value = sequence.charAt(i);
+                    if (value!=-1)
+                    {
+                        check += (i % 57 +1) * value;
+                    }
+            }
+            catch (Exception e)
+            {
+                System.err.println("Exception during MSF Checksum calculation");
+                e.printStackTrace();
+            }
+        }
+
+        return check % 10000;
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param is_NA DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String print(SequenceI[] seqs)
+    {
+
+      boolean is_NA = jalview.util.Comparison.isNucleotide(seqs);
+
+      SequenceI [] s = new SequenceI[seqs.length];
+
+        StringBuffer out = new StringBuffer("!!" + (is_NA ? "NA" : "AA") +
+                "_MULTIPLE_ALIGNMENT 1.0\n\n"); // TODO: JBPNote : Jalview doesn't remember NA or AA yet.
+
+        int max = 0;
+        int maxid = 0;
+        int i = 0;
+
+        while ((i < seqs.length) && (seqs[i] != null))
+        {
+          // Replace all internal gaps with . and external spaces with ~
+          s[i] =new Sequence(seqs[i].getName(),seqs[i].getSequence().replace('-', '.'));
+
+          StringBuffer sb = new StringBuffer(s[i].getSequence());
+          for (int ii = 0; ii < sb.length(); ii++)
+          {
+            if (sb.charAt(ii) == '.')
+            {
+              sb.setCharAt(ii, '~');
+            }
+            else
+              break;
+          }
+
+          for (int ii = sb.length() - 1; ii > 0; ii--)
+          {
+            if (sb.charAt(ii) == '.')
+            {
+              sb.setCharAt(ii,'~');
+            }
+            else
+              break;
+          }
+
+            s[i].setSequence(sb.toString());
+
+            if (s[i].getSequence().length() > max)
+            {
+                max = s[i].getSequence().length();
+            }
+
+            i++;
+        }
+
+        Format maxLenpad = new Format("%" + (new String("" + max)).length() +
+                "d");
+        Format maxChkpad = new Format("%" + (new String("1" + max)).length() +
+                "d");
+        i = 0;
+
+        int bigChecksum = 0;
+        int [] checksums = new int[s.length];
+        while ( i < s.length )
+        {
+          checksums[i] = checkSum(s[i].getSequence());
+          bigChecksum += checksums[i];
+          i++;
+        }
+
+        long maxNB = 0;
+        out.append("   MSF: " + s[0].getSequence().length() + "   Type: " +
+            (is_NA ? "N" : "P") + "    Check:  " + (bigChecksum%10000) + "   ..\n\n\n");
+
+        String[] nameBlock = new String[s.length];
+        String[] idBlock = new String[s.length];
+
+        i=0;
+        while ((i < s.length) && (s[i] != null))
+        {
+
+            nameBlock[i] = new String("  Name: " + printId(s[i])+" ");
+
+            idBlock[i] = new String("Len: " +
+                    maxLenpad.form(s[i].getSequence().length()) + "  Check: " +
+                    maxChkpad.form(checksums[i]) + "  Weight: 1.00\n");
+
+            if (s[i].getName().length() > maxid)
+            {
+                maxid = s[i].getName().length();
+            }
+
+            if (nameBlock[i].length() > maxNB)
+            {
+                maxNB = nameBlock[i].length();
+            }
+
+            i++;
+        }
+
+        if (maxid < 10)
+        {
+            maxid = 10;
+        }
+
+        if (maxNB < 15)
+        {
+            maxNB = 15;
+        }
+
+        Format nbFormat = new Format("%-" + maxNB + "s");
+
+        for (i = 0; (i < s.length) && (s[i] != null); i++)
+        {
+            out.append(nbFormat.form(nameBlock[i]) + idBlock[i]);
+        }
+
+        maxid++;
+        out.append("\n\n//\n\n");
+
+        int len = 50;
+
+        int nochunks = (max / len) + 1;
+
+        if ((max % len) == 0)
+        {
+            nochunks--;
+        }
+
+        for (i = 0; i < nochunks; i++)
+        {
+            int j = 0;
+
+            while ((j < s.length) && (s[j] != null))
+            {
+                String name = printId( s[j] );
+
+                out.append(new Format("%-" + maxid + "s").form(name+" "));
+
+
+                for (int k = 0; k < 5; k++)
+                {
+                    int start = (i * 50) + (k * 10);
+                    int end = start + 10;
+
+                    if ((end < s[j].getSequence().length()) &&
+                            (start < s[j].getSequence().length()))
+                    {
+                        out.append(s[j].getSequence().substring(start, end));
+
+                        if (k < 4)
+                        {
+                             out.append(" ");
+                        }
+                        else
+                        {
+                            out.append("\n");
+                        }
+                    }
+                    else
+                    {
+                        if (start < s[j].getSequence().length())
+                        {
+                            out.append(s[j].getSequence().substring(start));
+                            out.append("\n");
+                        }
+                        else
+                        {
+                            if (k == 0)
+                            {
+                                out.append("\n");
+                            }
+                        }
+                    }
+                }
+
+                j++;
+            }
+
+            out.append("\n");
+        }
+
+        return out.toString();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String print()
+    {
+        return print(getSeqsAsArray());
+    }
+}
index 13e48b4..bd0a900 100755 (executable)
-package jalview.io;\r
-\r
-import jalview.datamodel.SequenceI;\r
-import java.util.Vector;\r
-import com.stevesoft.pat.Regex;\r
-public class ModellerDescription\r
-{\r
-    /**\r
-     * Translates between a String containing a set of colon-separated values\r
-     * on a single line, and sequence start/end and other properties.\r
-     * See PIRFile IO for its use.\r
-     */\r
-    final String[] seqTypes =\r
-      {\r
-      "sequence", "structure", "structureX", "structureN"};\r
-  final String[] Fields =\r
-      {\r
-      "objectType", "objectId",\r
-      "startField", "startCode",\r
-      "endField", "endCode",\r
-      "description1", "description2",\r
-      "resolutionField", "tailField"};\r
-  final int TYPE = 0;\r
-  final int LOCALID = 1;\r
-  final int START = 2;\r
-  final int START_CHAIN = 3;\r
-  final int END = 4;\r
-  final int END_CHAIN = 5;\r
-  final int DESCRIPTION1 = 6;\r
-  final int DESCRIPTION2 = 7;\r
-  final int RESOLUTION = 8;\r
-  final int TAIL = 9;\r
-\r
-  /**\r
-   * 0 is free text or empty\r
-   * 1 is something that parses to an integer, or \@\r
-   */\r
-  final int Types[] =\r
-      {\r
-      0, 0, 1, 0, 1, 0, 0, 0, 0, 0\r
-  };\r
-  final char Padding[] =\r
-      {\r
-      ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'\r
-  };\r
-\r
-  java.util.Hashtable fields = new java.util.Hashtable();\r
-  ModellerDescription()\r
-  {\r
-    fields.put(Fields[TAIL], "");\r
-  }\r
-\r
-  class resCode\r
-  {\r
-    Integer val;\r
-    String field;\r
-    resCode(String f, Integer v)\r
-    {\r
-      val = v;\r
-      field = f;\r
-    }\r
-\r
-    resCode(int v)\r
-    {\r
-      val = new Integer(v);\r
-      field = val.toString();\r
-    }\r
-  };\r
-\r
-  private resCode validResidueCode(String field)\r
-  {\r
-    Integer val = null;\r
-    com.stevesoft.pat.Regex r = new Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");\r
-\r
-    if (!r.search(field))\r
-    {\r
-      return null; // invalid\r
-    }\r
-    String value = r.stringMatched(3);\r
-    if (value == null)\r
-    {\r
-      value = r.stringMatched(1);\r
-    }\r
-   // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +\r
-   //                             "'");\r
-    try\r
-    {\r
-      val = Integer.valueOf(value);\r
-      return new resCode(field, val); // successful numeric extraction\r
-    }\r
-    catch (Exception e)\r
-    {\r
-    }\r
-    return new resCode(field, null);\r
-  }\r
-\r
-  private java.util.Hashtable parseDescription(String desc)\r
-  {\r
-    java.util.Hashtable fields = new java.util.Hashtable();\r
-    java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");\r
-    String field;\r
-    int type = -1;\r
-    if (st.countTokens() > 0)\r
-    {\r
-      // parse colon-fields\r
-      int i = 0;\r
-      field = st.nextToken(":");\r
-      do\r
-      {\r
-        if (seqTypes[i].equalsIgnoreCase(field) )\r
-        {\r
-          break;\r
-        }\r
-      }\r
-      while (++i < seqTypes.length);\r
-\r
-      if (i < seqTypes.length)\r
-      {\r
-        // valid seqType for modeller\r
-        type = i;\r
-        i = 1; // continue parsing fields\r
-        while (i < TAIL && st.hasMoreTokens())\r
-        {\r
-          if ( (field = st.nextToken(":")) != null)\r
-          {\r
-            // validate residue field value\r
-            if (Types[i] == 1)\r
-            {\r
-              resCode val = validResidueCode(field);\r
-              if (val != null)\r
-              {\r
-                fields.put(new String(Fields[i] + "num"), val);\r
-              }\r
-              else\r
-              {\r
-          //      jalview.bin.Cache.log.debug(\r
-         //           "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");\r
-                type = -1; /* invalid field! - throw the FieldSet away */\r
-              }\r
-              ;\r
-            }\r
-            fields.put(Fields[i++], field);\r
-          }\r
-        }\r
-        if (i == TAIL)\r
-        {\r
-          // slurp remaining fields\r
-          while (st.hasMoreTokens())\r
-          {\r
-            field += ":" + st.nextToken(":");\r
-          }\r
-          fields.put(Fields[TAIL], field);\r
-        }\r
-      }\r
-    }\r
-    if (type == -1)\r
-    {\r
-      // object is not a proper ModellerPIR object\r
-      fields = new java.util.Hashtable();\r
-      fields.put(Fields[TAIL], new String(desc));\r
-    }\r
-    else\r
-    {\r
-      fields.put(Fields[TYPE], seqTypes[type]);\r
-    }\r
-    return fields;\r
-  }\r
-\r
-  ModellerDescription(String desc)\r
-  {\r
-    if (desc == null)\r
-    {\r
-      desc = "";\r
-    }\r
-    fields = parseDescription(desc);\r
-  }\r
-\r
-  void setStartCode(int v)\r
-  {\r
-    resCode r;\r
-    fields.put(Fields[START] + "num", r = new resCode(v));\r
-    fields.put(Fields[START], r.field);\r
-  }\r
-\r
-  void setEndCode(int v)\r
-  {\r
-    resCode r;\r
-    fields.put(Fields[END] + "num", r = new resCode(v));\r
-    fields.put(Fields[END], r.field);\r
-  }\r
-\r
-  /**\r
-   * make a possibly updated modeller field line for the sequence object\r
-   * @param seq SequenceI\r
-   */\r
-  ModellerDescription(SequenceI seq)\r
-  {\r
-\r
-    if (seq.getDescription() != null)\r
-    {\r
-      fields = parseDescription(seq.getDescription());\r
-    }\r
-\r
-    if (isModellerFieldset())\r
-    {\r
-      // Set start and end before we update the type (in the case of a synthesized field set)\r
-      if (getStartNum() != seq.getStart() && getStartCode().val != null)\r
-      {\r
-        setStartCode(seq.getStart());\r
-      }\r
-\r
-      if (getEndNum() != seq.getEnd() && getStartCode().val != null)\r
-      {\r
-        setEndCode(seq.getEnd());\r
-      }\r
-    }\r
-    else\r
-    {\r
-      // synthesize fields\r
-      setStartCode(seq.getStart());\r
-      setEndCode(seq.getEnd());\r
-      fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...\r
-      // type - decide based on evidence of PDB database references - this also sets the local reference field\r
-      int t = 0; // sequence\r
-      if (seq.getDatasetSequence() != null &&\r
-          seq.getDatasetSequence().getDBRef() != null)\r
-      {\r
-        Vector dbr = seq.getDatasetSequence().getDBRef();\r
-        int i, j;\r
-        for (i = 0, j = dbr.size(); i < j; i++)\r
-        {\r
-          jalview.datamodel.DBRefEntry dref = (jalview.datamodel.DBRefEntry)\r
-              dbr.elementAt(i);\r
-          if (dref != null)\r
-          {\r
-            // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField\r
-            // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.\r
-            if (dref.getSource().equals("PDB"))\r
-            {\r
-              fields.put(Fields[LOCALID], dref.getAccessionId());\r
-              t = 2;\r
-              break;\r
-            }\r
-          }\r
-        }\r
-      }\r
-      fields.put(Fields[TYPE], seqTypes[t]);\r
-    }\r
-\r
-  }\r
-\r
-  /**\r
-   * Indicate if fields parsed to a modeller-like colon-separated value line\r
-   * @return boolean\r
-   */\r
-  boolean isModellerFieldset()\r
-  {\r
-    return (fields.containsKey(Fields[TYPE]));\r
-  }\r
-\r
-  String getDescriptionLine()\r
-  {\r
-    String desc = "";\r
-    int lastfield = Fields.length - 1;\r
-\r
-    if (isModellerFieldset())\r
-    {\r
-      String value;\r
-      // try to write a minimal modeller field set, so..\r
-\r
-      // find the last valid field in the entry\r
-\r
-      for (; lastfield > 6; lastfield--)\r
-      {\r
-        if (fields.containsKey(Fields[lastfield]))\r
-        {\r
-          break;\r
-        }\r
-      }\r
-\r
-      for (int i = 0; i < lastfield; i++)\r
-      {\r
-        value = (String) fields.get(Fields[i]);\r
-        if (value != null && value.length() > 0)\r
-        {\r
-          desc += ( (String) fields.get(Fields[i])) + ":";\r
-        }\r
-        else\r
-        {\r
-          desc += Padding[i] + ":";\r
-        }\r
-      }\r
-    }\r
-    // just return the last field if no others were defined.\r
-    if (fields.containsKey(Fields[lastfield]))\r
-    {\r
-      desc += (String) fields.get(Fields[lastfield]);\r
-    }\r
-    else\r
-    {\r
-      desc += ".";\r
-    }\r
-    return desc;\r
-  }\r
-\r
-  int getStartNum()\r
-  {\r
-    int start = 0;\r
-    resCode val = getStartCode();\r
-    if (val.val != null)\r
-    {\r
-      return val.val.intValue();\r
-    }\r
-    return start;\r
-  }\r
-\r
-  resCode getStartCode()\r
-  {\r
-    if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))\r
-    {\r
-      return (resCode) fields.get(Fields[START] + "num");\r
-    }\r
-    return null;\r
-  }\r
-\r
-  resCode getEndCode()\r
-  {\r
-    if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))\r
-    {\r
-      return (resCode) fields.get(Fields[END] + "num");\r
-    }\r
-    return null;\r
-  }\r
-\r
-  int getEndNum()\r
-  {\r
-    int end = 0;\r
-    resCode val = getEndCode();\r
-    if (val.val != null)\r
-    {\r
-      return val.val.intValue();\r
-    }\r
-    return end;\r
-  }\r
-\r
-  /**\r
-   * returns true if sequence object was modifed with a valid modellerField set\r
-   * @param newSeq SequenceI\r
-   * @return boolean\r
-   */\r
-  boolean updateSequenceI(SequenceI newSeq)\r
-  {\r
-    if (isModellerFieldset())\r
-    {\r
-      if (getStartCode().val != null)\r
-      {\r
-        newSeq.setStart(getStartNum());\r
-      }\r
-      else\r
-      {\r
-        newSeq.setStart(1);\r
-      }\r
-      if (getEndCode().val != null)\r
-      {\r
-        newSeq.setEnd(getEndNum());\r
-      }\r
-      else\r
-      {\r
-        newSeq.setEnd(newSeq.getStart() + newSeq.getLength());\r
-      }\r
-      return true;\r
-    }\r
-    return false;\r
-  }\r
-}\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import jalview.datamodel.SequenceI;
+import java.util.Vector;
+public class ModellerDescription
+{
+    /**
+     * Translates between a String containing a set of colon-separated values
+     * on a single line, and sequence start/end and other properties.
+     * See PIRFile IO for its use.
+     */
+    final String[] seqTypes =
+      {
+      "sequence", "structure", "structureX", "structureN"};
+  final String[] Fields =
+      {
+      "objectType", "objectId",
+      "startField", "startCode",
+      "endField", "endCode",
+      "description1", "description2",
+      "resolutionField", "tailField"};
+  final int TYPE = 0;
+  final int LOCALID = 1;
+  final int START = 2;
+  final int START_CHAIN = 3;
+  final int END = 4;
+  final int END_CHAIN = 5;
+  final int DESCRIPTION1 = 6;
+  final int DESCRIPTION2 = 7;
+  final int RESOLUTION = 8;
+  final int TAIL = 9;
+
+  /**
+   * 0 is free text or empty
+   * 1 is something that parses to an integer, or \@
+   */
+  final int Types[] =
+      {
+      0, 0, 1, 0, 1, 0, 0, 0, 0, 0
+  };
+  final char Padding[] =
+      {
+      ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'
+  };
+
+  java.util.Hashtable fields = new java.util.Hashtable();
+  ModellerDescription()
+  {
+    fields.put(Fields[TAIL], "");
+  }
+
+  class resCode
+  {
+    Integer val;
+    String field;
+    resCode(String f, Integer v)
+    {
+      val = v;
+      field = f;
+    }
+
+    resCode(int v)
+    {
+      val = new Integer(v);
+      field = val.toString();
+    }
+  };
+
+  private resCode validResidueCode(String field)
+  {
+    Integer val = null;
+    com.stevesoft.pat.Regex r = new com.stevesoft.pat.Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
+
+    if (!r.search(field))
+    {
+      return null; // invalid
+    }
+    String value = r.stringMatched(3);
+    if (value == null)
+    {
+      value = r.stringMatched(1);
+    }
+   // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
+   //                             "'");
+    try
+    {
+      val = Integer.valueOf(value);
+      return new resCode(field, val); // successful numeric extraction
+    }
+    catch (Exception e)
+    {
+    }
+    return new resCode(field, null);
+  }
+
+  private java.util.Hashtable parseDescription(String desc)
+  {
+    java.util.Hashtable fields = new java.util.Hashtable();
+    java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
+    String field;
+    int type = -1;
+    if (st.countTokens() > 0)
+    {
+      // parse colon-fields
+      int i = 0;
+      field = st.nextToken(":");
+      do
+      {
+        if (seqTypes[i].equalsIgnoreCase(field) )
+        {
+          break;
+        }
+      }
+      while (++i < seqTypes.length);
+
+      if (i < seqTypes.length)
+      {
+        // valid seqType for modeller
+        type = i;
+        i = 1; // continue parsing fields
+        while (i < TAIL && st.hasMoreTokens())
+        {
+          if ( (field = st.nextToken(":")) != null)
+          {
+            // validate residue field value
+            if (Types[i] == 1)
+            {
+              resCode val = validResidueCode(field);
+              if (val != null)
+              {
+                fields.put(new String(Fields[i] + "num"), val);
+              }
+              else
+              {
+          //      jalview.bin.Cache.log.debug(
+         //           "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");
+                type = -1; /* invalid field! - throw the FieldSet away */
+              }
+              ;
+            }
+            fields.put(Fields[i++], field);
+          }
+        }
+        if (i == TAIL)
+        {
+          // slurp remaining fields
+          while (st.hasMoreTokens())
+          {
+            field += ":" + st.nextToken(":");
+          }
+          fields.put(Fields[TAIL], field);
+        }
+      }
+    }
+    if (type == -1)
+    {
+      // object is not a proper ModellerPIR object
+      fields = new java.util.Hashtable();
+      fields.put(Fields[TAIL], new String(desc));
+    }
+    else
+    {
+      fields.put(Fields[TYPE], seqTypes[type]);
+    }
+    return fields;
+  }
+
+  ModellerDescription(String desc)
+  {
+    if (desc == null)
+    {
+      desc = "";
+    }
+    fields = parseDescription(desc);
+  }
+
+  void setStartCode(int v)
+  {
+    resCode r;
+    fields.put(Fields[START] + "num", r = new resCode(v));
+    fields.put(Fields[START], r.field);
+  }
+
+  void setEndCode(int v)
+  {
+    resCode r;
+    fields.put(Fields[END] + "num", r = new resCode(v));
+    fields.put(Fields[END], r.field);
+  }
+
+  /**
+   * make a possibly updated modeller field line for the sequence object
+   * @param seq SequenceI
+   */
+  ModellerDescription(SequenceI seq)
+  {
+
+    if (seq.getDescription() != null)
+    {
+      fields = parseDescription(seq.getDescription());
+    }
+
+    if (isModellerFieldset())
+    {
+      // Set start and end before we update the type (in the case of a synthesized field set)
+      if (getStartNum() != seq.getStart() && getStartCode().val != null)
+      {
+        setStartCode(seq.getStart());
+      }
+
+      if (getEndNum() != seq.getEnd() && getStartCode().val != null)
+      {
+        setEndCode(seq.getEnd());
+      }
+    }
+    else
+    {
+      // synthesize fields
+      setStartCode(seq.getStart());
+      setEndCode(seq.getEnd());
+      fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...
+      // type - decide based on evidence of PDB database references - this also sets the local reference field
+      int t = 0; // sequence
+      if (seq.getDatasetSequence() != null &&
+          seq.getDatasetSequence().getDBRef() != null)
+      {
+        jalview.datamodel.DBRefEntry [] dbr = seq.getDatasetSequence().getDBRef();
+        int i, j;
+        for (i = 0, j = dbr.length; i < j; i++)
+        {
+          if (dbr[i] != null)
+          {
+            // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField
+            // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.
+            if (dbr[i].getSource().equals(jalview.datamodel.DBRefSource.PDB))
+            {
+              fields.put(Fields[LOCALID], dbr[i].getAccessionId());
+              t = 2;
+              break;
+            }
+          }
+        }
+      }
+      fields.put(Fields[TYPE], seqTypes[t]);
+    }
+
+  }
+
+  /**
+   * Indicate if fields parsed to a modeller-like colon-separated value line
+   * @return boolean
+   */
+  boolean isModellerFieldset()
+  {
+    return (fields.containsKey(Fields[TYPE]));
+  }
+
+  String getDescriptionLine()
+  {
+    String desc = "";
+    int lastfield = Fields.length - 1;
+
+    if (isModellerFieldset())
+    {
+      String value;
+      // try to write a minimal modeller field set, so..
+
+      // find the last valid field in the entry
+
+      for (; lastfield > 6; lastfield--)
+      {
+        if (fields.containsKey(Fields[lastfield]))
+        {
+          break;
+        }
+      }
+
+      for (int i = 0; i < lastfield; i++)
+      {
+        value = (String) fields.get(Fields[i]);
+        if (value != null && value.length() > 0)
+        {
+          desc += ( (String) fields.get(Fields[i])) + ":";
+        }
+        else
+        {
+          desc += Padding[i] + ":";
+        }
+      }
+    }
+    // just return the last field if no others were defined.
+    if (fields.containsKey(Fields[lastfield]))
+    {
+      desc += (String) fields.get(Fields[lastfield]);
+    }
+    else
+    {
+      desc += ".";
+    }
+    return desc;
+  }
+
+  int getStartNum()
+  {
+    int start = 0;
+    resCode val = getStartCode();
+    if (val.val != null)
+    {
+      return val.val.intValue();
+    }
+    return start;
+  }
+
+  resCode getStartCode()
+  {
+    if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
+    {
+      return (resCode) fields.get(Fields[START] + "num");
+    }
+    return null;
+  }
+
+  resCode getEndCode()
+  {
+    if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
+    {
+      return (resCode) fields.get(Fields[END] + "num");
+    }
+    return null;
+  }
+
+  int getEndNum()
+  {
+    int end = 0;
+    resCode val = getEndCode();
+    if (val.val != null)
+    {
+      return val.val.intValue();
+    }
+    return end;
+  }
+
+  /**
+   * returns true if sequence object was modifed with a valid modellerField set
+   * @param newSeq SequenceI
+   * @return boolean
+   */
+  boolean updateSequenceI(SequenceI newSeq)
+  {
+    if (isModellerFieldset())
+    {
+      if (getStartCode().val != null)
+      {
+        newSeq.setStart(getStartNum());
+      }
+      else
+      {
+        newSeq.setStart(1);
+      }
+      if (getEndCode().val != null)
+      {
+        newSeq.setEnd(getEndNum());
+      }
+      else
+      {
+        newSeq.setEnd(newSeq.getStart() + newSeq.getLength());
+      }
+      return true;
+    }
+    return false;
+  }
+}
+
index de33266..16ac2c7 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-\r
-// NewickFile.java\r
-// Tree I/O\r
-// http://evolution.genetics.washington.edu/phylip/newick_doc.html\r
-// TODO: Implement Basic NHX tag parsing and preservation\r
-// TODO: http://evolution.genetics.wustl.edu/eddy/forester/NHX.html\r
-// TODO: Extended SequenceNodeI to hold parsed NHX strings\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import java.io.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class NewickFile extends FileParse\r
-{\r
-    SequenceNode root;\r
-    private boolean HasBootstrap = false;\r
-    private boolean HasDistances = false;\r
-    private boolean RootHasDistance = false;\r
-\r
-    // File IO Flags\r
-    boolean ReplaceUnderscores = false;\r
-    boolean printRootInfo = false;\r
-    private com.stevesoft.pat.Regex[] NodeSafeName = new com.stevesoft.pat.Regex[]\r
-        {\r
-            new com.stevesoft.pat.Regex().perlCode("m/[\\[,:'()]/"), // test for requiring quotes\r
-            new com.stevesoft.pat.Regex().perlCode("s/'/''/"), // escaping quote characters\r
-            new com.stevesoft.pat.Regex().perlCode("s/\\/w/_/") // unqoted whitespace transformation\r
-        };\r
-    char QuoteChar = '\'';\r
-\r
-    /**\r
-     * Creates a new NewickFile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public NewickFile(String inStr) throws IOException\r
-    {\r
-        super(inStr, "Paste");\r
-    }\r
-\r
-    /**\r
-     * Creates a new NewickFile object.\r
-     *\r
-     * @param inFile DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public NewickFile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-    }\r
-\r
-    /**\r
-     * Creates a new NewickFile object.\r
-     *\r
-     * @param newtree DOCUMENT ME!\r
-     */\r
-    public NewickFile(SequenceNode newtree)\r
-    {\r
-        root = newtree;\r
-    }\r
-\r
-    /**\r
-     * Creates a new NewickFile object.\r
-     *\r
-     * @param newtree DOCUMENT ME!\r
-     * @param bootstrap DOCUMENT ME!\r
-     */\r
-    public NewickFile(SequenceNode newtree, boolean bootstrap)\r
-    {\r
-        HasBootstrap = bootstrap;\r
-        root = newtree;\r
-    }\r
-\r
-    /**\r
-     * Creates a new NewickFile object.\r
-     *\r
-     * @param newtree DOCUMENT ME!\r
-     * @param bootstrap DOCUMENT ME!\r
-     * @param distances DOCUMENT ME!\r
-     */\r
-    public NewickFile(SequenceNode newtree, boolean bootstrap, boolean distances)\r
-    {\r
-        root = newtree;\r
-        HasBootstrap = bootstrap;\r
-        HasDistances = distances;\r
-    }\r
-\r
-    /**\r
-     * Creates a new NewickFile object.\r
-     *\r
-     * @param newtree DOCUMENT ME!\r
-     * @param bootstrap DOCUMENT ME!\r
-     * @param distances DOCUMENT ME!\r
-     * @param rootdistance DOCUMENT ME!\r
-     */\r
-    public NewickFile(SequenceNode newtree, boolean bootstrap,\r
-        boolean distances, boolean rootdistance)\r
-    {\r
-        root = newtree;\r
-        HasBootstrap = bootstrap;\r
-        HasDistances = distances;\r
-        RootHasDistance = rootdistance;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param Error DOCUMENT ME!\r
-     * @param Er DOCUMENT ME!\r
-     * @param r DOCUMENT ME!\r
-     * @param p DOCUMENT ME!\r
-     * @param s DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private String ErrorStringrange(String Error, String Er, int r, int p,\r
-        String s)\r
-    {\r
-        return ((Error == null) ? "" : Error) + Er + " at position " + p +\r
-        " ( " +\r
-        s.substring(((p - r) < 0) ? 0 : (p - r),\r
-            ((p + r) > s.length()) ? s.length() : (p + r)) + " )\n";\r
-    }\r
-\r
-    // @tree annotations\r
-    // These are set automatically by the reader\r
-    public boolean HasBootstrap()\r
-    {\r
-        return HasBootstrap;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean HasDistances()\r
-    {\r
-        return HasDistances;\r
-    }\r
-\r
-    public boolean HasRootDistance()\r
-    {\r
-        return RootHasDistance;\r
-    }\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public void parse() throws IOException\r
-    {\r
-        String nf;\r
-\r
-        { // fill nf with complete tree file\r
-\r
-            StringBuffer file = new StringBuffer();\r
-\r
-            while ((nf = nextLine()) != null)\r
-            {\r
-                file.append(nf);\r
-            }\r
-\r
-            nf = file.toString();\r
-        }\r
-\r
-        root = new SequenceNode();\r
-\r
-        SequenceNode realroot = null;\r
-        SequenceNode c = root;\r
-\r
-        int d = -1;\r
-        int cp = 0;\r
-        //int flen = nf.length();\r
-\r
-        String Error = null;\r
-        String nodename = null;\r
-\r
-        float DefDistance = (float) 0.001; // @param Default distance for a node - very very small\r
-        int DefBootstrap = 0; // @param Default bootstrap for a node\r
-\r
-        float distance = DefDistance;\r
-        int bootstrap = DefBootstrap;\r
-\r
-        boolean ascending = false; // flag indicating that we are leaving the current node\r
-\r
-        com.stevesoft.pat.Regex majorsyms = new com.stevesoft.pat.Regex(\r
-                "[(\\['),;]");\r
-\r
-        while (majorsyms.searchFrom(nf, cp) && (Error == null))\r
-        {\r
-            int fcp = majorsyms.matchedFrom();\r
-\r
-            switch (nf.charAt(fcp))\r
-            {\r
-            case '[': // Comment or structured/extended NH format info\r
-\r
-                com.stevesoft.pat.Regex comment = new com.stevesoft.pat.Regex(\r
-                        "]");\r
-\r
-                if (comment.searchFrom(nf, fcp))\r
-                {\r
-                    // Skip the comment field\r
-                    cp = 1 + comment.matchedFrom();\r
-                }\r
-                else\r
-                {\r
-                    Error = ErrorStringrange(Error, "Unterminated comment", 3,\r
-                            fcp, nf);\r
-                }\r
-\r
-                ;\r
-\r
-                break;\r
-\r
-            case '(':\r
-\r
-                // ascending should not be set\r
-                // New Internal node\r
-                if (ascending)\r
-                {\r
-                    Error = ErrorStringrange(Error, "Unexpected '('", 7, fcp, nf);\r
-\r
-                    continue;\r
-                }\r
-\r
-                ;\r
-                d++;\r
-\r
-                if (c.right() == null)\r
-                {\r
-                    c.setRight(new SequenceNode(null, c, null, DefDistance,\r
-                            DefBootstrap, false));\r
-                    c = (SequenceNode) c.right();\r
-                }\r
-                else\r
-                {\r
-                    if (c.left() != null)\r
-                    {\r
-                        // Dummy node for polytomy - keeps c.left free for new node\r
-                        SequenceNode tmpn = new SequenceNode(null, c, null, 0,\r
-                                0, true);\r
-                        tmpn.SetChildren(c.left(), c.right());\r
-                        c.setRight(tmpn);\r
-                    }\r
-\r
-                    c.setLeft(new SequenceNode(null, c, null, DefDistance,\r
-                            DefBootstrap, false));\r
-                    c = (SequenceNode) c.left();\r
-                }\r
-\r
-                if (realroot == null)\r
-                {\r
-                    realroot = c;\r
-                }\r
-\r
-                nodename = null;\r
-                distance = DefDistance;\r
-                bootstrap = DefBootstrap;\r
-                cp = fcp + 1;\r
-\r
-                break;\r
-\r
-            // Deal with quoted fields\r
-            case '\'':\r
-\r
-                com.stevesoft.pat.Regex qnodename = new com.stevesoft.pat.Regex(\r
-                        "([^']|'')+'");\r
-\r
-                if (qnodename.searchFrom(nf, fcp))\r
-                {\r
-                    int nl = qnodename.stringMatched().length();\r
-                    nodename = new String(qnodename.stringMatched().substring(0,\r
-                                nl - 1));\r
-                    cp = fcp + nl + 1;\r
-                }\r
-                else\r
-                {\r
-                    Error = ErrorStringrange(Error,\r
-                            "Unterminated quotes for nodename", 7, fcp, nf);\r
-                }\r
-\r
-                break;\r
-\r
-            case ';':\r
-\r
-                if (d != -1)\r
-                {\r
-                    Error = ErrorStringrange(Error,\r
-                            "Wayward semicolon (depth=" + d + ")", 7, fcp, nf);\r
-                }\r
-\r
-            // cp advanced at the end of default\r
-            default:\r
-\r
-                // Parse simpler field strings\r
-                String fstring = nf.substring(cp, fcp);\r
-                com.stevesoft.pat.Regex uqnodename = new com.stevesoft.pat.Regex(\r
-                        "\\b([^' :;\\](),]+)");\r
-                com.stevesoft.pat.Regex nbootstrap = new com.stevesoft.pat.Regex(\r
-                        "\\S+([0-9+]+)\\S*:");\r
-                com.stevesoft.pat.Regex ndist = new com.stevesoft.pat.Regex(\r
-                        ":([-0-9Ee.+]+)");\r
-\r
-                if (uqnodename.search(fstring) &&\r
-                        ((uqnodename.matchedFrom(1) == 0) ||\r
-                        (fstring.charAt(uqnodename.matchedFrom(1) - 1) != ':'))) // JBPNote HACK!\r
-                {\r
-                    if (nodename == null)\r
-                    {\r
-                        if (ReplaceUnderscores)\r
-                        {\r
-                            nodename = uqnodename.stringMatched(1).replace('_',\r
-                                    ' ');\r
-                        }\r
-                        else\r
-                        {\r
-                            nodename = uqnodename.stringMatched(1);\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        Error = ErrorStringrange(Error,\r
-                                "File has broken algorithm - overwritten nodename",\r
-                                10, fcp, nf);\r
-                    }\r
-                }\r
-\r
-                if (nbootstrap.search(fstring) &&\r
-                        (nbootstrap.matchedFrom(1) > (uqnodename.matchedFrom(1) +\r
-                        uqnodename.stringMatched().length())))\r
-                {\r
-                    try\r
-                    {\r
-                        bootstrap = (new Integer(nbootstrap.stringMatched(1))).intValue();\r
-                        HasBootstrap = true;\r
-                    }\r
-                    catch (Exception e)\r
-                    {\r
-                        Error = ErrorStringrange(Error,\r
-                                "Can't parse bootstrap value", 4,\r
-                                cp + nbootstrap.matchedFrom(), nf);\r
-                    }\r
-                }\r
-\r
-                boolean nodehasdistance = false;\r
-\r
-                if (ndist.search(fstring))\r
-                {\r
-                    try\r
-                    {\r
-                        distance = (new Float(ndist.stringMatched(1))).floatValue();\r
-                        HasDistances = true;\r
-                        nodehasdistance = true;\r
-                    }\r
-                    catch (Exception e)\r
-                    {\r
-                        Error = ErrorStringrange(Error,\r
-                                "Can't parse node distance value", 7,\r
-                                cp + ndist.matchedFrom(), nf);\r
-                    }\r
-                }\r
-\r
-                if (ascending)\r
-                {\r
-                    // Write node info here\r
-                    c.setName(nodename);\r
-                    // Trees without distances still need a render distance\r
-                    c.dist = (HasDistances) ? distance : DefDistance;\r
-                    // be consistent for internal bootstrap defaults too\r
-                    c.setBootstrap((HasBootstrap) ? bootstrap : DefBootstrap);\r
-                    if (c == realroot)\r
-                    {\r
-                        RootHasDistance = nodehasdistance; // JBPNote This is really UGLY!!! Ensure root node gets its given distance\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    // Find a place to put the leaf\r
-                    SequenceNode newnode = new SequenceNode(null, c, nodename,\r
-                            (HasDistances) ? distance : DefDistance,\r
-                            (HasBootstrap) ? bootstrap : DefBootstrap, false);\r
-\r
-                    if (c.right() == null)\r
-                    {\r
-                        c.setRight(newnode);\r
-                    }\r
-                    else\r
-                    {\r
-                        if (c.left() == null)\r
-                        {\r
-                            c.setLeft(newnode);\r
-                        }\r
-                        else\r
-                        {\r
-                            // Insert a dummy node for polytomy\r
-                            // dummy nodes have distances\r
-                            SequenceNode newdummy = new SequenceNode(null, c,\r
-                                    null, (HasDistances ? 0 : DefDistance), 0, true);\r
-                            newdummy.SetChildren(c.left(), newnode);\r
-                            c.setLeft(newdummy);\r
-                        }\r
-                    }\r
-                }\r
-\r
-                if (ascending)\r
-                {\r
-                    // move back up the tree from preceding closure\r
-                    c = c.AscendTree();\r
-\r
-                    if ((d > -1) && (c == null))\r
-                    {\r
-                        Error = ErrorStringrange(Error,\r
-                                "File broke algorithm: Lost place in tree (is there an extra ')' ?)",\r
-                                7, fcp, nf);\r
-                    }\r
-                }\r
-\r
-                if (nf.charAt(fcp) == ')')\r
-                {\r
-                    d--;\r
-                    ascending = true;\r
-                }\r
-                else\r
-                {\r
-                    if (nf.charAt(fcp) == ',')\r
-                    {\r
-                        if (ascending)\r
-                        {\r
-                            ascending = false;\r
-                        }\r
-                        else\r
-                        {\r
-                            // Just advance focus, if we need to\r
-                            if ((c.left() != null) && (!c.left().isLeaf()))\r
-                            {\r
-                                c = (SequenceNode) c.left();\r
-                            }\r
-                        }\r
-                    }\r
-\r
-                    // else : We do nothing if ';' is encountered.\r
-                }\r
-\r
-                // Reset new node properties to obvious fakes\r
-                nodename = null;\r
-                distance = DefDistance;\r
-                bootstrap = DefBootstrap;\r
-\r
-                cp = fcp + 1;\r
-            }\r
-        }\r
-\r
-        if (Error != null)\r
-        {\r
-            throw (new IOException("NewickFile: " + Error + "\n"));\r
-        }\r
-\r
-        root = (SequenceNode) root.right().detach(); // remove the imaginary root.\r
-\r
-        if (!RootHasDistance)\r
-        {\r
-            root.dist = (HasDistances) ? 0 : DefDistance;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SequenceNode getTree()\r
-    {\r
-        return root;\r
-    }\r
-\r
-    /**\r
-     * Generate a newick format tree according to internal flags\r
-     * for bootstraps, distances and root distances.\r
-     *\r
-     * @return new hampshire tree in a single line\r
-     */\r
-    public String print()\r
-    {\r
-        synchronized (this)\r
-        {\r
-            StringBuffer tf = new StringBuffer();\r
-            print(tf, root);\r
-\r
-            return (tf.append(";").toString());\r
-        }\r
-    }\r
-\r
-    /**\r
-     *\r
-     *\r
-     * Generate a newick format tree according to internal flags\r
-     * for distances and root distances and user specificied writing of\r
-     * bootstraps.\r
-     * @param withbootstraps controls if bootstrap values are explicitly written.\r
-     *\r
-     * @return new hampshire tree in a single line\r
-     */\r
-    public String print(boolean withbootstraps)\r
-    {\r
-        synchronized (this)\r
-        {\r
-            boolean boots = this.HasBootstrap;\r
-            this.HasBootstrap = withbootstraps;\r
-\r
-            String rv = print();\r
-            this.HasBootstrap = boots;\r
-\r
-            return rv;\r
-        }\r
-    }\r
-\r
-    /**\r
-     *\r
-     * Generate newick format tree according to internal flags\r
-     * for writing root node distances.\r
-     *\r
-     * @param withbootstraps explicitly write bootstrap values\r
-     * @param withdists explicitly write distances\r
-     *\r
-     * @return new hampshire tree in a single line\r
-     */\r
-    public String print(boolean withbootstraps, boolean withdists)\r
-    {\r
-        synchronized (this)\r
-        {\r
-            boolean dists = this.HasDistances;\r
-            this.HasDistances = withdists;\r
-\r
-            String rv = print(withbootstraps);\r
-            this.HasDistances = dists;\r
-\r
-            return rv;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Generate newick format tree according to user specified flags\r
-     *\r
-     * @param withbootstraps explicitly write bootstrap values\r
-     * @param withdists explicitly write distances\r
-     * @param printRootInfo explicitly write root distance\r
-     *\r
-     * @return new hampshire tree in a single line\r
-     */\r
-    public String print(boolean withbootstraps, boolean withdists,\r
-        boolean printRootInfo)\r
-    {\r
-        synchronized (this)\r
-        {\r
-            boolean rootinfo = printRootInfo;\r
-            this.printRootInfo = printRootInfo;\r
-\r
-            String rv = print(withbootstraps, withdists);\r
-            this.printRootInfo = rootinfo;\r
-\r
-            return rv;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    char getQuoteChar()\r
-    {\r
-        return QuoteChar;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    char setQuoteChar(char c)\r
-    {\r
-        char old = QuoteChar;\r
-        QuoteChar = c;\r
-\r
-        return old;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private String nodeName(String name)\r
-    {\r
-        if (NodeSafeName[0].search(name))\r
-        {\r
-            return QuoteChar + NodeSafeName[1].replaceAll(name) + QuoteChar;\r
-        }\r
-        else\r
-        {\r
-            return NodeSafeName[2].replaceAll(name);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private String printNodeField(SequenceNode c)\r
-    {\r
-        return ((c.getName() == null) ? "" : nodeName(c.getName())) +\r
-        ((HasBootstrap)\r
-        ? ((c.getBootstrap() > -1) ? (" " + c.getBootstrap()) : "") : "") +\r
-        ((HasDistances) ? (":" + c.dist) : "");\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param root DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    private String printRootField(SequenceNode root)\r
-    {\r
-        return (printRootInfo)\r
-        ? (((root.getName() == null) ? "" : nodeName(root.getName())) +\r
-        ((HasBootstrap)\r
-        ? ((root.getBootstrap() > -1) ? (" " + root.getBootstrap()) : "") : "") +\r
-        ((RootHasDistance) ? (":" + root.dist) : "")) : "";\r
-    }\r
-\r
-    // Non recursive call deals with root node properties\r
-    public void print(StringBuffer tf, SequenceNode root)\r
-    {\r
-        if (root != null)\r
-        {\r
-            if (root.isLeaf() && printRootInfo)\r
-            {\r
-                tf.append(printRootField(root));\r
-            }\r
-            else\r
-            {\r
-                if (root.isDummy())\r
-                {\r
-                    _print(tf, (SequenceNode) root.right());\r
-                    _print(tf, (SequenceNode) root.left());\r
-                }\r
-                else\r
-                {\r
-                    tf.append("(");\r
-                    _print(tf, (SequenceNode) root.right());\r
-\r
-                    if (root.left() != null)\r
-                    {\r
-                        tf.append(",");\r
-                    }\r
-\r
-                    _print(tf, (SequenceNode) root.left());\r
-                    tf.append(")" + printRootField(root));\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    // Recursive call for non-root nodes\r
-    public void _print(StringBuffer tf, SequenceNode c)\r
-    {\r
-        if (c != null)\r
-        {\r
-            if (c.isLeaf())\r
-            {\r
-                tf.append(printNodeField(c));\r
-            }\r
-            else\r
-            {\r
-                if (c.isDummy())\r
-                {\r
-                    _print(tf, (SequenceNode) c.left());\r
-                    if (c.left() != null)\r
-                    {\r
-                      tf.append(",");\r
-                    }\r
-                    _print(tf, (SequenceNode) c.right());\r
-                }\r
-                else\r
-                {\r
-                    tf.append("(");\r
-                    _print(tf, (SequenceNode) c.right());\r
-\r
-                    if (c.left() != null)\r
-                    {\r
-                        tf.append(",");\r
-                    }\r
-\r
-                    _print(tf, (SequenceNode) c.left());\r
-                    tf.append(")" + printNodeField(c));\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    // Test\r
-    public static void main(String[] args)\r
-    {\r
-        try\r
-        {\r
-            if (args==null || args.length!=1) {\r
-              System.err.println("Takes one argument - file name of a newick tree file.");\r
-              System.exit(0);\r
-            }\r
-\r
-            File fn = new File(args[0]);\r
-\r
-            StringBuffer newickfile = new StringBuffer();\r
-            BufferedReader treefile = new BufferedReader(new FileReader(fn));\r
-            String l;\r
-\r
-            while ((l = treefile.readLine()) != null)\r
-            {\r
-                newickfile.append(l);\r
-            }\r
-\r
-            treefile.close();\r
-            System.out.println("Read file :\n");\r
-\r
-            NewickFile trf = new NewickFile(args[0], "File");\r
-            trf.parse();\r
-            System.out.println("Original file :\n");\r
-\r
-            com.stevesoft.pat.Regex nonl = new com.stevesoft.pat.Regex("\n+", "");\r
-            System.out.println(nonl.replaceAll(newickfile.toString()) + "\n");\r
-\r
-            System.out.println("Parsed file.\n");\r
-            System.out.println("Default output type for original input.\n");\r
-            System.out.println(trf.print());\r
-            System.out.println("Without bootstraps.\n");\r
-            System.out.println(trf.print(false));\r
-            System.out.println("Without distances.\n");\r
-            System.out.println(trf.print(true, false));\r
-            System.out.println("Without bootstraps but with distanecs.\n");\r
-            System.out.println(trf.print(false, true));\r
-            System.out.println("Without bootstraps or distanecs.\n");\r
-            System.out.println(trf.print(false, false));\r
-            System.out.println("With bootstraps and with distances.\n");\r
-            System.out.println(trf.print(true, true));\r
-        }\r
-        catch (java.io.IOException e)\r
-        {\r
-            System.err.println("Exception\n" + e);\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+
+// NewickFile.java
+// Tree I/O
+// http://evolution.genetics.washington.edu/phylip/newick_doc.html
+// TODO: Implement Basic NHX tag parsing and preservation
+// TODO: http://evolution.genetics.wustl.edu/eddy/forester/NHX.html
+// TODO: Extended SequenceNodeI to hold parsed NHX strings
+package jalview.io;
+
+import jalview.datamodel.*;
+
+import java.io.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class NewickFile extends FileParse
+{
+    SequenceNode root;
+    private boolean HasBootstrap = false;
+    private boolean HasDistances = false;
+    private boolean RootHasDistance = false;
+
+    // File IO Flags
+    boolean ReplaceUnderscores = false;
+    boolean printRootInfo = false;
+    private com.stevesoft.pat.Regex[] NodeSafeName = new com.stevesoft.pat.Regex[]
+        {
+            new com.stevesoft.pat.Regex().perlCode("m/[\\[,:'()]/"), // test for requiring quotes
+            new com.stevesoft.pat.Regex().perlCode("s/'/''/"), // escaping quote characters
+            new com.stevesoft.pat.Regex().perlCode("s/\\/w/_/") // unqoted whitespace transformation
+        };
+    char QuoteChar = '\'';
+
+    /**
+     * Creates a new NewickFile object.
+     *
+     * @param inStr DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public NewickFile(String inStr) throws IOException
+    {
+        super(inStr, "Paste");
+    }
+
+    /**
+     * Creates a new NewickFile object.
+     *
+     * @param inFile DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public NewickFile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+    }
+
+    /**
+     * Creates a new NewickFile object.
+     *
+     * @param newtree DOCUMENT ME!
+     */
+    public NewickFile(SequenceNode newtree)
+    {
+        root = newtree;
+    }
+
+    /**
+     * Creates a new NewickFile object.
+     *
+     * @param newtree DOCUMENT ME!
+     * @param bootstrap DOCUMENT ME!
+     */
+    public NewickFile(SequenceNode newtree, boolean bootstrap)
+    {
+        HasBootstrap = bootstrap;
+        root = newtree;
+    }
+
+    /**
+     * Creates a new NewickFile object.
+     *
+     * @param newtree DOCUMENT ME!
+     * @param bootstrap DOCUMENT ME!
+     * @param distances DOCUMENT ME!
+     */
+    public NewickFile(SequenceNode newtree, boolean bootstrap, boolean distances)
+    {
+        root = newtree;
+        HasBootstrap = bootstrap;
+        HasDistances = distances;
+    }
+
+    /**
+     * Creates a new NewickFile object.
+     *
+     * @param newtree DOCUMENT ME!
+     * @param bootstrap DOCUMENT ME!
+     * @param distances DOCUMENT ME!
+     * @param rootdistance DOCUMENT ME!
+     */
+    public NewickFile(SequenceNode newtree, boolean bootstrap,
+        boolean distances, boolean rootdistance)
+    {
+        root = newtree;
+        HasBootstrap = bootstrap;
+        HasDistances = distances;
+        RootHasDistance = rootdistance;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param Error DOCUMENT ME!
+     * @param Er DOCUMENT ME!
+     * @param r DOCUMENT ME!
+     * @param p DOCUMENT ME!
+     * @param s DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private String ErrorStringrange(String Error, String Er, int r, int p,
+        String s)
+    {
+        return ((Error == null) ? "" : Error) + Er + " at position " + p +
+        " ( " +
+        s.substring(((p - r) < 0) ? 0 : (p - r),
+            ((p + r) > s.length()) ? s.length() : (p + r)) + " )\n";
+    }
+
+    // @tree annotations
+    // These are set automatically by the reader
+    public boolean HasBootstrap()
+    {
+        return HasBootstrap;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean HasDistances()
+    {
+        return HasDistances;
+    }
+
+    public boolean HasRootDistance()
+    {
+        return RootHasDistance;
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public void parse() throws IOException
+    {
+        String nf;
+
+        { // fill nf with complete tree file
+
+            StringBuffer file = new StringBuffer();
+
+            while ((nf = nextLine()) != null)
+            {
+                file.append(nf);
+            }
+
+            nf = file.toString();
+        }
+
+        root = new SequenceNode();
+
+        SequenceNode realroot = null;
+        SequenceNode c = root;
+
+        int d = -1;
+        int cp = 0;
+        //int flen = nf.length();
+
+        String Error = null;
+        String nodename = null;
+
+        float DefDistance = (float) 0.001; // @param Default distance for a node - very very small
+        int DefBootstrap = 0; // @param Default bootstrap for a node
+
+        float distance = DefDistance;
+        int bootstrap = DefBootstrap;
+
+        boolean ascending = false; // flag indicating that we are leaving the current node
+
+        com.stevesoft.pat.Regex majorsyms = new com.stevesoft.pat.Regex(
+                "[(\\['),;]");
+
+        while (majorsyms.searchFrom(nf, cp) && (Error == null))
+        {
+            int fcp = majorsyms.matchedFrom();
+
+            switch (nf.charAt(fcp))
+            {
+            case '[': // Comment or structured/extended NH format info
+
+                com.stevesoft.pat.Regex comment = new com.stevesoft.pat.Regex(
+                        "]");
+
+                if (comment.searchFrom(nf, fcp))
+                {
+                    // Skip the comment field
+                    cp = 1 + comment.matchedFrom();
+                }
+                else
+                {
+                    Error = ErrorStringrange(Error, "Unterminated comment", 3,
+                            fcp, nf);
+                }
+
+                ;
+
+                break;
+
+            case '(':
+
+                // ascending should not be set
+                // New Internal node
+                if (ascending)
+                {
+                    Error = ErrorStringrange(Error, "Unexpected '('", 7, fcp, nf);
+
+                    continue;
+                }
+
+                ;
+                d++;
+
+                if (c.right() == null)
+                {
+                    c.setRight(new SequenceNode(null, c, null, DefDistance,
+                            DefBootstrap, false));
+                    c = (SequenceNode) c.right();
+                }
+                else
+                {
+                    if (c.left() != null)
+                    {
+                        // Dummy node for polytomy - keeps c.left free for new node
+                        SequenceNode tmpn = new SequenceNode(null, c, null, 0,
+                                0, true);
+                        tmpn.SetChildren(c.left(), c.right());
+                        c.setRight(tmpn);
+                    }
+
+                    c.setLeft(new SequenceNode(null, c, null, DefDistance,
+                            DefBootstrap, false));
+                    c = (SequenceNode) c.left();
+                }
+
+                if (realroot == null)
+                {
+                    realroot = c;
+                }
+
+                nodename = null;
+                distance = DefDistance;
+                bootstrap = DefBootstrap;
+                cp = fcp + 1;
+
+                break;
+
+            // Deal with quoted fields
+            case '\'':
+
+                com.stevesoft.pat.Regex qnodename = new com.stevesoft.pat.Regex(
+                        "([^']|'')+'");
+
+                if (qnodename.searchFrom(nf, fcp))
+                {
+                    int nl = qnodename.stringMatched().length();
+                    nodename = new String(qnodename.stringMatched().substring(0,
+                                nl - 1));
+                    cp = fcp + nl + 1;
+                }
+                else
+                {
+                    Error = ErrorStringrange(Error,
+                            "Unterminated quotes for nodename", 7, fcp, nf);
+                }
+
+                break;
+
+            case ';':
+
+                if (d != -1)
+                {
+                    Error = ErrorStringrange(Error,
+                            "Wayward semicolon (depth=" + d + ")", 7, fcp, nf);
+                }
+
+            // cp advanced at the end of default
+            default:
+
+                // Parse simpler field strings
+                String fstring = nf.substring(cp, fcp);
+                com.stevesoft.pat.Regex uqnodename = new com.stevesoft.pat.Regex(
+                        "\\b([^' :;\\](),]+)");
+                com.stevesoft.pat.Regex nbootstrap = new com.stevesoft.pat.Regex(
+                        "\\S+([0-9+]+)\\S*:");
+                com.stevesoft.pat.Regex ndist = new com.stevesoft.pat.Regex(
+                        ":([-0-9Ee.+]+)");
+
+                if (uqnodename.search(fstring) &&
+                        ((uqnodename.matchedFrom(1) == 0) ||
+                        (fstring.charAt(uqnodename.matchedFrom(1) - 1) != ':'))) // JBPNote HACK!
+                {
+                    if (nodename == null)
+                    {
+                        if (ReplaceUnderscores)
+                        {
+                            nodename = uqnodename.stringMatched(1).replace('_',
+                                    ' ');
+                        }
+                        else
+                        {
+                            nodename = uqnodename.stringMatched(1);
+                        }
+                    }
+                    else
+                    {
+                        Error = ErrorStringrange(Error,
+                                "File has broken algorithm - overwritten nodename",
+                                10, fcp, nf);
+                    }
+                }
+
+                if (nbootstrap.search(fstring) &&
+                        (nbootstrap.matchedFrom(1) > (uqnodename.matchedFrom(1) +
+                        uqnodename.stringMatched().length())))
+                {
+                    try
+                    {
+                        bootstrap = (new Integer(nbootstrap.stringMatched(1))).intValue();
+                        HasBootstrap = true;
+                    }
+                    catch (Exception e)
+                    {
+                        Error = ErrorStringrange(Error,
+                                "Can't parse bootstrap value", 4,
+                                cp + nbootstrap.matchedFrom(), nf);
+                    }
+                }
+
+                boolean nodehasdistance = false;
+
+                if (ndist.search(fstring))
+                {
+                    try
+                    {
+                        distance = (new Float(ndist.stringMatched(1))).floatValue();
+                        HasDistances = true;
+                        nodehasdistance = true;
+                    }
+                    catch (Exception e)
+                    {
+                        Error = ErrorStringrange(Error,
+                                "Can't parse node distance value", 7,
+                                cp + ndist.matchedFrom(), nf);
+                    }
+                }
+
+                if (ascending)
+                {
+                    // Write node info here
+                    c.setName(nodename);
+                    // Trees without distances still need a render distance
+                    c.dist = (HasDistances) ? distance : DefDistance;
+                    // be consistent for internal bootstrap defaults too
+                    c.setBootstrap((HasBootstrap) ? bootstrap : DefBootstrap);
+                    if (c == realroot)
+                    {
+                        RootHasDistance = nodehasdistance; // JBPNote This is really UGLY!!! Ensure root node gets its given distance
+                    }
+                }
+                else
+                {
+                    // Find a place to put the leaf
+                    SequenceNode newnode = new SequenceNode(null, c, nodename,
+                            (HasDistances) ? distance : DefDistance,
+                            (HasBootstrap) ? bootstrap : DefBootstrap, false);
+
+                    if (c.right() == null)
+                    {
+                        c.setRight(newnode);
+                    }
+                    else
+                    {
+                        if (c.left() == null)
+                        {
+                            c.setLeft(newnode);
+                        }
+                        else
+                        {
+                            // Insert a dummy node for polytomy
+                            // dummy nodes have distances
+                            SequenceNode newdummy = new SequenceNode(null, c,
+                                    null, (HasDistances ? 0 : DefDistance), 0, true);
+                            newdummy.SetChildren(c.left(), newnode);
+                            c.setLeft(newdummy);
+                        }
+                    }
+                }
+
+                if (ascending)
+                {
+                    // move back up the tree from preceding closure
+                    c = c.AscendTree();
+
+                    if ((d > -1) && (c == null))
+                    {
+                        Error = ErrorStringrange(Error,
+                                "File broke algorithm: Lost place in tree (is there an extra ')' ?)",
+                                7, fcp, nf);
+                    }
+                }
+
+                if (nf.charAt(fcp) == ')')
+                {
+                    d--;
+                    ascending = true;
+                }
+                else
+                {
+                    if (nf.charAt(fcp) == ',')
+                    {
+                        if (ascending)
+                        {
+                            ascending = false;
+                        }
+                        else
+                        {
+                            // Just advance focus, if we need to
+                            if ((c.left() != null) && (!c.left().isLeaf()))
+                            {
+                                c = (SequenceNode) c.left();
+                            }
+                        }
+                    }
+
+                    // else : We do nothing if ';' is encountered.
+                }
+
+                // Reset new node properties to obvious fakes
+                nodename = null;
+                distance = DefDistance;
+                bootstrap = DefBootstrap;
+
+                cp = fcp + 1;
+            }
+        }
+
+        if (Error != null)
+        {
+            throw (new IOException("NewickFile: " + Error + "\n"));
+        }
+
+        root = (SequenceNode) root.right().detach(); // remove the imaginary root.
+
+        if (!RootHasDistance)
+        {
+            root.dist = (HasDistances) ? 0 : DefDistance;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public SequenceNode getTree()
+    {
+        return root;
+    }
+
+    /**
+     * Generate a newick format tree according to internal flags
+     * for bootstraps, distances and root distances.
+     *
+     * @return new hampshire tree in a single line
+     */
+    public String print()
+    {
+        synchronized (this)
+        {
+            StringBuffer tf = new StringBuffer();
+            print(tf, root);
+
+            return (tf.append(";").toString());
+        }
+    }
+
+    /**
+     *
+     *
+     * Generate a newick format tree according to internal flags
+     * for distances and root distances and user specificied writing of
+     * bootstraps.
+     * @param withbootstraps controls if bootstrap values are explicitly written.
+     *
+     * @return new hampshire tree in a single line
+     */
+    public String print(boolean withbootstraps)
+    {
+        synchronized (this)
+        {
+            boolean boots = this.HasBootstrap;
+            this.HasBootstrap = withbootstraps;
+
+            String rv = print();
+            this.HasBootstrap = boots;
+
+            return rv;
+        }
+    }
+
+    /**
+     *
+     * Generate newick format tree according to internal flags
+     * for writing root node distances.
+     *
+     * @param withbootstraps explicitly write bootstrap values
+     * @param withdists explicitly write distances
+     *
+     * @return new hampshire tree in a single line
+     */
+    public String print(boolean withbootstraps, boolean withdists)
+    {
+        synchronized (this)
+        {
+            boolean dists = this.HasDistances;
+            this.HasDistances = withdists;
+
+            String rv = print(withbootstraps);
+            this.HasDistances = dists;
+
+            return rv;
+        }
+    }
+
+    /**
+     * Generate newick format tree according to user specified flags
+     *
+     * @param withbootstraps explicitly write bootstrap values
+     * @param withdists explicitly write distances
+     * @param printRootInfo explicitly write root distance
+     *
+     * @return new hampshire tree in a single line
+     */
+    public String print(boolean withbootstraps, boolean withdists,
+        boolean printRootInfo)
+    {
+        synchronized (this)
+        {
+            boolean rootinfo = printRootInfo;
+            this.printRootInfo = printRootInfo;
+
+            String rv = print(withbootstraps, withdists);
+            this.printRootInfo = rootinfo;
+
+            return rv;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    char getQuoteChar()
+    {
+        return QuoteChar;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    char setQuoteChar(char c)
+    {
+        char old = QuoteChar;
+        QuoteChar = c;
+
+        return old;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private String nodeName(String name)
+    {
+        if (NodeSafeName[0].search(name))
+        {
+            return QuoteChar + NodeSafeName[1].replaceAll(name) + QuoteChar;
+        }
+        else
+        {
+            return NodeSafeName[2].replaceAll(name);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private String printNodeField(SequenceNode c)
+    {
+        return ((c.getName() == null) ? "" : nodeName(c.getName())) +
+        ((HasBootstrap)
+        ? ((c.getBootstrap() > -1) ? (" " + c.getBootstrap()) : "") : "") +
+        ((HasDistances) ? (":" + c.dist) : "");
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param root DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private String printRootField(SequenceNode root)
+    {
+        return (printRootInfo)
+        ? (((root.getName() == null) ? "" : nodeName(root.getName())) +
+        ((HasBootstrap)
+        ? ((root.getBootstrap() > -1) ? (" " + root.getBootstrap()) : "") : "") +
+        ((RootHasDistance) ? (":" + root.dist) : "")) : "";
+    }
+
+    // Non recursive call deals with root node properties
+    public void print(StringBuffer tf, SequenceNode root)
+    {
+        if (root != null)
+        {
+            if (root.isLeaf() && printRootInfo)
+            {
+                tf.append(printRootField(root));
+            }
+            else
+            {
+                if (root.isDummy())
+                {
+                    _print(tf, (SequenceNode) root.right());
+                    _print(tf, (SequenceNode) root.left());
+                }
+                else
+                {
+                    tf.append("(");
+                    _print(tf, (SequenceNode) root.right());
+
+                    if (root.left() != null)
+                    {
+                        tf.append(",");
+                    }
+
+                    _print(tf, (SequenceNode) root.left());
+                    tf.append(")" + printRootField(root));
+                }
+            }
+        }
+    }
+
+    // Recursive call for non-root nodes
+    public void _print(StringBuffer tf, SequenceNode c)
+    {
+        if (c != null)
+        {
+            if (c.isLeaf())
+            {
+                tf.append(printNodeField(c));
+            }
+            else
+            {
+                if (c.isDummy())
+                {
+                    _print(tf, (SequenceNode) c.left());
+                    if (c.left() != null)
+                    {
+                      tf.append(",");
+                    }
+                    _print(tf, (SequenceNode) c.right());
+                }
+                else
+                {
+                    tf.append("(");
+                    _print(tf, (SequenceNode) c.right());
+
+                    if (c.left() != null)
+                    {
+                        tf.append(",");
+                    }
+
+                    _print(tf, (SequenceNode) c.left());
+                    tf.append(")" + printNodeField(c));
+                }
+            }
+        }
+    }
+
+    // Test
+    public static void main(String[] args)
+    {
+        try
+        {
+            if (args==null || args.length!=1) {
+              System.err.println("Takes one argument - file name of a newick tree file.");
+              System.exit(0);
+            }
+
+            File fn = new File(args[0]);
+
+            StringBuffer newickfile = new StringBuffer();
+            BufferedReader treefile = new BufferedReader(new FileReader(fn));
+            String l;
+
+            while ((l = treefile.readLine()) != null)
+            {
+                newickfile.append(l);
+            }
+
+            treefile.close();
+            System.out.println("Read file :\n");
+
+            NewickFile trf = new NewickFile(args[0], "File");
+            trf.parse();
+            System.out.println("Original file :\n");
+
+            com.stevesoft.pat.Regex nonl = new com.stevesoft.pat.Regex("\n+", "");
+            System.out.println(nonl.replaceAll(newickfile.toString()) + "\n");
+
+            System.out.println("Parsed file.\n");
+            System.out.println("Default output type for original input.\n");
+            System.out.println(trf.print());
+            System.out.println("Without bootstraps.\n");
+            System.out.println(trf.print(false));
+            System.out.println("Without distances.\n");
+            System.out.println(trf.print(true, false));
+            System.out.println("Without bootstraps but with distanecs.\n");
+            System.out.println(trf.print(false, true));
+            System.out.println("Without bootstraps or distanecs.\n");
+            System.out.println(trf.print(false, false));
+            System.out.println("With bootstraps and with distances.\n");
+            System.out.println(trf.print(true, true));
+        }
+        catch (java.io.IOException e)
+        {
+            System.err.println("Exception\n" + e);
+            e.printStackTrace();
+        }
+    }
+}
index 6d6e525..f409a73 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class PIRFile\r
-    extends AlignFile\r
-{\r
-  Vector words = new Vector(); //Stores the words in a line after splitting\r
-\r
-  public PIRFile()\r
-  {\r
-  }\r
-\r
-  public PIRFile(String inStr)\r
-  {\r
-    super(inStr);\r
-  }\r
-\r
-  public PIRFile(String inFile, String type)\r
-      throws IOException\r
-  {\r
-    super(inFile, type);\r
-  }\r
-\r
-  public void parse() throws IOException\r
-  {\r
-      StringBuffer sequence;\r
-      String line = null;\r
-\r
-      while ( (line = nextLine()) != null)\r
-      {\r
-        if (line.length() == 0)\r
-        {\r
-          //System.out.println("blank line");\r
-          continue;\r
-        }\r
-        if (line.indexOf("C;") == 0 || line.indexOf("#") == 0)\r
-        {\r
-          continue;\r
-        }\r
-        Sequence newSeq = parseId(line.substring(line.indexOf(";") + 1));\r
-\r
-        sequence = new StringBuffer();\r
-\r
-        newSeq.setDescription(nextLine()); // this is the title line\r
-\r
-        boolean starFound = false;\r
-\r
-        while(!starFound)\r
-        {\r
-          line = nextLine();\r
-          sequence.append(line);\r
-\r
-          if (line == null)\r
-            break;\r
-\r
-          if (line.indexOf("*") > -1)\r
-          {\r
-            starFound = true;\r
-          }\r
-        }\r
-\r
-        if (sequence.length() > 0)\r
-        {\r
-          sequence.setLength(sequence.length() - 1);\r
-          newSeq.setSequence(sequence.toString());\r
-          if (!isValidProteinSequence(newSeq.getSequence()))\r
-          {\r
-            throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
-                                  +" : "+ newSeq.getName()\r
-                                  +" : "+invalidCharacter);\r
-          }\r
-\r
-          seqs.addElement(newSeq);\r
-          ModellerDescription md = new ModellerDescription(newSeq.\r
-              getDescription());\r
-          md.updateSequenceI(newSeq);\r
-        }\r
-      }\r
-  }\r
-\r
-  public String print()\r
-  {\r
-    return print(getSeqsAsArray());\r
-  }\r
-\r
-  public String print(SequenceI[] s)\r
-  {\r
-    boolean is_NA = jalview.util.Comparison.isNucleotide(s);\r
-    int len = 72;\r
-    StringBuffer out = new StringBuffer();\r
-    int i = 0;\r
-\r
-    while ( (i < s.length) && (s[i] != null))\r
-    {\r
-      String seq = s[i].getSequence();\r
-      seq = seq + "*";\r
-\r
-      if (is_NA)\r
-      {\r
-        // modeller doesn't really do nucleotides, so we don't do anything fancy\r
-        // Nucleotide sequence tags should have a >DL; prefix\r
-        out.append(">N1;" + s[i].getName() + "\n"); // JBPNote Should change >P to >N\r
-        if (s[i].getDescription() == null)\r
-        {\r
-          out.append(s[i].getName() + " " +\r
-                     (s[i].getEnd() - s[i].getStart() + 1));\r
-          out.append(is_NA ? " bases\n" : " residues\n");\r
-        }\r
-        else\r
-        {\r
-          out.append(s[i].getDescription()+"\n");\r
-        }\r
-      }\r
-      else\r
-      {\r
-        out.append(">P1;" + s[i].getName() + "\n");\r
-        ModellerDescription md = new ModellerDescription(s[i]);\r
-        out.append(md.getDescriptionLine() + "\n");\r
-      }\r
-      int nochunks = (seq.length() / len) + 1;\r
-\r
-      for (int j = 0; j < nochunks; j++)\r
-      {\r
-        int start = j * len;\r
-        int end = start + len;\r
-\r
-        if (end < seq.length())\r
-        {\r
-          out.append(seq.substring(start, end) + "\n");\r
-        }\r
-        else if (start < seq.length())\r
-        {\r
-          out.append(seq.substring(start) + "\n");\r
-        }\r
-      }\r
-\r
-      i++;\r
-    }\r
-\r
-    return out.toString();\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+import java.util.*;
+
+import jalview.datamodel.*;
+
+public class PIRFile
+    extends AlignFile
+{
+  public static boolean useModellerOutput = false;
+
+  Vector words = new Vector(); //Stores the words in a line after splitting
+
+  public PIRFile()
+  {
+  }
+
+  public PIRFile(String inFile, String type)
+      throws IOException
+  {
+    super(inFile, type);
+  }
+
+  public void parse() throws IOException
+  {
+      StringBuffer sequence;
+      String line = null;
+      ModellerDescription md;
+
+      while ( (line = nextLine()) != null)
+      {
+        if (line.length() == 0)
+        {
+          //System.out.println("blank line");
+          continue;
+        }
+        if (line.indexOf("C;") == 0 || line.indexOf("#") == 0)
+        {
+          continue;
+        }
+        Sequence newSeq = parseId(line.substring(line.indexOf(";") + 1));
+
+        sequence = new StringBuffer();
+
+        newSeq.setDescription(nextLine()); // this is the title line
+
+        boolean starFound = false;
+
+        while(!starFound)
+        {
+          line = nextLine();
+          sequence.append(line);
+
+          if (line == null)
+            break;
+
+          if (line.indexOf("*") > -1)
+          {
+            starFound = true;
+          }
+        }
+
+        if (sequence.length() > 0)
+        {
+          sequence.setLength(sequence.length() - 1);
+          newSeq.setSequence(sequence.toString());
+          if (!isValidProteinSequence(newSeq.getSequence()))
+          {
+            throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS
+                                  +" : "+ newSeq.getName()
+                                  +" : "+invalidCharacter);
+          }
+
+          seqs.addElement(newSeq);
+
+          md = new ModellerDescription(newSeq.
+                getDescription());
+          md.updateSequenceI(newSeq);
+        }
+      }
+  }
+
+  public String print()
+  {
+    return print(getSeqsAsArray());
+  }
+
+  public String print(SequenceI[] s)
+  {
+    boolean is_NA = jalview.util.Comparison.isNucleotide(s);
+    int len = 72;
+    StringBuffer out = new StringBuffer();
+    int i = 0;
+    ModellerDescription md;
+
+    while ( (i < s.length) && (s[i] != null))
+    {
+      String seq = s[i].getSequence();
+      seq = seq + "*";
+
+
+      if (is_NA)
+      {
+          // modeller doesn't really do nucleotides, so we don't do anything fancy
+          // Official tags area as follows, for now we'll use P1 and DL
+          // Protein (complete) P1
+          // Protein (fragment) F1
+          // DNA (linear) Dl
+          // DNA (circular) DC
+          // RNA (linear) RL
+          // RNA (circular) RC
+          // tRNA N3
+          // other functional RNA N1
+
+        out.append(">N1;" + s[i].getName() + "\n");
+        if (s[i].getDescription() == null)
+        {
+          out.append(s[i].getName() + " " +
+                     (s[i].getEnd() - s[i].getStart() + 1));
+          out.append(is_NA ? " bases\n" : " residues\n");
+        }
+        else
+        {
+          out.append(s[i].getDescription()+"\n");
+        }
+      }
+      else
+      {
+
+       if(useModellerOutput)
+       {
+         out.append(">P1;" + s[i].getName() + "\n");
+         md = new ModellerDescription(s[i]);
+         out.append(md.getDescriptionLine() + "\n");
+       }
+       else
+       {
+         out.append(">P1;" + printId(s[i]) + "\n");
+         if (s[i].getDescription() != null)
+           out.append(s[i].getDescription() + "\n");
+         else
+           out.append(s[i].getName() + " "
+                      + (s[i].getEnd() - s[i].getStart() + 1)
+                      + " residues\n");
+       }
+      }
+      int nochunks = (seq.length() / len) + 1;
+
+      for (int j = 0; j < nochunks; j++)
+      {
+        int start = j * len;
+        int end = start + len;
+
+        if (end < seq.length())
+        {
+          out.append(seq.substring(start, end) + "\n");
+        }
+        else if (start < seq.length())
+        {
+          out.append(seq.substring(start) + "\n");
+        }
+      }
+
+      i++;
+    }
+
+    return out.toString();
+  }
+
+}
index 8056f38..67d748c 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.util.*;\r
-\r
-public class PfamFile\r
-    extends AlignFile\r
-{\r
-\r
-  public PfamFile()\r
-  {\r
-  }\r
-\r
-  public PfamFile(String inStr)\r
-  {\r
-    super(inStr);\r
-  }\r
-\r
-  public PfamFile(String inFile, String type)\r
-      throws IOException\r
-  {\r
-    super(inFile, type);\r
-  }\r
-\r
-  public void initData()\r
-  {\r
-    super.initData();\r
-  }\r
-\r
-  public void parse() throws IOException\r
-  {\r
-    int i = 0;\r
-    String line;\r
-\r
-    Hashtable seqhash = new Hashtable();\r
-    Vector headers = new Vector();\r
-\r
-    while ( (line = nextLine()) != null)\r
-    {\r
-      if (line.indexOf(" ") != 0)\r
-      {\r
-        if (line.indexOf("#") != 0)\r
-        {\r
-          StringTokenizer str = new StringTokenizer(line, " ");\r
-          String id = "";\r
-\r
-          if (str.hasMoreTokens())\r
-          {\r
-            id = str.nextToken();\r
-\r
-            StringBuffer tempseq;\r
-\r
-            if (seqhash.containsKey(id))\r
-            {\r
-              tempseq = (StringBuffer) seqhash.get(id);\r
-            }\r
-            else\r
-            {\r
-              tempseq = new StringBuffer();\r
-              seqhash.put(id, tempseq);\r
-            }\r
-\r
-            if (! (headers.contains(id)))\r
-            {\r
-              headers.addElement(id);\r
-            }\r
-\r
-            tempseq.append(str.nextToken());\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    this.noSeqs = headers.size();\r
-\r
-    if (noSeqs < 1)\r
-    {\r
-      throw new IOException("No sequences found (PFAM input)");\r
-    }\r
-\r
-    for (i = 0; i < headers.size(); i++)\r
-    {\r
-      if (seqhash.get(headers.elementAt(i)) != null)\r
-      {\r
-        if (maxLength < seqhash.get(headers.elementAt(i)).toString()\r
-            .length())\r
-        {\r
-          maxLength = seqhash.get(headers.elementAt(i)).toString()\r
-              .length();\r
-        }\r
-\r
-\r
-        Sequence newSeq = parseId(headers.elementAt(i).toString());\r
-        newSeq.setSequence( seqhash.get(headers.elementAt(i).toString()).toString());\r
-        seqs.addElement(newSeq);\r
-\r
-        if (!isValidProteinSequence(newSeq.getSequence()))\r
-        {\r
-          throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
-                                +" : "+ newSeq.getName()\r
-                                +" : "+invalidCharacter);\r
-        }\r
-      }\r
-      else\r
-      {\r
-        System.err.println("PFAM File reader: Can't find sequence for " +\r
-                           headers.elementAt(i));\r
-      }\r
-    }\r
-  }\r
-\r
-  public String print(SequenceI[] s)\r
-  {\r
-    StringBuffer out = new StringBuffer("");\r
-\r
-    int max = 0;\r
-    int maxid = 0;\r
-\r
-    int i = 0;\r
-\r
-    while ( (i < s.length) && (s[i] != null))\r
-    {\r
-      String tmp = printId(s[i]);\r
-\r
-      if (s[i].getSequence().length() > max)\r
-      {\r
-        max = s[i].getSequence().length();\r
-      }\r
-\r
-      if (tmp.length() > maxid)\r
-      {\r
-        maxid = tmp.length();\r
-      }\r
-\r
-      i++;\r
-    }\r
-\r
-    if (maxid < 15)\r
-    {\r
-      maxid = 15;\r
-    }\r
-\r
-    int j = 0;\r
-\r
-    while ( (j < s.length) && (s[j] != null))\r
-    {\r
-      out.append(new Format("%-" + maxid + "s").form( printId(s[j])+" "));\r
-\r
-      out.append(s[j].getSequence() + "\n");\r
-      j++;\r
-    }\r
-\r
-    out.append("\n");\r
-\r
-    return out.toString();\r
-  }\r
-\r
-  public String print()\r
-  {\r
-    return print(getSeqsAsArray());\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+import java.io.*;
+import java.util.*;
+
+import jalview.datamodel.*;
+import jalview.util.*;
+
+public class PfamFile
+    extends AlignFile
+{
+
+  public PfamFile()
+  {
+  }
+
+  public PfamFile(String inFile, String type)
+      throws IOException
+  {
+    super(inFile, type);
+  }
+
+  public void initData()
+  {
+    super.initData();
+  }
+
+  public void parse() throws IOException
+  {
+    int i = 0;
+    String line;
+
+    Hashtable seqhash = new Hashtable();
+    Vector headers = new Vector();
+
+    while ( (line = nextLine()) != null)
+    {
+      if (line.indexOf(" ") != 0)
+      {
+        if (line.indexOf("#") != 0)
+        {
+          StringTokenizer str = new StringTokenizer(line, " ");
+          String id = "";
+
+          if (str.hasMoreTokens())
+          {
+            id = str.nextToken();
+
+            StringBuffer tempseq;
+
+            if (seqhash.containsKey(id))
+            {
+              tempseq = (StringBuffer) seqhash.get(id);
+            }
+            else
+            {
+              tempseq = new StringBuffer();
+              seqhash.put(id, tempseq);
+            }
+
+            if (! (headers.contains(id)))
+            {
+              headers.addElement(id);
+            }
+
+            tempseq.append(str.nextToken());
+          }
+        }
+      }
+    }
+
+    this.noSeqs = headers.size();
+
+    if (noSeqs < 1)
+    {
+      throw new IOException("No sequences found (PFAM input)");
+    }
+
+    for (i = 0; i < headers.size(); i++)
+    {
+      if (seqhash.get(headers.elementAt(i)) != null)
+      {
+        if (maxLength < seqhash.get(headers.elementAt(i)).toString()
+            .length())
+        {
+          maxLength = seqhash.get(headers.elementAt(i)).toString()
+              .length();
+        }
+
+
+        Sequence newSeq = parseId(headers.elementAt(i).toString());
+        newSeq.setSequence( seqhash.get(headers.elementAt(i).toString()).toString());
+        seqs.addElement(newSeq);
+
+        if (!isValidProteinSequence(newSeq.getSequence()))
+        {
+          throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS
+                                +" : "+ newSeq.getName()
+                                +" : "+invalidCharacter);
+        }
+      }
+      else
+      {
+        System.err.println("PFAM File reader: Can't find sequence for " +
+                           headers.elementAt(i));
+      }
+    }
+  }
+
+  public String print(SequenceI[] s)
+  {
+    StringBuffer out = new StringBuffer("");
+
+    int max = 0;
+    int maxid = 0;
+
+    int i = 0;
+
+    while ( (i < s.length) && (s[i] != null))
+    {
+      String tmp = printId(s[i]);
+
+      if (s[i].getSequence().length() > max)
+      {
+        max = s[i].getSequence().length();
+      }
+
+      if (tmp.length() > maxid)
+      {
+        maxid = tmp.length();
+      }
+
+      i++;
+    }
+
+    if (maxid < 15)
+    {
+      maxid = 15;
+    }
+
+    int j = 0;
+
+    while ( (j < s.length) && (s[j] != null))
+    {
+      out.append(new Format("%-" + maxid + "s").form( printId(s[j])+" "));
+
+      out.append(s[j].getSequence() + "\n");
+      j++;
+    }
+
+    out.append("\n");
+
+    return out.toString();
+  }
+
+  public String print()
+  {
+    return print(getSeqsAsArray());
+  }
+}
index c945fd5..007c306 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.io;\r
-\r
-/**\r
- * <p>Title: </p>\r
- *  PileUpfile\r
- * <p>Description: </p>\r
- *\r
- *  Read and write PileUp style MSF Files.\r
- *  This used to be the MSFFile class, and was written according to the EBI's idea\r
- *  of a subset of the MSF alignment format. But, that was updated to reflect current\r
- *  GCG style IO fashion, as found in Emboss (thanks David Martin!)\r
- *\r
- **/\r
-import java.io.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.util.*;\r
-\r
-public class PileUpfile  extends MSFfile\r
-{\r
-\r
-    /**\r
-     * Creates a new MSFfile object.\r
-     */\r
-    public PileUpfile()\r
-    {\r
-    }\r
-    /**\r
-     * Creates a new MSFfile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public PileUpfile(String inStr)\r
-    {\r
-        super(inStr);\r
-    }\r
-\r
-    /**\r
-     * Creates a new MSFfile object.\r
-     *\r
-     * @param inFile DOCUMENT ME!\r
-     * @param type DOCUMENT ME!\r
-     *\r
-     * @throws IOException DOCUMENT ME!\r
-     */\r
-    public PileUpfile(String inFile, String type) throws IOException\r
-    {\r
-        super(inFile, type);\r
-    }\r
-   /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public String print()\r
-  {\r
-      return print(getSeqsAsArray());\r
-  }\r
-\r
-\r
-  public  String print(SequenceI[] s)\r
-  {\r
-    StringBuffer out = new StringBuffer("PileUp\n\n");\r
-\r
-    int max = 0;\r
-    int maxid = 0;\r
-\r
-    int i = 0;\r
-    int bigChecksum = 0;\r
-    int[] checksums = new int[s.length];\r
-    while (i < s.length)\r
-    {\r
-      checksums[i] = checkSum(s[i].getSequence());\r
-      bigChecksum += checksums[i];\r
-      i++;\r
-    }\r
-\r
-    out.append("   MSF: " + s[0].getSequence().length() +\r
-               "   Type: P    Check:  " + bigChecksum%10000 + "   ..\n\n\n");\r
-\r
-    i=0;\r
-    while ( (i < s.length) && (s[i] != null))\r
-    {\r
-      String seq = s[i].getSequence();\r
-      out.append(" Name: " + printId(s[i]) +\r
-                 " oo  Len:  " +\r
-                 s[i].getSequence().length() + "  Check:  " + checksums[i] +\r
-                 "  Weight:  1.00\n");\r
-\r
-      if (seq.length() > max)\r
-      {\r
-        max = seq.length();\r
-      }\r
-\r
-      if (s[i].getName().length() > maxid)\r
-      {\r
-        maxid = s[i].getName().length();\r
-      }\r
-\r
-      i++;\r
-    }\r
-\r
-    if (maxid < 10)\r
-    {\r
-      maxid = 10;\r
-    }\r
-\r
-    maxid++;\r
-    out.append("\n\n//\n\n");\r
-\r
-    int len = 50;\r
-\r
-    int nochunks = (max / len) + 1;\r
-\r
-    if ( (max % len) == 0)\r
-    {\r
-      nochunks--;\r
-    }\r
-\r
-    for (i = 0; i < nochunks; i++)\r
-    {\r
-      int j = 0;\r
-\r
-      while ( (j < s.length) && (s[j] != null))\r
-      {\r
-        String name = printId(s[j]);\r
-\r
-         out.append(new Format("%-" + maxid + "s").form(name + " "));\r
-\r
-        for (int k = 0; k < 5; k++)\r
-        {\r
-          int start = (i * 50) + (k * 10);\r
-          int end = start + 10;\r
-\r
-          if ( (end < s[j].getSequence().length()) &&\r
-              (start < s[j].getSequence().length()))\r
-          {\r
-            out.append(s[j].getSequence().substring(start, end));\r
-\r
-            if (k < 4)\r
-            {\r
-              out.append(" ");\r
-            }\r
-            else\r
-            {\r
-              out.append("\n");\r
-            }\r
-          }\r
-          else\r
-          {\r
-            if (start < s[j].getSequence().length())\r
-            {\r
-              out.append(s[j].getSequence().substring(start));\r
-              out.append("\n");\r
-            }\r
-            else\r
-            {\r
-              if (k == 0)\r
-              {\r
-                out.append("\n");\r
-              }\r
-            }\r
-          }\r
-        }\r
-\r
-        j++;\r
-      }\r
-\r
-      out.append("\n");\r
-    }\r
-\r
-    return out.toString();\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.io;
+
+/**
+ * <p>Title: </p>
+ *  PileUpfile
+ * <p>Description: </p>
+ *
+ *  Read and write PileUp style MSF Files.
+ *  This used to be the MSFFile class, and was written according to the EBI's idea
+ *  of a subset of the MSF alignment format. But, that was updated to reflect current
+ *  GCG style IO fashion, as found in Emboss (thanks David Martin!)
+ *
+ **/
+import java.io.*;
+
+import jalview.datamodel.*;
+import jalview.util.*;
+
+public class PileUpfile  extends MSFfile
+{
+
+    /**
+     * Creates a new MSFfile object.
+     */
+    public PileUpfile()
+    {
+    }
+
+
+    /**
+     * Creates a new MSFfile object.
+     *
+     * @param inFile DOCUMENT ME!
+     * @param type DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public PileUpfile(String inFile, String type) throws IOException
+    {
+        super(inFile, type);
+    }
+   /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public String print()
+  {
+      return print(getSeqsAsArray());
+  }
+
+
+  public  String print(SequenceI[] s)
+  {
+    StringBuffer out = new StringBuffer("PileUp\n\n");
+
+    int max = 0;
+    int maxid = 0;
+
+    int i = 0;
+    int bigChecksum = 0;
+    int[] checksums = new int[s.length];
+    while (i < s.length)
+    {
+      checksums[i] = checkSum(s[i].getSequence());
+      bigChecksum += checksums[i];
+      i++;
+    }
+
+    out.append("   MSF: " + s[0].getSequence().length() +
+               "   Type: P    Check:  " + bigChecksum%10000 + "   ..\n\n\n");
+
+    i=0;
+    while ( (i < s.length) && (s[i] != null))
+    {
+      String seq = s[i].getSequence();
+      out.append(" Name: " + printId(s[i]) +
+                 " oo  Len:  " +
+                 s[i].getSequence().length() + "  Check:  " + checksums[i] +
+                 "  Weight:  1.00\n");
+
+      if (seq.length() > max)
+      {
+        max = seq.length();
+      }
+
+      if (s[i].getName().length() > maxid)
+      {
+        maxid = s[i].getName().length();
+      }
+
+      i++;
+    }
+
+    if (maxid < 10)
+    {
+      maxid = 10;
+    }
+
+    maxid++;
+    out.append("\n\n//\n\n");
+
+    int len = 50;
+
+    int nochunks = (max / len) + 1;
+
+    if ( (max % len) == 0)
+    {
+      nochunks--;
+    }
+
+    for (i = 0; i < nochunks; i++)
+    {
+      int j = 0;
+
+      while ( (j < s.length) && (s[j] != null))
+      {
+        String name = printId(s[j]);
+
+         out.append(new Format("%-" + maxid + "s").form(name + " "));
+
+        for (int k = 0; k < 5; k++)
+        {
+          int start = (i * 50) + (k * 10);
+          int end = start + 10;
+
+          if ( (end < s[j].getSequence().length()) &&
+              (start < s[j].getSequence().length()))
+          {
+            out.append(s[j].getSequence().substring(start, end));
+
+            if (k < 4)
+            {
+              out.append(" ");
+            }
+            else
+            {
+              out.append("\n");
+            }
+          }
+          else
+          {
+            if (start < s[j].getSequence().length())
+            {
+              out.append(s[j].getSequence().substring(start));
+              out.append("\n");
+            }
+            else
+            {
+              if (k == 0)
+              {
+                out.append("\n");
+              }
+            }
+          }
+        }
+
+        j++;
+      }
+
+      out.append("\n");
+    }
+
+    return out.toString();
+  }
+}
diff --git a/src/jalview/io/SequenceFeatureFetcher.java b/src/jalview/io/SequenceFeatureFetcher.java
deleted file mode 100755 (executable)
index 61b25f9..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.gui.*;\r
-\r
-import java.io.*;\r
-\r
-import java.util.*;\r
-\r
-import org.exolab.castor.mapping.Mapping;\r
-\r
-import org.exolab.castor.xml.*;\r
-import jalview.analysis.AlignSeq;\r
-\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class SequenceFeatureFetcher implements Runnable\r
-{\r
-\r
-  AlignmentI align;\r
-  AlignmentI dataset;\r
-  AlignmentPanel ap;\r
-  ArrayList unknownSequences;\r
-  CutAndPasteTransfer output = new CutAndPasteTransfer();\r
-  StringBuffer sbuffer = new StringBuffer();\r
-  boolean uniprotFlag = false;\r
-\r
-  public SequenceFeatureFetcher()\r
-  {}\r
-\r
-  public Vector getUniprotEntries(File file)\r
-  {\r
-\r
-    UniprotFile uni = new UniprotFile();\r
-    try\r
-    {\r
-      // 1. Load the mapping information from the file\r
-      Mapping map = new Mapping(uni.getClass().getClassLoader());\r
-      java.net.URL url = getClass().getResource("/uniprot_mapping.xml");\r
-      map.loadMapping(url);\r
-\r
-      // 2. Unmarshal the data\r
-      Unmarshaller unmar = new Unmarshaller();\r
-      unmar.setIgnoreExtraElements(true);\r
-      unmar.setMapping(map);\r
-      uni = (UniprotFile) unmar.unmarshal(new FileReader(file));\r
-\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      System.out.println("Error getUniprotEntries() "+e);\r
-    }\r
-    return uni.getUniprotEntries();\r
-  }\r
-\r
-  /**\r
-   * Creates a new SequenceFeatureFetcher object.\r
-   *\r
-   * @param align DOCUMENT ME!\r
-   * @param ap DOCUMENT ME!\r
-   */\r
-  public SequenceFeatureFetcher(AlignmentI align, AlignmentPanel ap)\r
-  {\r
-    unknownSequences = new ArrayList();\r
-    this.align = align;\r
-    this.dataset = align.getDataset();\r
-    this.ap = ap;\r
-\r
-    Thread thread = new Thread(this);\r
-    thread.start();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void run()\r
-  {\r
-    try\r
-    {\r
-      int seqIndex = 0;\r
-      Vector sequences = dataset.getSequences();\r
-\r
-      while (seqIndex < sequences.size())\r
-      {\r
-        Vector ids = new Vector();\r
-\r
-        for (int i = 0; (seqIndex < sequences.size()) && (i < 50);\r
-             seqIndex++, i++)\r
-        {\r
-          Sequence sequence = (Sequence) sequences.get(seqIndex);\r
-          Vector uprefs = jalview.util.DBRefUtils.selectRefs(sequence.getDBRef(), new String[] { "Uniprot"});\r
-          if (uprefs!=null)\r
-          {\r
-            // we know the id for this entry, so don't note its ID in the unknownSequences list\r
-            for (int j=0,k=uprefs.size(); j<k; j++)\r
-              ids.add(((DBRefEntry) uprefs.get(j)).getAccessionId());\r
-            unknownSequences.add(sequence);\r
-          } else {\r
-            if (!ids.contains(sequence.getName()))\r
-            {\r
-              ids.add(sequence.getName());\r
-              unknownSequences.add(sequence);\r
-            }\r
-          }\r
-        }\r
-\r
-        ///////////////////////////////////\r
-        ///READ FROM EBI\r
-        if (ids.size() > 0)\r
-        {\r
-          StringBuffer remainingIds = new StringBuffer("uniprot:");\r
-          for (int i = 0; i < ids.size(); i++)\r
-           {\r
-             if(ids.get(i).toString().indexOf("|")>-1)\r
-             {\r
-               remainingIds.append(ids.get(i).toString().substring(\r
-                   ids.get(i).toString().lastIndexOf("|") + 1));\r
-               uniprotFlag = true;\r
-             }\r
-             remainingIds.append(ids.get(i) + ";");\r
-           }\r
-          EBIFetchClient ebi = new EBIFetchClient();\r
-          File file = ebi.fetchDataAsFile(remainingIds.toString(),\r
-                                          "xml", "raw");\r
-\r
-\r
-\r
-          if (file != null)\r
-          {\r
-            ReadUniprotFile(file, ids);\r
-          }\r
-        }\r
-      }\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    if (sbuffer.length() > 0)\r
-    {\r
-      output.setText(\r
-          "Your sequences have been matched to Uniprot. Some of the ids have been\n" +\r
-          "altered, most likely the start/end residue will have been updated.\n" +\r
-          "Save your alignment to maintain the updated id.\n\n" +\r
-          sbuffer.toString());\r
-      Desktop.addInternalFrame(output, "Sequence names updated ", 600, 300);\r
-      // The above is the dataset, we must now find out the index\r
-      // of the viewed sequence\r
-\r
-    }\r
-\r
-    promptBeforeBlast();\r
-\r
-  }\r
-\r
-\r
-  void promptBeforeBlast()\r
-   {\r
-     // This must be outside the run() body as java 1.5\r
-     // will not return any value from the OptionPane to the expired thread.\r
-      if (unknownSequences.size() > 0)\r
-      {\r
-       // int reply = javax.swing.JOptionPane.showConfirmDialog(\r
-       //     Desktop.desktop, "Couldn't find a match for "+unknownSequences.size()+" sequences."\r
-        //        +"\nPerform blast for unknown sequences?",\r
-        //            "Blast for Unidentified Sequences",\r
-        //             javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.QUESTION_MESSAGE);\r
-     javax.swing.JOptionPane.showMessageDialog(\r
-    Desktop.desktop, "Couldn't find a match for "+unknownSequences.size()+" sequences.",\r
-            "Unidentified Sequences",\r
-             javax.swing.JOptionPane.WARNING_MESSAGE);\r
-\r
-\r
-      //  if(reply == javax.swing.JOptionPane.YES_OPTION)\r
-     //    new WSWUBlastClient(ap, align, unknownSequences);\r
-      }\r
-\r
-\r
-    ap.repaint();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param result DOCUMENT ME!\r
-   * @param out DOCUMENT ME!\r
-   * @param align DOCUMENT ME!\r
-   */\r
-  void ReadUniprotFile(File file, Vector ids)\r
-  {\r
-    if(!file.exists())\r
-      return;\r
-\r
-    SequenceI sequence = null;\r
-\r
-    Vector entries = getUniprotEntries(file);\r
-\r
-    int i, iSize = entries==null?0:entries.size();\r
-    UniprotEntry entry;\r
-    for (i = 0; i < iSize; i++)\r
-    {\r
-      entry = (UniprotEntry) entries.elementAt(i);\r
-      String idmatch = entry.getAccession().elementAt(0).toString();\r
-      sequence = dataset.findName(idmatch);\r
-\r
-      if (sequence == null)\r
-      {\r
-        //Sequence maybe Name, not Accession\r
-        idmatch = entry.getName().elementAt(0).toString();\r
-        sequence = dataset.findName(idmatch);\r
-      }\r
-\r
-      if(sequence!=null)\r
-        ids.remove(sequence.getName());\r
-\r
-      else  if (sequence == null && uniprotFlag)\r
-      {\r
-          sequence = dataset.findName("UniProt/Swiss-Prot|"+entry.getAccession().elementAt(0)+"|"+idmatch);\r
-          ids.remove(idmatch);\r
-      }\r
-\r
-      if(sequence ==null)\r
-      {\r
-        System.out.println(idmatch+" not found");\r
-        continue;\r
-      }\r
-\r
-\r
-      String nonGapped = AlignSeq.extractGaps("-. ", sequence.getSequence());\r
-\r
-      int absStart = entry.getUniprotSequence().getContent().indexOf(\r
-          nonGapped.toString());\r
-\r
-      if (absStart == -1)\r
-      {\r
-        // Is UniprotSequence contained in dataset sequence?\r
-        absStart = nonGapped.toString().indexOf(entry.getUniprotSequence().getContent());\r
-        if(absStart == -1)\r
-        {\r
-          sbuffer.append(sequence.getName() +\r
-                         " SEQUENCE NOT %100 MATCH \n");\r
-\r
-          continue;\r
-        }\r
-        else\r
-        {\r
-\r
-          if(entry.getFeature()!=null)\r
-          {\r
-            Enumeration e = entry.getFeature().elements();\r
-            while (e.hasMoreElements())\r
-            {\r
-              SequenceFeature sf = (SequenceFeature) e.nextElement();\r
-              sf.setBegin(sf.getBegin() + absStart + 1);\r
-              sf.setEnd(sf.getEnd() + absStart + 1);\r
-            }\r
-          }\r
-\r
-          sbuffer.append(sequence.getName() +\r
-                         " HAS "+absStart+" PREFIXED RESIDUES COMPARED TO UNIPROT - ANY SEQUENCE FEATURES"\r
-                        +" HAVE BEEN ADJUSTED ACCORDINGLY \n");\r
-          absStart = 0;\r
-        }\r
-\r
-      }\r
-\r
-      unknownSequences.remove(sequence);\r
-\r
-      int absEnd = absStart + nonGapped.toString().length();\r
-      absStart += 1;\r
-\r
-      Enumeration e = entry.getDbReference().elements();\r
-      Vector onlyPdbEntries = new Vector();\r
-      while(e.hasMoreElements())\r
-      {\r
-        PDBEntry pdb = (PDBEntry)e.nextElement();\r
-        if(!pdb.getType().equals("PDB"))\r
-          continue;\r
-\r
-        onlyPdbEntries.addElement(pdb);\r
-      }\r
-\r
-      sequence.setPDBId(onlyPdbEntries);\r
-      if (entry.getFeature()!=null) {\r
-        e = entry.getFeature().elements();\r
-        while (e.hasMoreElements())\r
-        {\r
-          SequenceFeature sf = (SequenceFeature) e.nextElement();\r
-          sf.setFeatureGroup("Uniprot");\r
-          sequence.addSequenceFeature( sf );\r
-        }\r
-      }\r
-      sequence.setStart(absStart);\r
-      sequence.setEnd(absEnd);\r
-\r
-\r
-      int n = 0;\r
-      SequenceI seq2;\r
-      while (n < align.getHeight())\r
-      {\r
-        //This loop enables multiple sequences with the same\r
-        //id to have features added and seq limits updated\r
-        seq2 = align.getSequenceAt(n);\r
-        if (seq2.getName().equals(idmatch))\r
-        {\r
-\r
-          nonGapped = AlignSeq.extractGaps("-. ", seq2.getSequence());\r
-\r
-          absStart = sequence.getSequence().indexOf(nonGapped);\r
-          absEnd = absStart + nonGapped.toString().length() - 1;\r
-\r
-          // This is the Viewd alignment sequences\r
-          // No need to tell the user of the dataset updates\r
-          if ( (seq2.getStart() != absStart+sequence.getStart())\r
-             || (seq2.getEnd() != absEnd+sequence.getStart()))\r
-          {\r
-            sbuffer.append("Updated: " + seq2.getName() + " " +\r
-                           seq2.getStart() + "/" + seq2.getEnd() +\r
-                           "  to  " + (absStart + sequence.getStart()) + "/" +\r
-                           (absEnd + sequence.getStart()) + "\n");\r
-\r
-            seq2.setStart(absStart + sequence.getStart());\r
-            seq2.setEnd(absEnd + sequence.getStart());\r
-          }\r
-        }\r
-\r
-        n++;\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-\r
index 3915446..a9735be 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.io;\r
-\r
-import org.vamsas.client.Vobject;\r
-import org.vamsas.client.VorbaId;\r
-import org.vamsas.objects.core.*;\r
-import org.vamsas.objects.utils.DocumentStuff;\r
-import org.vamsas.test.simpleclient.ClientDoc;\r
-\r
-import jalview.bin.Cache;\r
-import jalview.datamodel.SequenceI;\r
-import jalview.gui.*;\r
-import java.io.*;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Hashtable;\r
-import java.util.IdentityHashMap;\r
-import java.util.jar.*;\r
-import org.exolab.castor.xml.*;\r
-import org.exolab.castor.mapping.Mapping;\r
-\r
-/*\r
-\r
- static {\r
- org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty(\r
- "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer");\r
- }\r
-\r
- */\r
-\r
-public class VamsasDatastore\r
-{\r
-       Entry provEntry=null;\r
-       AlignViewport av;\r
-       org.exolab.castor.types.Date date\r
-       = new org.exolab.castor.types.Date(new java.util.Date());\r
-       ClientDoc cdoc;\r
-       Hashtable vobj2jv;\r
-       IdentityHashMap jv2vobj;\r
-       public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj, Entry provEntry) {\r
-               \r
-               this.cdoc = cdoc;\r
-               this.vobj2jv = vobj2jv;\r
-               this.jv2vobj = jv2vobj;\r
-               this.provEntry = provEntry;\r
-       }\r
-       \r
-       /* public void storeJalview(String file, AlignFrame af)\r
-        {\r
-          try\r
-          {\r
-            // 1. Load the mapping information from the file\r
-            Mapping map = new Mapping(getClass().getClassLoader());\r
-            java.net.URL url = getClass().getResource("/jalview_mapping.xml");\r
-            map.loadMapping(url);\r
-\r
-            // 2. Unmarshal the data\r
-            // Unmarshaller unmar = new Unmarshaller();\r
-            //unmar.setIgnoreExtraElements(true);\r
-            //unmar.setMapping(map);\r
-            // uni = (UniprotFile) unmar.unmarshal(new FileReader(file));\r
-\r
-            // 3. marshal the data with the total price back and print the XML in the console\r
-              Marshaller marshaller = new Marshaller( new FileWriter(file) );\r
-\r
-             marshaller.setMapping(map);\r
-             marshaller.marshal(af);\r
-          }\r
-          catch (Exception e)\r
-          {\r
-            e.printStackTrace();\r
-          }\r
-        }\r
-\r
-\r
-        */\r
-       \r
-       protected Vobject getjv2vObj(Object jvobj) {\r
-               if (jv2vobj.containsKey(jvobj))\r
-                       return cdoc.getObject(((VorbaId)jv2vobj.get(jvobj)));\r
-               return null;\r
-       }\r
-       \r
-       protected Object getvObj2jv(org.vamsas.client.Vobject vobj) {\r
-               VorbaId id = vobj.getVorbaId();\r
-               if (id==null) {\r
-                       id = cdoc.registerObject(vobj);\r
-                       Cache.log.debug("Registering new object and returning null for getvObj2jv");\r
-                       return null;\r
-               }\r
-               if (vobj2jv.containsKey(vobj.getVorbaId()))\r
-                       return vobj2jv.get(id);\r
-               return null;\r
-       }\r
-       protected void bindjvvobj(Object jvobj, org.vamsas.client.Vobject vobj) {\r
-               VorbaId id = vobj.getVorbaId();\r
-               if (id==null) {\r
-                       id = cdoc.registerObject(vobj);\r
-               }\r
-               if (vobj2jv.containsKey(vobj.getVorbaId())||jv2vobj.containsKey(jvobj)) {\r
-                       Cache.log.error("Duplicate object binding!");\r
-               } else {\r
-                       vobj2jv.put(vobj.getVorbaId(),jvobj);// JBPNote - better implementing a hybrid invertible hash.\r
-                       jv2vobj.put(jvobj,vobj.getVorbaId());                           \r
-               }\r
-       }\r
-       \r
-       public void storeVAMSAS(AlignViewport av) \r
-       {\r
-               long time = System.currentTimeMillis();\r
-               \r
-               try\r
-               {\r
-                       \r
-                       jalview.datamodel.AlignmentI jal = av.getAlignment();\r
-                       \r
-                       \r
-                       ///////////////////////////////////////////\r
-                       // SAVE THE DATASET\r
-                       VAMSAS root = cdoc.getVamsasRoots()[0];\r
-                       if (jal.getDataset()==null) {\r
-                               Cache.log.warn("Creating new dataset for an alignment.");\r
-                               jal.setDataset(null); // \r
-                       }\r
-                       boolean nw=false;\r
-                       DataSet dataset = (DataSet) getjv2vObj(jal.getDataset());\r
-                       if (dataset==null) {\r
-                               dataset = new DataSet();\r
-                               root.addDataSet(dataset);\r
-                               bindjvvobj(jal.getDataset(),dataset);\r
-                               nw=true;\r
-                       } //else {\r
-                       // should really check root corresponds to dataset.\r
-                       // }\r
-                       // update dataset\r
-                       Sequence sequence;\r
-                       DbRef dbref;\r
-                       for (int i = 0; i < jal.getHeight(); i++)\r
-                       {\r
-                               SequenceI sq = jal.getDataset().getSequenceAt(i);\r
-                               sequence = (Sequence) getjv2vObj(sq);\r
-                               if (sequence==null) {\r
-                                       sequence=new Sequence();\r
-                                       bindjvvobj(sq, sequence);\r
-                                       sq.setVamsasId(sequence.getVorbaId().getId());\r
-                                       sequence.setSequence(sq.getSequence());\r
-                                       sequence.setName(jal.getDataset().getSequenceAt(i).getName());\r
-                                       sequence.setStart(jal.getDataset().getSequenceAt(i).getStart());\r
-                                       sequence.setEnd(jal.getDataset().getSequenceAt(i).getEnd());\r
-                                       dataset.addSequence(sequence);\r
-                               } else {\r
-                                       // verify principal attributes.\r
-                                       \r
-                               }\r
-                               \r
-                               if(jal.getDataset().getSequenceAt(i).getSequenceFeatures()!=null)\r
-                               {\r
-                                       int sfSize = jal.getDataset().getSequenceAt(i).getSequenceFeatures().length;\r
-                                       \r
-                                       for (int sf = 0; sf < sfSize; sf++)\r
-                                       {\r
-                                               jalview.datamodel.SequenceFeature feature =\r
-                                                       (jalview.datamodel.SequenceFeature)\r
-                                                       jal.getDataset().getSequenceAt(i).getSequenceFeatures()[sf];\r
-                                               \r
-                                               DataSetAnnotations dsa = (DataSetAnnotations) getjv2vObj(feature); \r
-                                               if (dsa==null) {\r
-                                                       dsa = new DataSetAnnotations();\r
-                                                       bindjvvobj(feature, dsa);\r
-                                                       dsa.setType(feature.getType());\r
-                                                       dsa.setBegin(feature.getBegin());\r
-                                                       dsa.setEnd(feature.getEnd());\r
-                                                       dsa.setDescription(feature.getDescription());\r
-                                                       dsa.setStatus(feature.getStatus());\r
-                                                       if (dsa.getProvenance()==null) {\r
-                                                               dsa.setProvenance(new Provenance());\r
-                                                       }\r
-                                                       \r
-                                                       dsa.getProvenance().addEntry(provEntry); // JBPNote - need to update jalview datamodel.\r
-                                                       dsa.setSeqRef(sequence);\r
-                                                       dataset.addDataSetAnnotations(dsa);\r
-                                               } else {\r
-                                                       // todo: verify\r
-                                               }\r
-                                       }\r
-                               }\r
-                               \r
-                               if(jal.getDataset().getSequenceAt(i).getDBRef()!=null)\r
-                               {\r
-                                       java.util.Vector entries = jal.getDataset().getSequenceAt(i).getDBRef();\r
-                                       jalview.datamodel.DBRefEntry dbentry;\r
-                                       for(int db=0; db<entries.size(); db++)\r
-                                       {\r
-                                               dbentry = (jalview.datamodel.DBRefEntry)entries.elementAt(db);\r
-                                               dbref = (DbRef) getjv2vObj(dbentry);\r
-                                               if (dbref==null) {\r
-                                                       dbref = new DbRef();\r
-                                                       bindjvvobj(dbentry, dbref);\r
-                                                       dbref.setAccessionId( dbentry.getAccessionId() );\r
-                                                       dbref.setSource( dbentry.getSource() );\r
-                                                       dbref.setVersion( dbentry.getVersion() );\r
-                                                       dbref.setId("db"+(time++));\r
-                                                       sequence.addDbRef(dbref);\r
-                                               } else {\r
-                                                       // todo: verify\r
-                                               }\r
-                                       }\r
-                                       \r
-                               }\r
-                               \r
-                               /* not needed any more.\r
-                               if(jal.getDataset().getSequenceAt(i).getVamsasId()==null)\r
-                                       sequence.setId("ds" + (time++));\r
-                               else\r
-                                       sequence.setId(jal.getDataset().getSequenceAt(i).getVamsasId());\r
-                                */\r
-                       }\r
-                       // dataset.setProvenance(getVamsasProvenance(jal.getDataset().getProvenance()));\r
-                       //////////////////////////////////////////////\r
-                       \r
-                       \r
-                       //////////////////////////////////////////////\r
-                       //Save the Alignments\r
-                       \r
-                       Alignment alignment = (Alignment) getjv2vObj(jal);\r
-                       if (alignment==null) {\r
-                               alignment=new Alignment();\r
-                               bindjvvobj(jal, alignment);\r
-                               if (alignment.getProvenance()==null)\r
-                                       alignment.setProvenance(new Provenance());\r
-                               alignment.getProvenance().addEntry(provEntry);\r
-                               dataset.addAlignment(alignment);\r
-                               alignment.setGapChar(av.getGapCharacter() + "");\r
-                               AlignmentSequence alseq = null;\r
-                               for (int i = 0; i < jal.getHeight(); i++)\r
-                               {\r
-                                       alseq = new AlignmentSequence();\r
-                                       alseq.setSequence(\r
-                                                       jal.getSequenceAt(i).getSequence()\r
-                                       );\r
-                                       alseq.setName(jal.getSequenceAt(i).getName());\r
-                                       alseq.setStart(jal.getSequenceAt(i).getStart());\r
-                                       alseq.setEnd(jal.getSequenceAt(i).getEnd());\r
-                                       // how is this going to work ? find alseq in DataSet by..\r
-                                       if (nw) {\r
-                                               // order is conserved because we just created a new dataset.\r
-                                               alseq.setRefid(dataset.getSequence(i));\r
-                                       }\r
-                                       alignment.addAlignmentSequence(alseq);\r
-                               }\r
-                       } else {\r
-                               // todo: verify and update mutable alignment props.\r
-                       }\r
-                       //////////////////////////////////////////////\r
-                       \r
-                       \r
-                       \r
-                       //////////////////////////////////////////////\r
-                       //SAVE ANNOTATIONS\r
-                       if (jal.getAlignmentAnnotation() != null)\r
-                       {\r
-                               jalview.datamodel.AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();\r
-                               \r
-                               for (int i = 0; i < aa.length; i++)\r
-                               {\r
-                                       if (aa[i].label.equals("Quality") ||\r
-                                                       aa[i].label.equals("Conservation") ||\r
-                                                       aa[i].label.equals("Consensus"))\r
-                                       {\r
-                                               continue;\r
-                                       }\r
-                                       AlignmentAnnotations an = (AlignmentAnnotations) getjv2vObj(aa[i]);\r
-                                       if (an==null) {\r
-                                               an = new AlignmentAnnotations();\r
-                                               an.setDescription(aa[i].description);\r
-                                               // JBPNote - have to deal with the many lines for one graph thing\r
-                                               if (aa[i].graph>0)\r
-                                                       an.setGraph(true); //aa[i].graph);\r
-                                               // JBPNote - store graphGroup in the Jalview specific bits.\r
-                                               an.setLabel(aa[i].label);\r
-                                               an.setProvenance(dummyProvenance());\r
-                                               \r
-                                               AnnotationElement ae;\r
-                                               \r
-                                               for (int a = 0; a < aa[i].annotations.length; a++)\r
-                                               {\r
-                                                       if ((aa[i] == null) || (aa[i].annotations[a] == null))\r
-                                                       {\r
-                                                               continue;\r
-                                                       }\r
-                                                       \r
-                                                       ae = new AnnotationElement();\r
-                                                       ae.setDescription(aa[i].annotations[a].description);\r
-                                                       ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);\r
-                                                       ae.setValue(aa[i].annotations[a].value);\r
-                                                       ae.setPosition(a);\r
-                                                       ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure +\r
-                                                       "");\r
-                                                       an.addAnnotationElement(ae);\r
-                                               }\r
-                                               \r
-                                               alignment.addAlignmentAnnotations(an);\r
-                                       } else {\r
-                                               // verify annotation - update (perhaps)\r
-                                       }\r
-                               }\r
-                       }\r
-                       ///////////////////////////////////////////////////////\r
-                       \r
-                       ////////////////////////////////////////////////\r
-                       ///SAVE THE TREES\r
-                       ///////////////////////////////////\r
-                       // FIND ANY ASSOCIATED TREES\r
-                       if (Desktop.desktop != null)\r
-                       {\r
-                               javax.swing.JInternalFrame[] frames = Desktop.desktop.getAllFrames();\r
-                               \r
-                               for (int t = 0; t < frames.length; t++)\r
-                               {\r
-                                       if (frames[t] instanceof TreePanel)\r
-                                       {\r
-                                               TreePanel tp = (TreePanel) frames[t];\r
-                                               \r
-                                               if (tp.getAlignment() == jal)\r
-                                               {\r
-                                                       // JBPNote - can recover alignment and Vamsas Alignment for an associated tree using the getjv2vObj()\r
-                                                       \r
-                                                       Tree tree = (Tree) getjv2vObj(tp);\r
-                                                       if (tree==null) {\r
-                                                               tree = new Tree();\r
-                                                               bindjvvobj(tp,tree);\r
-                                                               tree.setTitle(tp.getTitle());\r
-                                                               Newick newick = new Newick();\r
-                                                               newick.setContent( tp.getTree().toString() );\r
-                                                               newick.setTitle( tp.getTitle() );\r
-                                                               tree.addNewick( newick );\r
-                                                               tree.setProvenance(dummyProvenance());\r
-                                                               alignment.addTree(tree);\r
-                                                       } else {\r
-                                                               // verify any changes.\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               \r
-               catch (Exception ex)\r
-               {\r
-                       ex.printStackTrace();\r
-               }\r
-               \r
-       }\r
-       \r
-       \r
-       \r
-       public void updateJalview()\r
-       {\r
-               VAMSAS root = cdoc.getVamsasRoots()[0];\r
-               try\r
-               {\r
-                       boolean newds=false;\r
-                       for (int _ds=0,_nds=root.getDataSetCount(); _ds<_nds; _ds++) {\r
-                               /////////////////////////////////////\r
-                               /////LOAD DATASET\r
-                               DataSet dataset = vamsas.getDataSet(_ds);\r
-                               int i, iSize = dataset.getSequenceCount();\r
-                               jalview.datamodel.Alignment jdataset = (jalview.datamodel.Alignment) vobj2jv(dataset);\r
-                               if (jdataset!=null) {\r
-                                       // recover\r
-                               } else {\r
-                                       newds=true;\r
-                                       // construct new dataset\r
-                                       jalview.datamodel.Sequence [] seqs = new jalview.datamodel.Sequence[iSize];\r
-                                       DbRef [] dbref;\r
-                                       for (i = 0; i < iSize ; i++)\r
-                                       {\r
-                                               seqs[i] = new jalview.datamodel.Sequence(\r
-                                                               dataset.getSequence(i).getName(),\r
-                                                               dataset.getSequence(i).getSequence(),\r
-                                                               dataset.getSequence(i).getStart(),\r
-                                                               dataset.getSequence(i).getEnd()  );\r
-                                               bindjvvobj(seqs[i], dataset.getSequence(i));\r
-                                               seqs[i].setVamsasId(dataset.getSequence(i).getVorbaId().getId());\r
-                                               \r
-                                               if (dataset.getDataSetAnnotations() != null)\r
-                                               {\r
-                                                       for (int dsa = 0; dsa < dataset.getDataSetAnnotationsCount(); dsa++)\r
-                                                       {\r
-                                                               // could be optimised\r
-                                                               if (dataset.getDataSetAnnotations(dsa).getSeqRef() ==\r
-                                                                       dataset.getSequence(i))\r
-                                                               {\r
-                                                                       jalview.datamodel.SequenceFeature sf;\r
-                                                                       seqs[i].addSequenceFeature(sf=new jalview.datamodel.\r
-                                                                                       SequenceFeature(\r
-                                                                                                       dataset.getDataSetAnnotations(dsa).getType(),\r
-                                                                                                       dataset.getDataSetAnnotations(dsa).getDescription(),\r
-                                                                                                       dataset.getDataSetAnnotations(dsa).getStatus(),\r
-                                                                                                       dataset.getDataSetAnnotations(dsa).getBegin(),\r
-                                                                                                       dataset.getDataSetAnnotations(dsa).getEnd(),\r
-                                                                                       "vamsas"));\r
-                                                                       bindjvvobj(sf, dataset.getDataSetAnnotations(dsa));\r
-                                                               }\r
-                                                       }\r
-                                               }\r
-                                               dbref = dataset.getSequence(i).getDbRef();\r
-                                               \r
-                                               if(dbref.length>0)\r
-                                               {\r
-                                                       for(int db=0; db<dbref.length; db++)\r
-                                                       {\r
-                                                               jalview.datamodel.DBRefEntry dbr;\r
-                                                               seqs[i].addDBRef(dbr= new jalview.datamodel.DBRefEntry\r
-                                                                               (\r
-                                                                                               dbref[db].getSource().toString(),\r
-                                                                                               dbref[db].getVersion().toString(),\r
-                                                                                               dbref[db].getAccessionId().toString()));\r
-                                                               bindjvvobj(dbr, dvref[db]);\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                                       jdataset = jalview.datamodel.Alignment(seqs); // complete construction\r
-                                       bindjvvobj(jdataset, dataset);\r
-                               }\r
-                               ////////////////////////////////////////////////\r
-                       }\r
-                       for (int _al=0,_nal=dataset.getAlignmentCount(); _al<_nal; _al++) {\r
-                               //////////////////////////////////////\r
-                               ////LOAD ALIGNMENT\r
-                               Alignment alignment = dataset.getAlignment(_al);\r
-                               iSize = alignment.getAlignmentSequenceCount();\r
-                               jalview.datamodel.Alignment jal = getvObj2jv(alignment); \r
-                               if (jal!=null) {\r
-                                       // merge/update\r
-                               } else {\r
-                                       seqs = new jalview.datamodel.Sequence[iSize];\r
-                                       String id;\r
-                                       int j, jSize = jdataset.getHeight();\r
-                                       for (i = 0; i < iSize; i++)\r
-                                       {\r
-                                               seqs[i] = new jalview.datamodel.Sequence(\r
-                                                               alignment.getAlignmentSequence(i).getName(),\r
-                                                               alignment.getAlignmentSequence(i).getSequence(),\r
-                                                               alignment.getAlignmentSequence(i).getStart(),\r
-                                                               alignment.getAlignmentSequence(i).getEnd());\r
-                                               bindjvvobj(seqs[i], alignment.getAlignmentSequence(i));\r
-                                               id = ( (Sequence) alignment.getAlignmentSequence(i).getRefid()).getVorbaId().getId();\r
-                                               \r
-                                               for(j=0; j<jSize; j++)\r
-                                               {\r
-                                                       if(jdataset.getSequenceAt(j).getVamsasId().equals(id))\r
-                                                       {\r
-                                                               seqs[i].setDatasetSequence( jdataset.getSequenceAt(j) );\r
-                                                               break;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                                       jalview.datamodel.Alignment jal = new jalview.datamodel.Alignment(seqs);\r
-                                       bindjvvobj(jal, alignment);\r
-                                       jal.setDataset(jdataset);\r
-                                       /*jal.getDataset().setProvenance(\r
-                       getJalviewProvenance(dataset.getProvenance()));\r
-                       jal.setProvenance(\r
-                       getJalviewProvenance(alignment.getProvenance()));\r
-                                        */\r
-                                       //////////////////////////////////////////////\r
-                                       \r
-                                       \r
-                                       ////////////////////////////////////////////\r
-                                       ////LOAD ANNOTATIONS\r
-                                       ////////////////////\r
-                                       if (alignment.getAlignmentAnnotationsCount()>0)\r
-                                       {\r
-                                               AlignmentAnnotations[] an = alignment.getAlignmentAnnotations();\r
-                                               \r
-                                               for (j = 0; j < an.length; j++)\r
-                                               {\r
-                                                       boolean topaliBreakpoint = false;\r
-                                                       \r
-                                                       AnnotationElement[] ae = an[j].getAnnotationElement();\r
-                                                       jalview.datamodel.Annotation[] anot = getvObj2jv(ae);\r
-                                                       if (anot!=null) {\r
-                                                               // update or stay the same.\r
-                                                       } else {\r
-                                                               // new one\r
-                                                               anot=new jalview.datamodel.Annotation[jal.\r
-                                                                 getWidth()];\r
-                                                               bindjvvobj(anot, ae);\r
-                                try{\r
-                                       for (int aa = 0; aa < ae.length; aa++)\r
-                                       {\r
-                                               String dc = ae[aa].getDisplayCharacter()==null ? "dc" : ae[aa].getDisplayCharacter();\r
-                                               String desc = ae[aa].getDescription()==null ? "desc" : ae[aa].getDescription();\r
-                                               String ss = ae[aa].getSecondaryStructure()==null ? "ss" : ae[aa].getSecondaryStructure();\r
-                                               float value = ae[aa].getValue();\r
-                                               if(an[j].getGraph())\r
-                                               {\r
-                                                       dc = value+"";\r
-                                                       desc = value + "";\r
-                                               }\r
-                                               anot[ae[aa].getPosition()-1] = new jalview.datamodel.\r
-                                               Annotation(dc,desc,ss.charAt(0),value);\r
-                                                                       \r
-                                               if(desc.equals("TOPALi Partition Breakpoint"))\r
-                                                                               topaliBreakpoint = true;\r
-                                                                       \r
-                                       }\r
-                                }catch(Exception ex)\r
-                                {\r
-                                       ex.printStackTrace();\r
-                                       System.out.println("problem parsing annotations\n"+ex);}\r
-                                }\r
-                                                       jalview.datamodel.AlignmentAnnotation jaa = null;\r
-                                                       if (an[j].getGraph())\r
-                                                       {\r
-                                                               jaa = new jalview.datamodel.AlignmentAnnotation(an[j].getLabel(),\r
-                                                                               an[j].getDescription(), anot, 0, 0, 1);\r
-                                                       }\r
-                                                       else\r
-                                                       {\r
-                                                               String label = an[j].getLabel();\r
-                                                               if(topaliBreakpoint)\r
-                                                                       label = "TOPALi Partition Breakpoint";\r
-                                                               jaa = new jalview.datamodel.AlignmentAnnotation(label,\r
-                                                                               an[j].getDescription(), anot);\r
-                                                       }\r
-                                                       \r
-                                                       jal.addAnnotation(jaa);\r
-                                               }\r
-                                       }\r
-                                       /////////////////////////////////\r
-                                       \r
-                                       AlignFrame alignFrame = new AlignFrame(jal);\r
-                                       jalview.gui.Desktop.addInternalFrame(alignFrame, "VAMSAS LOAD",\r
-                                                       AlignFrame.NEW_WINDOW_WIDTH,\r
-                                                       AlignFrame.NEW_WINDOW_HEIGHT);\r
-                                       \r
-                                       //LOAD TREES\r
-                                       ///////////////////////////////////////\r
-                                       if (alignment.getTreeCount() > 0)\r
-                                       {\r
-                                               for (int t = 0; t < alignment.getTreeCount(); t++)\r
-                                               {\r
-                                                       Tree tree = alignment.getTree(t);\r
-                                                       \r
-                                                       alignFrame.ShowNewickTree(\r
-                                                                       new jalview.io.NewickFile(tree.getNewick(0).getContent()),\r
-                                                                       tree.getNewick(0).getTitle(),\r
-                                                                       600, 500,\r
-                                                                       t * 20 + 50, t * 20 + 50);\r
-                                               }\r
-                                       }\r
-                                       \r
-                                       \r
-                                       in.close();\r
-                                       jin.close();\r
-                               }\r
-                               catch (Exception ex)\r
-                               {\r
-                                       ex.printStackTrace();\r
-                               }\r
-                               \r
-                               \r
-                       }\r
-                       \r
-                       \r
-                       \r
-                       Provenance getVamsasProvenance(jalview.datamodel.Provenance jprov)\r
-                       {\r
-                               jalview.datamodel.ProvenanceEntry [] entries = null;\r
-                               \r
-                               \r
-                               Provenance prov = new Provenance();\r
-                               org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(\r
-                                               new java.util.Date());\r
-                               Entry provEntry;\r
-                               \r
-                               if(jprov!=null)\r
-                               {\r
-                                       entries = jprov.getEntries();\r
-                                       for (int i = 0; i < entries.length; i++)\r
-                                       {\r
-                                               provEntry = new Entry();\r
-                                               try\r
-                                               {\r
-                                                       date = new org.exolab.castor.types.Date(entries[i].getDate());\r
-                                               }\r
-                                               catch (Exception ex)\r
-                                               {\r
-                                                       ex.printStackTrace();\r
-                                                       \r
-                                                       date = new org.exolab.castor.types.Date(entries[i].getDate());\r
-                                               }\r
-                                               provEntry.setDate(date);\r
-                                               provEntry.setUser(entries[i].getUser());\r
-                                               provEntry.setAction(entries[i].getAction());\r
-                                               prov.addEntry(provEntry);\r
-                                       }\r
-                               }\r
-                               else\r
-                               {\r
-                                       provEntry = new Entry();\r
-                                       provEntry.setDate(date);\r
-                                       provEntry.setUser(System.getProperty("user.name"));\r
-                                       provEntry.setAction("Jalview");\r
-                                       prov.addEntry(provEntry);\r
-                               }\r
-                               \r
-                               return prov;\r
-                       }\r
-                       \r
-                       jalview.datamodel.Provenance getJalviewProvenance(Provenance prov)\r
-                       {\r
-                               \r
-                               jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();\r
-                               for (int i = 0; i < prov.getEntryCount(); i++)\r
-                               {\r
-                                       jprov.addEntry(\r
-                                                       prov.getEntry(i).getUser(),\r
-                                                       prov.getEntry(i).getAction(),\r
-                                                       prov.getEntry(i).getDate().toDate(),\r
-                                                       prov.getEntry(i).getId()\r
-                                       );\r
-                               }\r
-                               \r
-                               return jprov;\r
-                       }\r
-                       \r
-                       Provenance dummyProvenance()\r
-                       {\r
-                               Provenance prov = new Provenance();\r
-                               Entry entry = new Entry();\r
-                               entry.setAction("Jalview");\r
-                               entry.setDate(new org.exolab.castor.types.Date(new java.util.Date()));\r
-                               entry.setUser(System.getProperty("user.name"));\r
-                               prov.addEntry(entry);\r
-                               return prov;\r
-                       }\r
-                       \r
-               }\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+package jalview.io;
+
+import org.vamsas.client.Vobject;
+import org.vamsas.client.VorbaId;
+import org.vamsas.objects.core.*;
+import org.vamsas.objects.utils.DocumentStuff;
+import org.vamsas.test.simpleclient.ClientDoc;
+
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.*;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Vector;
+import java.util.jar.*;
+import org.exolab.castor.xml.*;
+import org.exolab.castor.mapping.Mapping;
+
+/*
+ * 
+ * static {
+ * org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty(
+ * "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer"); }
+ * 
+ */
+
+public class VamsasDatastore {
+  Entry provEntry = null;
+
+  // AlignViewport av;
+
+  org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(
+      new java.util.Date());
+
+  ClientDoc cdoc;
+
+  Hashtable vobj2jv;
+
+  Hashtable root2jv;
+
+  IdentityHashMap jv2vobj;
+
+  IdentityHashMap jv2root;
+
+  public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,
+      IdentityHashMap jv2vobj, Entry provEntry) {
+    this(cdoc, vobj2jv, jv2vobj, provEntry, new Hashtable(),
+        new IdentityHashMap());
+  }
+
+  public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,
+      IdentityHashMap jv2vobj, Entry provEntry, Hashtable root2jv,
+      IdentityHashMap jv2root) {
+    this.cdoc = cdoc;
+    this.vobj2jv = vobj2jv;
+    this.jv2vobj = jv2vobj;
+    this.root2jv = root2jv;
+    this.jv2root = jv2root;
+    this.provEntry = provEntry;
+  }
+
+  /*
+   * public void storeJalview(String file, AlignFrame af) { try { // 1. Load the
+   * mapping information from the file Mapping map = new
+   * Mapping(getClass().getClassLoader()); java.net.URL url =
+   * getClass().getResource("/jalview_mapping.xml"); map.loadMapping(url); // 2.
+   * Unmarshal the data // Unmarshaller unmar = new Unmarshaller();
+   * //unmar.setIgnoreExtraElements(true); //unmar.setMapping(map); // uni =
+   * (UniprotFile) unmar.unmarshal(new FileReader(file)); // 3. marshal the data
+   * with the total price back and print the XML in the console Marshaller
+   * marshaller = new Marshaller( new FileWriter(file) );
+   * 
+   * marshaller.setMapping(map); marshaller.marshal(af); } catch (Exception e) {
+   * e.printStackTrace(); } }
+   * 
+   * 
+   */
+  /**
+   * @return the Vobject bound to Jalview datamodel object
+   */
+  protected Vobject getjv2vObj(Object jvobj) {
+    if (jv2vobj.containsKey(jvobj))
+      return cdoc.getObject(((VorbaId) jv2vobj.get(jvobj)));
+    return null;
+  }
+
+  /**
+   * 
+   * @param vobj
+   * @return Jalview datamodel object bound to the vamsas document object
+   */
+  protected Object getvObj2jv(org.vamsas.client.Vobject vobj) {
+    VorbaId id = vobj.getVorbaId();
+    if (id == null)
+    {
+      id = cdoc.registerObject(vobj);
+      Cache.log
+      .debug("Registering new object and returning null for getvObj2jv");
+      return null;
+    }
+    if (vobj2jv.containsKey(vobj.getVorbaId()))
+      return vobj2jv.get(id);
+    return null;
+  }
+
+  protected void bindjvvobj(Object jvobj, org.vamsas.client.Vobject vobj) {
+    VorbaId id = vobj.getVorbaId();
+    if (id == null)
+    {
+      id = cdoc.registerObject(vobj);
+    }
+    if (vobj2jv.containsKey(vobj.getVorbaId()) || jv2vobj.containsKey(jvobj))
+    {
+      Cache.log.error("Duplicate object binding!");
+    }
+    else
+    {
+      vobj2jv.put(vobj.getVorbaId(), jvobj);// JBPNote - better implementing a
+      // hybrid invertible hash.
+      jv2vobj.put(jvobj, vobj.getVorbaId());
+    }
+  }
+
+  /**
+   * put the alignment viewed by AlignViewport into cdoc.
+   * 
+   * @param av
+   */
+  public void storeVAMSAS(AlignViewport av) {
+    try
+    {
+      jalview.datamodel.AlignmentI jal = av.getAlignment();
+      boolean nw = false;
+      VAMSAS root = null; // will be resolved based on Dataset Parent.
+      // /////////////////////////////////////////
+      // SAVE THE DATASET
+      if (jal.getDataset() == null)
+      {
+        Cache.log.warn("Creating new dataset for an alignment.");
+        jal.setDataset(null);
+      }
+      DataSet dataset = (DataSet) getjv2vObj(jal.getDataset());
+      if (dataset == null)
+      {
+        root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying.
+        dataset = new DataSet();
+        root.addDataSet(dataset);
+        bindjvvobj(jal.getDataset(), dataset);
+        dataset.setProvenance(dummyProvenance());
+        dataset.getProvenance().addEntry(provEntry);
+        nw = true;
+      }
+      else
+      {
+        root = (VAMSAS) dataset.getV_parent();
+      }
+      // update dataset
+      Sequence sequence;
+      DbRef dbref;
+      // set new dataset and alignment sequences based on alignment Nucleotide
+      // flag.
+      // this *will* break when alignment contains both nucleotide and amino
+      // acid sequences.
+      String dict = jal.isNucleotide() ? org.vamsas.objects.utils.SymbolDictionary.STANDARD_NA
+          : org.vamsas.objects.utils.SymbolDictionary.STANDARD_AA;
+      for (int i = 0; i < jal.getHeight(); i++)
+      {
+        SequenceI sq = jal.getSequenceAt(i).getDatasetSequence(); // only insert
+        // referenced
+        // sequences
+        // to dataset.
+        sequence = (Sequence) getjv2vObj(sq);
+        if (sequence == null)
+        {
+          sequence = new Sequence();
+          bindjvvobj(sq, sequence);
+          sq.setVamsasId(sequence.getVorbaId().getId());
+          sequence.setSequence(sq.getSequence());
+          sequence.setDictionary(dict);
+          sequence.setName(jal.getDataset().getSequenceAt(i).getName());
+          sequence.setStart(jal.getDataset().getSequenceAt(i).getStart());
+          sequence.setEnd(jal.getDataset().getSequenceAt(i).getEnd());
+          dataset.addSequence(sequence);
+        }
+        else
+        {
+          // verify principal attributes. and update any new
+          // features/references.
+          System.out.println("update dataset sequence object.");
+        }
+        if (sq.getSequenceFeatures() != null)
+        {
+          int sfSize = sq.getSequenceFeatures().length;
+
+          for (int sf = 0; sf < sfSize; sf++)
+          {
+            jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) sq
+            .getSequenceFeatures()[sf];
+
+            DataSetAnnotations dsa = (DataSetAnnotations) getjv2vObj(feature);
+            if (dsa == null)
+            {
+              dsa = (DataSetAnnotations) getDSAnnotationFromJalview(
+                  new DataSetAnnotations(), feature);
+              if (dsa.getProvenance() == null)
+              {
+                dsa.setProvenance(new Provenance());
+              }
+              addProvenance(dsa.getProvenance(), "created"); // JBPNote - need
+              // to update
+              dsa.setSeqRef(sequence);
+              bindjvvobj(feature, dsa);
+              dataset.addDataSetAnnotations(dsa);
+            }
+            else
+            {
+              // todo: verify and update dataset annotations for sequence
+              System.out.println("update dataset sequence annotations.");
+            }
+          }
+        }
+
+        if (sq.getDBRef() != null)
+        {
+          DBRefEntry[] entries = sq.getDBRef();
+          jalview.datamodel.DBRefEntry dbentry;
+          for (int db = 0; db < entries.length; db++)
+          {
+            dbentry = entries[db];
+            dbref = (DbRef) getjv2vObj(dbentry);
+            if (dbref == null)
+            {
+              dbref = new DbRef();
+              bindjvvobj(dbentry, dbref);
+              dbref.setAccessionId(dbentry.getAccessionId());
+              dbref.setSource(dbentry.getSource());
+              dbref.setVersion(dbentry.getVersion());
+              /*
+               * TODO: Maps are not yet supported by Jalview. Map vMap = new
+               * Map(); vMap.set dbref.addMap(vMap);
+               */
+              sequence.addDbRef(dbref);
+            }
+            else
+            {
+              // TODO: verify and update dbrefs in vamsas document
+              // there will be trouble when a dataset sequence is modified to
+              // contain more residues than were originally referenced - we must
+              // then make a number of dataset sequence entries
+              System.out
+              .println("update dataset sequence database references.");
+            }
+          }
+
+        }
+      }
+      // dataset.setProvenance(getVamsasProvenance(jal.getDataset().getProvenance()));
+      // ////////////////////////////////////////////
+
+      // ////////////////////////////////////////////
+      // Save the Alignments
+
+      Alignment alignment = (Alignment) getjv2vObj(av); // this is so we can get the alignviewport back 
+      if (alignment == null)
+      {
+        alignment = new Alignment();
+        bindjvvobj(jal, alignment);
+        if (alignment.getProvenance() == null)
+          alignment.setProvenance(new Provenance());
+        addProvenance(alignment.getProvenance(), "added"); // TODO: insert some
+        // sensible source
+        // here
+        dataset.addAlignment(alignment);
+        alignment.setGapChar(String.valueOf(av.getGapCharacter()));
+        AlignmentSequence alseq = null;
+        for (int i = 0; i < jal.getHeight(); i++)
+        {
+          alseq = new AlignmentSequence();
+          // TODO: VAMSAS: translate lowercase symbols to annotation ?
+          alseq.setSequence(jal.getSequenceAt(i).getSequence());
+          alseq.setName(jal.getSequenceAt(i).getName());
+          alseq.setStart(jal.getSequenceAt(i).getStart());
+          alseq.setEnd(jal.getSequenceAt(i).getEnd());
+          alseq.setRefid(getjv2vObj(jal.getSequenceAt(i).getDatasetSequence()));
+          alignment.addAlignmentSequence(alseq);
+          bindjvvobj(jal.getSequenceAt(i), alseq);
+        }
+      }
+      else
+      {
+        // todo: verify and update mutable alignment props.
+        if (alignment.getModifiable())
+        {
+          System.out.println("update alignment in document.");
+        }
+        else
+        {
+          System.out
+          .println("update edited alignment to new alignment in document.");
+        }
+      }
+      // ////////////////////////////////////////////
+      // SAVE Alignment Sequence Features
+      for (int i = 0, iSize = alignment.getAlignmentSequenceCount(); i < iSize; i++)
+      {
+        AlignmentSequence valseq;
+        SequenceI alseq = (SequenceI) getvObj2jv(valseq = alignment
+            .getAlignmentSequence(i));
+        if (alseq != null && alseq.getSequenceFeatures() != null)
+        {
+          jalview.datamodel.SequenceFeature[] features = alseq
+          .getSequenceFeatures();
+          for (int f = 0; f < features.length; f++)
+          {
+            if (features[f] != null)
+            {
+              AlignmentSequenceAnnotation valseqf = (AlignmentSequenceAnnotation) getjv2vObj(features[i]);
+              if (valseqf == null)
+              {
+
+                valseqf = (AlignmentSequenceAnnotation) getDSAnnotationFromJalview(
+                    new AlignmentSequenceAnnotation(), features[i]);
+                if (valseqf.getProvenance() == null)
+                {
+                  valseqf.setProvenance(new Provenance());
+                }
+                addProvenance(valseqf.getProvenance(), "created"); // JBPNote -
+                // need to
+                // update
+                bindjvvobj(features[i], valseqf);
+                valseq.addAlignmentSequenceAnnotation(valseqf);
+              }
+            }
+
+          }
+        }
+      }
+
+      // ////////////////////////////////////////////
+      // SAVE ANNOTATIONS
+      if (jal.getAlignmentAnnotation() != null)
+      {
+        jalview.datamodel.AlignmentAnnotation[] aa = jal
+        .getAlignmentAnnotation();
+        java.util.HashMap AlSeqMaps = new HashMap(); // stores int maps from
+        // alignment columns to
+        // sequence positions.
+        for (int i = 0; i < aa.length; i++)
+        {
+          if (aa[i] == null || isJalviewOnly(aa[i]))
+          {
+            continue;
+          }
+          if (aa[i].sequenceRef != null)
+          {
+            org.vamsas.objects.core.AlignmentSequence alsref = (org.vamsas.objects.core.AlignmentSequence) getjv2vObj(aa[i].sequenceRef);
+            org.vamsas.objects.core.AlignmentSequenceAnnotation an = (org.vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj(aa[i]);
+            int[] gapMap = null;
+            if (AlSeqMaps.containsKey(aa[i].sequenceRef))
+            {
+              gapMap = (int[]) AlSeqMaps.get(aa[i].sequenceRef);
+            }
+            else
+            {
+              gapMap = new int[aa[i].sequenceRef.getLength()];
+              // map from alignment position to sequence position.
+              int[] sgapMap = aa[i].sequenceRef.gapMap();
+              for (int a = 0; a < sgapMap.length; a++)
+                gapMap[sgapMap[a]] = a;
+            }
+            if (an == null)
+            {
+              an = new org.vamsas.objects.core.AlignmentSequenceAnnotation();
+              alsref.addAlignmentSequenceAnnotation(an);
+              // LATER: much of this is verbatim from the alignmentAnnotation
+              // method below. suggests refactoring to make rangeAnnotation the
+              // base class
+              an.setDescription(aa[i].description);
+              if (aa[i].graph > 0)
+                an.setGraph(true); // aa[i].graph);
+              an.setLabel(aa[i].label);
+              an.setProvenance(dummyProvenance()); // get provenance as user
+              // created, or jnet, or
+              // something else.
+              an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
+              // originally we
+              // were going to
+              // store
+              // graphGroup in
+              // the Jalview
+              // specific
+              // bits.
+              AnnotationElement ae;
+              for (int a = 0; a < aa[i].annotations.length; a++)
+              {
+                if (aa[i].annotations[a] == null)
+                {
+                  continue;
+                }
+
+                ae = new AnnotationElement();
+                ae.setDescription(aa[i].annotations[a].description);
+                ae.addGlyph(new Glyph());
+                ae.getGlyph(0)
+                .setContent(aa[i].annotations[a].displayCharacter); // assume
+                // jax-b
+                // takes
+                // care
+                // of
+                // utf8
+                // translation
+                ae.addValue(aa[i].annotations[a].value);
+                ae.setPosition(gapMap[a]); // position w.r.t. AlignmentSequence
+                // symbols
+                if (aa[i].annotations[a].secondaryStructure != ' ')
+                {
+                  // we only write an annotation where it really exists.
+                  Glyph ss = new Glyph();
+                  ss
+                  .setDict(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
+                  ss.setContent(String
+                      .valueOf(aa[i].annotations[a].secondaryStructure));
+                  ae.addGlyph(ss);
+                }
+                an.addAnnotationElement(ae);
+              }
+            }
+            else
+            {
+              // update reference sequence Annotation
+              if (an.getModifiable())
+              {
+                // verify existing alignment sequence annotation is up to date
+                System.out.println("update alignment sequence annotation.");
+              }
+              else
+              {
+                // verify existing alignment sequence annotation is up to date
+                System.out
+                .println("make new alignment sequence annotation if modification has happened.");
+              }
+            }
+          }
+          else
+          {
+            // add Alignment Annotation
+            org.vamsas.objects.core.AlignmentAnnotation an = (org.vamsas.objects.core.AlignmentAnnotation) getjv2vObj(aa[i]);
+            if (an == null)
+            {
+              an = new org.vamsas.objects.core.AlignmentAnnotation();
+              an.setDescription(aa[i].description);
+              alignment.addAlignmentAnnotation(an);
+              if (aa[i].graph > 0)
+                an.setGraph(true); // aa[i].graph);
+              an.setLabel(aa[i].label);
+              an.setProvenance(dummyProvenance());
+              an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
+              // originally we
+              // were going to
+              // store
+              // graphGroup in
+              // the Jalview
+              // specific
+              // bits.
+
+              AnnotationElement ae;
+
+              for (int a = 0; a < aa[i].annotations.length; a++)
+              {
+                if ((aa[i] == null) || (aa[i].annotations[a] == null))
+                {
+                  continue;
+                }
+
+                ae = new AnnotationElement();
+                ae.setDescription(aa[i].annotations[a].description);
+                ae.addGlyph(new Glyph());
+                ae.getGlyph(0)
+                .setContent(aa[i].annotations[a].displayCharacter); // assume
+                // jax-b
+                // takes
+                // care
+                // of
+                // utf8
+                // translation
+                ae.addValue(aa[i].annotations[a].value);
+                ae.setPosition(a);
+                if (aa[i].annotations[a].secondaryStructure != ' ')
+                {
+                  Glyph ss = new Glyph();
+                  ss
+                  .setDict(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
+                  ss.setContent(String
+                      .valueOf(aa[i].annotations[a].secondaryStructure));
+                  ae.addGlyph(ss);
+                }
+                an.addAnnotationElement(ae);
+              }
+              if (aa[i].editable) {
+                //an.addProperty(newProperty("jalview:editable", null, "true"));
+                an.setModifiable(true);
+              }
+              if (aa[i].graph!=jalview.datamodel.AlignmentAnnotation.NO_GRAPH) {
+                an.setGraph(true);
+                an.setGroup(Integer.toString(aa[i].graphGroup));
+                an.addProperty(newProperty("jalview:graphType",null,
+                    ((aa[i].graph==jalview.datamodel.AlignmentAnnotation.BAR_GRAPH) ? "BAR_GRAPH" : "LINE_GRAPH")));
+
+                /** and on and on.. 
+                 vProperty=new Property();
+                  vProperty.setName("jalview:graphThreshhold");
+                  vProperty.setContent(aa[i].threshold);
+                 */
+
+              }
+            }
+            else
+            {
+              if (an.getModifiable())
+              {
+                // verify annotation - update (perhaps)
+                Cache.log.info("update alignment sequence annotation. not yet implemented.");
+              }
+              else
+              {
+                // verify annotation - update (perhaps)
+                Cache.log.info("updated alignment sequence annotation added.");
+              }
+            }
+          }
+        }
+      }
+      // /////////////////////////////////////////////////////
+
+      // //////////////////////////////////////////////
+      // /SAVE THE TREES
+      // /////////////////////////////////
+      // FIND ANY ASSOCIATED TREES
+      if (Desktop.desktop != null)
+      {
+        javax.swing.JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+
+        for (int t = 0; t < frames.length; t++)
+        {
+          if (frames[t] instanceof TreePanel)
+          {
+            TreePanel tp = (TreePanel) frames[t];
+
+            if (tp.getAlignment() == jal)
+            {
+              // LATER: can recover alignment and Vamsas Alignment for an
+              // associated tree using the getjv2vObj() so we could pass through
+              // the tree list just once rather than many times
+
+              Tree tree = (Tree) getjv2vObj(tp);
+              if (tree == null)
+              {
+                tree = new Tree();
+                bindjvvobj(tp, tree);
+                tree.setTitle(tp.getTitle());
+                Newick newick = new Newick();
+                // TODO: translate sequenceI to leaf mappings to vamsas
+                // references - see tree specification in schema.
+                newick.setContent(tp.getTree().toString());
+                newick.setTitle(tp.getTitle());
+                tree.addNewick(newick);
+                tree.setProvenance(makeTreeProvenance(jal, tp));
+                alignment.addTree(tree);
+              }
+              else
+              {
+                if (tree.getModifiable())
+                {
+                  // verify any changes.
+                  System.out.println("Update tree in document.");
+                }
+                else
+                {
+                  System.out
+                  .println("Add modified tree as new tree in document.");
+                }
+              }
+            }
+          }
+        }
+      }
+      // Store Jalview specific stuff in the Jalview appData
+      // not implemented in the SimpleDoc interface.
+    }
+
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+  }
+
+  private Property newProperty(String name, String type, String content) {
+    Property vProperty=new Property();
+    vProperty.setName(name);
+    if (type!=null)
+      vProperty.setType(type);
+    vProperty.setContent(content);
+    return vProperty;
+  }
+
+  /**
+   * correctly create a RangeAnnotation from a jalview sequence feature
+   * 
+   * @param dsa
+   *          (typically DataSetAnnotations or AlignmentSequenceAnnotation)
+   * @param feature
+   *          (the feature to be mapped from)
+   * @return
+   */
+  private RangeAnnotation getDSAnnotationFromJalview(RangeAnnotation dsa,
+      SequenceFeature feature) {
+    dsa.setType(feature.getType());
+    Seg vSeg = new Seg();
+    vSeg.setStart(feature.getBegin());
+    vSeg.setEnd(feature.getEnd());
+    dsa.addSeg(vSeg);
+    dsa.setDescription(feature.getDescription());
+    dsa.setStatus(feature.getStatus());
+    if (feature.links != null && feature.links.size() > 0)
+    {
+      for (int i = 0, iSize = feature.links.size(); i < iSize; i++)
+      {
+        String link = (String) feature.links.elementAt(i);
+        int sep = link.indexOf('|');
+        if (sep > -1)
+        {
+          Link vLink = new Link();
+          if (sep > 0)
+            vLink.setContent(link.substring(0, sep - 1));
+          else
+            vLink.setContent("");
+          vLink.setHref(link.substring(sep + 1)); // TODO: validate href.
+          dsa.addLink(vLink);
+        }
+      }
+    }
+    dsa.setGroup(feature.getFeatureGroup());
+    return dsa;
+  }
+
+  /**
+   * correctly creates provenance for trees calculated on an alignment by
+   * jalview.
+   * 
+   * @param jal
+   * @param tp
+   * @return
+   */
+  private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp) {
+    Input vInput = new Input();
+    // LATER: check to see if tree input data is contained in this alignment -
+    // or just correctly resolve the tree's seqData to the correct alignment in
+    // the document.
+    vInput.setObjRef(getjv2vObj(jal));
+    Provenance prov = dummyProvenance();
+    if (tp.getTree().hasOriginalSequenceData())
+    {
+      prov.getEntry(0).addInput(vInput);
+      int ranges[] = tp.getTree().seqData.getVisibleContigs();
+      for (int r = 0; r < ranges.length; r += 2)
+      {
+        Seg visSeg = new Seg();
+        visSeg.setStart(ranges[r]);
+        visSeg.setEnd(ranges[r + 1]);
+        visSeg.setInclusive(true);
+        vInput.addSeg(visSeg);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * 
+   * @param tp
+   * @return Object[] { AlignmentView, AlignmentI - reference alignment for
+   *         input }
+   */
+  private Object[] recoverInputData(Provenance tp) {
+    for (int pe = 0; pe < tp.getEntryCount(); pe++)
+    {
+      if (tp.getEntry(pe).getInputCount() > 0)
+      {
+        if (tp.getEntry(pe).getInputCount() > 1)
+          Cache.log.warn("Ignoring additional input spec in provenance entry "
+              + tp.getEntry(pe).toString());
+        // LATER: deal sensibly with multiple inputs.
+        Input vInput = tp.getEntry(pe).getInput(0);
+        if (vInput.getObjRef() instanceof org.vamsas.objects.core.Alignment)
+        {
+          // recover an AlignmentView for the input data
+          AlignmentI jal = (AlignmentI) getvObj2jv((org.vamsas.client.Vobject) vInput
+              .getObjRef());
+          jalview.datamodel.CigarArray view = jal.getCompactAlignment();
+          int from = 0, to = jal.getWidth();
+          for (int r = 0, s = vInput.getSegCount(); r < s; r++)
+          {
+            Seg visSeg = vInput.getSeg(r);
+            int se[] = getSegRange(visSeg,true); // jalview doesn't do bidirection alignments yet.
+            if (to > se[1])
+              Cache.log.warn("Ignoring invalid segment in InputData spec.");
+            else
+            {
+              if (se[0] > from)
+              {
+                view.deleteRange(from, se[0] - 1);
+              }
+              from = se[1] + 1;
+            }
+          }
+          if (from < to)
+          {
+            view.deleteRange(from, to); // final deletion - TODO: check off by
+            // one for to
+          }
+          return new Object[] { new AlignmentView(view), jal };
+        }
+      }
+    }
+    Cache.log.debug("Returning null for input data recovery from provenance.");
+    return null;
+  }
+
+  /**
+   * get start<end range of segment, adjusting for inclusivity flag and
+   * polarity.
+   *  
+   * @param visSeg
+   * @param ensureDirection when true - always ensure start is less than end.
+   * @return int[] { start, end, direction} where direction==1 for range running from end to start.
+   */
+  private int[] getSegRange(Seg visSeg, boolean ensureDirection) {
+    boolean incl = visSeg.getInclusive();
+    // adjust for inclusive flag.
+    int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
+    // region.
+    int start = visSeg.getStart() + (incl ? 0 : pol);
+    int end = visSeg.getEnd() + (incl ? -pol : 0);
+    if (ensureDirection && pol==-1)
+    {
+      // jalview doesn't deal with inverted ranges, yet.
+      int t = end;
+      end = start;
+      start = t;
+    }
+    return new int[] { start, end, pol<0 ? 1 : 0 };
+  }
+
+  /**
+   * 
+   * @param annotation
+   * @return true if annotation is not to be stored in document
+   */
+  private boolean isJalviewOnly(AlignmentAnnotation annotation) {
+    return annotation.label.equals("Quality")
+    || annotation.label.equals("Conservation")
+    || annotation.label.equals("Consensus");
+  }
+  /**
+   * This will return the first AlignFrame viewing AlignViewport av.
+   * It will break if there are more than one AlignFrames viewing a particular av.
+   * This also shouldn't be in the io package.
+   * @param av
+   * @return alignFrame for av
+   */
+  public AlignFrame getAlignFrameFor(AlignViewport av) {
+    if (Desktop.desktop != null)
+    {
+      javax.swing.JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+
+      for (int t = 0; t < frames.length; t++)
+      {
+        if (frames[t] instanceof AlignFrame) {
+          if (((AlignFrame) frames[t]).getViewport()==av)
+          return (AlignFrame) frames[t];
+        }
+      }
+    }
+    return null;
+  }
+  public void updateToJalview() {
+    VAMSAS _roots[] = cdoc.getVamsasRoots();
+
+    for (int _root = 0; _root<_roots.length; _root++) {
+      VAMSAS root = _roots[_root];
+      boolean newds=false;
+      for (int _ds=0,_nds=root.getDataSetCount(); _ds<_nds; _ds++) {
+        // ///////////////////////////////////
+        // ///LOAD DATASET
+        DataSet dataset = root.getDataSet(_ds);
+        int i, iSize = dataset.getSequenceCount();
+        Vector dsseqs;
+        jalview.datamodel.Alignment jdataset = (jalview.datamodel.Alignment) getvObj2jv(dataset);
+        int jremain=0;
+        if (jdataset==null) {
+          Cache.log.debug("Initialising new jalview dataset fields");
+          newds=true;
+          dsseqs=new Vector();
+        } else {
+          Cache.log.debug("Update jalview dataset from vamsas.");
+          jremain=jdataset.getHeight();
+          dsseqs=jdataset.getSequences();
+        }
+
+        // TODO: test sequence merging - we preserve existing non vamsas
+        // sequences but add in any new vamsas ones, and don't yet update any
+        // sequence attributes
+        for (i = 0; i < iSize ; i++)
+        {
+          Sequence vdseq = dataset.getSequence(i);
+          jalview.datamodel.SequenceI dsseq = (SequenceI) getvObj2jv(vdseq);
+          if (dsseq!=null) {
+            if (!dsseq.getSequence().equals(vdseq.getSequence()))
+              throw new Error("Broken! - mismatch of dataset sequence and jalview internal dataset sequence.");
+            jremain--;
+          } else {
+            dsseq = new jalview.datamodel.Sequence(
+                dataset.getSequence(i).getName(),
+                dataset.getSequence(i).getSequence(),
+                dataset.getSequence(i).getStart(),
+                dataset.getSequence(i).getEnd()  );
+            bindjvvobj(dsseq, dataset.getSequence(i));
+            dsseq.setVamsasId(dataset.getSequence(i).getVorbaId().getId());
+            dsseqs.add(dsseq);
+          }
+          if (vdseq.getDbRefCount()>0) {
+            DbRef [] dbref = vdseq.getDbRef();
+            for(int db=0; db<dbref.length; db++)
+            {
+              jalview.datamodel.DBRefEntry dbr=(jalview.datamodel.DBRefEntry) getvObj2jv(dbref[db]);
+              if (dbr==null) {
+                // add new dbref
+                dsseq.addDBRef(dbr= new jalview.datamodel.DBRefEntry
+                    (
+                        dbref[db].getSource().toString(),
+                        dbref[db].getVersion().toString(),
+                        dbref[db].getAccessionId().toString()));
+                bindjvvobj(dbr, dbref[db]);
+              }
+            }
+          }
+        }
+
+        if (newds) {
+          SequenceI[] seqs = new SequenceI[dsseqs.size()];
+          for (i=0,iSize=dsseqs.size(); i<iSize; i++) {
+            seqs[i]=(SequenceI) dsseqs.elementAt(i);
+            dsseqs.setElementAt(null, i);
+          }
+          jdataset = new jalview.datamodel.Alignment(seqs);
+          Cache.log.debug("New vamsas dataset imported into jalview.");
+          bindjvvobj(jdataset, dataset);
+        }
+        // ////////
+        // add any new dataset sequence feature annotations
+        if (dataset.getDataSetAnnotations() != null) {
+          for (int dsa = 0; dsa < dataset.getDataSetAnnotationsCount(); dsa++) {
+            DataSetAnnotations dseta=dataset.getDataSetAnnotations(dsa);
+            SequenceI dsSeq=(SequenceI) getvObj2jv((Vobject) dseta.getSeqRef());
+            if (dsSeq==null) {
+              jalview.bin.Cache.log.warn("Couldn't resolve jalview sequenceI for dataset object reference "+((Vobject)dataset.getDataSetAnnotations(dsa).getSeqRef()).getVorbaId().getId());
+            } else {
+              if (dseta.getAnnotationElementCount()==0) {
+                jalview.datamodel.SequenceFeature sf=(jalview.datamodel.SequenceFeature) getvObj2jv(dseta);
+                if (sf==null) {
+                  dsSeq.addSequenceFeature(sf=getJalviewSeqFeature(dseta));
+                  bindjvvobj(sf, dseta);
+                }
+              } else {
+                // TODO: deal with alignmentAnnotation style annotation
+                // appearing on dataset sequences.
+                // JBPNote: we could just add them to all alignments but
+                // that may complicate cross references in the jalview
+                // datamodel
+                Cache.log.warn("Ignoring dataset annotation with annotationElements. Not yet supported in jalview.");
+              }
+            }
+          }
+        }
+
+        if (dataset.getAlignmentCount()>0) {
+          // LOAD ALIGNMENTS from DATASET 
+
+          for (int al=0,nal=dataset.getAlignmentCount(); al<nal; al++) {
+            org.vamsas.objects.core.Alignment alignment = dataset.getAlignment(al);
+            AlignViewport av = (AlignViewport) getvObj2jv(alignment);
+            jalview.datamodel.AlignmentI jal=null;
+            if (av!=null)
+              jal = av.getAlignment(); 
+            iSize = alignment.getAlignmentSequenceCount();
+            boolean newal=(jal==null) ? true : false;
+            Vector newasAnnots=new Vector();
+            char gapChar=' '; // default for new alignments read in from the document
+            if (jal!=null) {
+              dsseqs=jal.getSequences(); // for merge/update
+              gapChar=jal.getGapCharacter();
+            } else {
+              dsseqs=new Vector();
+            }
+            char valGapchar=alignment.getGapChar().charAt(0);
+            for (i = 0; i < iSize; i++)
+            {
+              AlignmentSequence valseq = alignment.getAlignmentSequence(i);
+              jalview.datamodel.SequenceI alseq = (SequenceI) getvObj2jv(valseq);
+              if (alseq!=null) {
+                //TODO: upperCase/LowerCase situation here ? do we allow it ?
+                //if (!alseq.getSequence().equals(valseq.getSequence())) {
+                // throw new Error("Broken! - mismatch of dataset sequence and jalview internal dataset sequence.");
+                if (Cache.log.isDebugEnabled())
+                  Cache.log.debug("Updating apparently edited sequence "+alseq.getName());
+                // this might go *horribly* wrong
+                alseq.setSequence(new String(valseq.getSequence()).replace(valGapchar, gapChar));
+                jremain--;
+              } else {
+                alseq = new jalview.datamodel.Sequence(
+                    valseq.getName(),
+                    valseq.getSequence().replace(valGapchar, gapChar),
+                    valseq.getStart(),
+                    valseq.getEnd()  );
+                alseq.setDatasetSequence((SequenceI)getvObj2jv((Vobject)valseq.getRefid())); // exceptions if AlignemntSequence reference isn't a simple SequenceI
+                bindjvvobj(alseq, valseq);
+                alseq.setVamsasId(valseq.getVorbaId().getId());
+                dsseqs.add(alseq);
+              }
+              if (valseq.getAlignmentSequenceAnnotationCount()>0) {
+                AlignmentSequenceAnnotation[] vasannot=valseq.getAlignmentSequenceAnnotation();
+                for (int a=0; a<vasannot.length; a++) {
+                  jalview.datamodel.AlignmentAnnotation asa = (jalview.datamodel.AlignmentAnnotation) getvObj2jv(vasannot[a]); // TODO: 1:many jalview alignment sequence annotations
+                  if (asa==null) {
+                    int se[] = getBounds(vasannot[a]);
+                    asa = getjAlignmentAnnotation(jal, vasannot[a]);
+                    asa.createSequenceMapping(alseq, se[0], false); // TODO: verify that positions in alseqAnnotation correspond to ungapped residue positions.
+                    bindjvvobj(asa, vasannot[a]);
+                    newasAnnots.add(asa);
+                  } else {
+                    // update existing annotation - can do this in place
+                    if (vasannot[a].getModifiable()) {
+                      Cache.log.info("UNIMPLEMENTED: not recovering user modifiable sequence alignment annotation");
+                      // TODO: should at least replace with new one - otherwise things will break
+                      // basically do this:
+                      // int se[] = getBounds(vasannot[a]);
+                      // asa.update(getjAlignmentAnnotation(jal, vasannot[a])); //  update from another annotation object in place.
+                      // asa.createSequenceMapping(alseq, se[0], false); 
+                      
+                    }
+                  }
+                }
+              }
+            }
+            if (jal==null) {
+              SequenceI[] seqs = new SequenceI[dsseqs.size()];
+              for (i=0,iSize=dsseqs.size(); i<iSize; i++) {
+                seqs[i]=(SequenceI) dsseqs.elementAt(i);
+                dsseqs.setElementAt(null, i);
+              }
+              jal = new jalview.datamodel.Alignment(seqs);
+              Cache.log.debug("New vamsas alignment imported into jalview "+alignment.getVorbaId().getId());
+              bindjvvobj(jal, alignment);
+              jal.setDataset(jdataset);
+            }
+            if (newasAnnots!=null && newasAnnots.size()>0) {
+              // Add the new sequence annotations in to the alignment.
+              for (int an=0,anSize=newasAnnots.size(); an<anSize; an++) {
+                jal.addAnnotation((AlignmentAnnotation) newasAnnots.elementAt(an));
+                // TODO: check if anything has to be done - like calling adjustForAlignment or something.
+                newasAnnots.setElementAt(null, an);
+              }
+              newasAnnots=null;
+            }
+            // //////////////////////////////////////////
+            // //LOAD ANNOTATIONS FOR THE ALIGNMENT
+            // ////////////////////////////////////
+            if (alignment.getAlignmentAnnotationCount()>0)
+            {
+              org.vamsas.objects.core.AlignmentAnnotation[] an = alignment.getAlignmentAnnotation();
+
+              for (int j = 0; j < an.length; j++)
+              {
+                jalview.datamodel.AlignmentAnnotation jan=(jalview.datamodel.AlignmentAnnotation) getvObj2jv(an[j]);
+                if (jan!=null) {
+                  // update or stay the same.
+                  // TODO: should at least replace with a new one - otherwise things will break
+                  // basically do this:
+                  // jan.update(getjAlignmentAnnotation(jal, an[a])); //  update from another annotation object in place.
+                  
+                  Cache.log.debug("update from vamsas alignment annotation to existing jalview alignment annotation.");
+                  if (an[i].getModifiable()) {
+                    // TODO: user defined annotation is totally mutable... - so load it up or throw away if locally edited.
+                    Cache.log.info("NOT IMPLEMENTED - Recovering user-modifiable annotation - yet...");
+                  }
+                  // TODO: compare annotation element rows
+                  // TODO: compare props.
+                } else {
+                  jan = getjAlignmentAnnotation(jal, an[j]);
+                  jal.addAnnotation(jan);
+                  bindjvvobj(jan, an[j]);
+                }
+              }
+            }
+            AlignFrame alignFrame;
+            if (av==null) {
+                // ///////////////////////////////
+              // construct alignment view
+              alignFrame = new AlignFrame(jal);
+              av=alignFrame.getViewport();
+              // TODO: automatically create meaningful title for a vamsas alignment using its provenance.
+              jalview.gui.Desktop.addInternalFrame(alignFrame, alignment.getProvenance().getEntry(alignment.getProvenance().getEntryCount()-1).toString(),
+                  AlignFrame.NEW_WINDOW_WIDTH,
+                  AlignFrame.NEW_WINDOW_HEIGHT);
+            } else {
+              // find the alignFrame for jal.
+              // TODO: fix this so we retrieve the alignFrame handing av *directly*
+              alignFrame=getAlignFrameFor(av);
+            }
+            // LOAD TREES
+            // /////////////////////////////////////
+            if (alignment.getTreeCount() > 0)
+            {
+              
+              for (int t = 0; t < alignment.getTreeCount(); t++)
+              {
+                Tree tree = alignment.getTree(t);
+                TreePanel tp=(TreePanel) getvObj2jv(tree);
+                if (tp!=null) {
+                  Cache.log.info("Update from vamsas document to alignment associated tree not implemented yet.");
+                } else {
+                  // make a new tree
+                  Object[] idata = this.recoverInputData(tree.getProvenance());
+                  try {
+                    
+                    tp = alignFrame.ShowNewickTree(
+                        new jalview.io.NewickFile(tree.getNewick(0).getContent()),
+                        tree.getNewick(0).getTitle(),
+                        600, 500,
+                        t * 20 + 50, t * 20 + 50);
+                    bindjvvobj(tp, tree);
+                    if (idata!=null) {
+                      // add it to tp.
+                      check jalview_2xml that it isn't an out of date version.
+                    }
+                        
+                  } catch (Exception e) {
+                    Cache.log.warn("Problems parsing treefile '"+tree.getNewick(0).getContent()+"'",e);
+                  }
+                }
+              }
+            }
+
+          }
+        }
+      }
+    }
+  }
+  // bitfields - should be a template in j1.5
+  private static int HASSECSTR=0;
+  private static int HASVALS=1;
+  private static int HASHPHOB=2;
+  private static int HASDC=3;
+  private static int HASDESCSTR=4;
+  private static int HASTWOSTATE=5; // not used yet.
+  /**
+   * parses the AnnotationElements - if they exist - into jalview.datamodel.Annotation[] rows
+   * Two annotation rows are made if there are distinct annotation for both at 'pos' and 'after pos' at any particular site.
+   * @param annotation
+   * @return { boolean[static int constants ], int[ae.length] - map to annotated object frame, jalview.datamodel.Annotation[], jalview.datamodel.Annotation[] (after)}
+   */
+  private Object[] parseRangeAnnotation(org.vamsas.objects.core.RangeAnnotation annotation) {
+    // set these attributes by looking in the annotation to decide what kind of alignment annotation rows will be made
+    // TODO: potentially we might make several annotation rows from one vamsas alignment annotation. the jv2Vobj binding mechanism
+    // may not quite cope with this (without binding an array of annotations to a vamsas alignment annotation)
+    // summary flags saying what we found over the set of annotation rows.
+    boolean[] AeContent = new boolean[] { false, false, false, false, false};
+    int[] rangeMap = getMapping(annotation);
+    jalview.datamodel.Annotation[][] anot=new jalview.datamodel.Annotation[][] { 
+        new jalview.datamodel.Annotation[rangeMap.length],
+        new jalview.datamodel.Annotation[rangeMap.length]
+    };
+    boolean mergeable=true; //false  if 'after positions cant be placed on same annotation row as positions. 
+
+    if (annotation.getAnnotationElementCount()>0) {
+      AnnotationElement ae[] = annotation.getAnnotationElement();
+      for (int aa = 0; aa < ae.length; aa++)
+      {
+        int pos = ae[aa].getPosition();
+        if (pos>=0 && pos<anot.length) {
+          int row=ae[aa].getAfter()?1:0;
+          if (anot[row][pos]!=null) {
+            // only time this should happen is if the After flag is set.
+            Cache.log.debug("Ignoring duplicate annotation site at "+pos);
+            continue;
+          }
+          if (anot[1-row][pos]!=null)
+            mergeable=false;
+          String desc = "";
+          if (ae[aa].getDescription()!=null) {
+            desc = ae[aa].getDescription();
+            if (desc.length()>0) {
+              // have imported valid description string
+              AeContent[HASDESCSTR]=true;
+            }
+          }
+          String dc = null;//ae[aa].getDisplayCharacter()==null ? "dc" : ae[aa].getDisplayCharacter();
+          String ss = null;//ae[aa].getSecondaryStructure()==null ? "ss" : ae[aa].getSecondaryStructure();
+          java.awt.Color colour = null;
+          if (ae[aa].getGlyphCount()>0) {
+            Glyph[] glyphs = ae[aa].getGlyph();
+            for (int g=0; g<glyphs.length; g++) {
+              if (glyphs[g].getDict()==org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE) {
+                ss=glyphs[g].getContent();
+                AeContent[HASSECSTR]=true;
+              } else if (glyphs[g].getDict()==org.vamsas.objects.utils.GlyphDictionary.PROTEIN_HD_HYDRO) {
+                Cache.log.debug("ignoring hydrophobicity glyph marker.");
+                AeContent[HASHPHOB]=true;
+                char c=(dc=glyphs[g].getContent()).charAt(0);
+                // dc may get overwritten - but we still set the colour.
+                colour = new java.awt.Color(c=='+'?255:0,c=='.'?255:0,c=='-'?255:0);
+
+              } else if (glyphs[g].getDict()==org.vamsas.objects.utils.GlyphDictionary.DEFAULT) {
+                dc = glyphs[g].getContent();
+                AeContent[HASDC]=true;
+              } else {
+                Cache.log.debug("Ignoring unknown glyph type "+glyphs[g].getDict());
+              }
+            }
+          }
+          float val=0;
+          if (ae[aa].getValueCount()>0) {
+            AeContent[HASVALS]=true;
+            if (ae[aa].getValueCount()>1) {
+              Cache.log.warn("ignoring additional "+(ae[aa].getValueCount()-1)+"values in annotation element.");
+            }
+            val = ae[aa].getValue(0);
+          }
+          if (colour!=null) {
+            anot[row][pos]=new jalview.datamodel.Annotation(desc, (dc!=null) ? dc : "", (ss!=null)?ss.charAt(0):' ', val);
+          } else {
+            anot[row][pos]=new jalview.datamodel.Annotation(desc, (dc!=null) ? dc : "", (ss!=null)?ss.charAt(0):' ', val, colour);
+          }
+        } else {
+          Cache.log.warn("Ignoring out of bound annotation element "+aa+" in "+annotation.getVorbaId().getId());
+        }
+      }
+      // decide on how many annotation rows are needed.
+      if (mergeable) {
+        for (int i=0; i<anot[0].length;i++) {
+          if (anot[1][i]!=null) {
+            anot[0][i] = anot[1][i];
+            anot[0][i].description = anot[0][i].description+" (after)";
+            AeContent[HASDESCSTR]=true; // we have valid description string data
+            anot[1][i] = null;
+          }
+        }
+        anot[1] = null;
+      } else {
+        for (int i=0; i<anot[0].length;i++) {
+          anot[1][i].description = anot[1][i].description+" (after)";
+        }
+      }
+      return new Object[] { AeContent, rangeMap, anot[0], anot[1] };
+    } else {
+      // no annotations to parse.
+    }
+    return null;
+  }
+  /**
+   * @param jal the jalview alignment to which the annotation will be attached (ideally - freshly updated from corresponding vamsas alignment)
+   * @param annotation
+   * @return unbound jalview alignment annotation object.
+   */
+  private jalview.datamodel.AlignmentAnnotation getjAlignmentAnnotation(jalview.datamodel.AlignmentI jal, org.vamsas.objects.core.RangeAnnotation annotation) {
+    jalview.datamodel.AlignmentAnnotation jan =null;
+    if (annotation==null)
+      return null;
+    /*int se[] = getBounds(annotation);
+    if (se==null)
+      se=new int[] {0,jal.getWidth()-1};
+     */
+    Object[] parsedRangeAnnotation = parseRangeAnnotation(annotation);
+
+    if (parsedRangeAnnotation!=null) {
+      if (parsedRangeAnnotation[3]!=null) {
+        Cache.log.warn("Ignoring 'After' annotation row in "+annotation.getVorbaId());
+      }
+      jalview.datamodel.Annotation[] arow = (jalview.datamodel.Annotation[]) parsedRangeAnnotation[2];
+      boolean[] has=(boolean[])parsedRangeAnnotation[0];
+      // VAMSAS: getGraph is only on derived annotation for alignments - in this way its 'odd' - there is already an existing TODO about removing this flag as being redundant
+      if ((annotation.getClass().equals(org.vamsas.objects.core.AlignmentAnnotation.class) && ((org.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())
+          || (annotation.getClass().equals(AlignmentSequenceAnnotation.class) && ((org.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())) {
+        // make bounds and automatic description strings for jalview user's benefit (these shouldn't be written back to vamsas document)
+        boolean first=true;
+        float min=0,max=1;
+
+        for (int i=0;i<arow.length; i++) {
+          if (arow[i]!=null) {
+            // check range - shouldn't we have a min and max property in the annotation object ?
+            if (first) { min=max=arow[i].value; first=false;}
+            else { if (arow[i].value<min) { min=arow[i].value; }
+            else if (arow[i].value>max) { max=arow[i].value; }
+            }
+            // make tooltip and display char value
+            if (!has[HASDESCSTR]) arow[i].description = arow[i].value + "";
+            if (!has[HASDC]) arow[i].displayCharacter=arow[i].value+"";
+          }
+        }
+        int type=jalview.datamodel.AlignmentAnnotation.LINE_GRAPH;
+        if (has[HASHPHOB]) {
+          type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH;
+        }
+        jan = new jalview.datamodel.AlignmentAnnotation(annotation.getLabel(), annotation.getDescription(), arow, min, max, type);
+      } else {
+        jan = new jalview.datamodel.AlignmentAnnotation(annotation.getLabel(), annotation.getDescription(), arow);
+      }
+      if (annotation.getLinkCount()>0) {
+        Cache.log.warn("Ignoring "+annotation.getLinkCount()+"links added to AlignmentAnnotation.");
+      }
+      if (annotation.getModifiable()) {
+        jan.editable=true;
+      }
+
+      if (annotation.getPropertyCount()>0) {
+        // look for special jalview properties
+        org.vamsas.objects.core.Property[] props=annotation.getProperty();
+        for (int p=0;p<props.length; p++) {
+          if (props[p].getName().equalsIgnoreCase("jalview:graphType")) {
+            try { 
+              // probably a jalview annotation graph so recover the visualization hints.
+              jan.graph = jalview.datamodel.AlignmentAnnotation.getGraphValueFromString(props[p].getContent());
+            } catch (Exception e) {
+              Cache.log.debug("Invalid graph type value in jalview:graphType property.");
+            }
+            try {
+              if (annotation.getGroup()!=null && annotation.getGroup().length()>0)
+                jan.graphGroup = Integer.parseInt(annotation.getGroup());
+            } catch (Exception e) {
+              Cache.log.info("UNIMPLEMENTED : Couldn't parse non-integer group value for setting graphGroup correctly.");
+            }
+          }
+        }
+      }
+
+      return jan;
+
+    } else {
+      Cache.log.debug("(Ignoring so ... not) Inserting empty annotation row for whole-alignment annotation.");
+    }
+
+    return null;
+  }
+
+  private SequenceFeature getJalviewSeqFeature(RangeAnnotation dseta) {
+    int[] se = getBounds(dseta);
+    SequenceFeature sf = new jalview.datamodel.SequenceFeature(dseta.getType(),
+        dseta.getDescription(), dseta.getStatus(), se[0], se[1], dseta
+        .getGroup());
+    if (dseta.getLinkCount() > 0)
+    {
+      Link[] links = dseta.getLink();
+      for (int i = 0; i < links.length; i++)
+      {
+        sf.addLink(links[i].getContent() + "|" + links[i].getHref());
+      }
+    }
+    return sf;
+  }
+
+  /**
+   * get real bounds of a RangeType's specification. start and end are an
+   * inclusive range within which all segments and positions lie.
+   * TODO: refactor to vamsas utils
+   * @param dseta
+   * @return int[] { start, end}
+   */
+  private int[] getBounds(RangeType dseta) {
+    if (dseta != null)
+    {
+      int[] se = null;
+      if (dseta.getSegCount()>0 && dseta.getPosCount()>0)
+        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+      if (dseta.getSegCount() > 0)
+      {
+        se = getSegRange(dseta.getSeg(0),true);
+        for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)
+        {
+          int nse[] = getSegRange(dseta.getSeg(s), true);
+          if (se[0] > nse[0])
+            se[0] = nse[0];
+          if (se[1] < nse[1])
+            se[1] = nse[1];
+        }
+      }
+      if (dseta.getPosCount() > 0)
+      {
+        // could do a polarity for pos range too. and pass back indication of discontinuities.
+        int pos = dseta.getPos(0).getI();
+        se = new int[] { pos, pos };
+        for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
+        {
+          pos = dseta.getPos(p).getI();
+          if (se[0] > pos)
+            se[0] = pos;
+          if (se[1] < pos)
+            se[1] = pos;
+        }
+      }
+      return se;
+    }
+    return null;
+  }
+  /**
+   * map from a rangeType's internal frame to the referenced object's coordinate frame.
+   * @param dseta
+   * @return int [] { ref(pos)...} for all pos in rangeType's frame.
+   */
+  private int[] getMapping(RangeType dseta) {
+    Vector posList=new Vector();
+    if (dseta != null)
+    {
+      int[] se = null;
+      if (dseta.getSegCount()>0 && dseta.getPosCount()>0)
+        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+      if (dseta.getSegCount() > 0)
+      {
+        for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
+        {
+          se = getSegRange(dseta.getSeg(s), false);
+          for (int p=se[se[2]]; p!=se[1-se[2]]; p+=se[2]==0 ? 1 : -1 ) {
+            posList.add(Integer.valueOf(p));
+          }
+        }
+      } 
+      else if (dseta.getPosCount() > 0)
+      {
+        int pos = dseta.getPos(0).getI();
+
+        for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
+        {
+          pos = dseta.getPos(p).getI();
+          posList.add(Integer.valueOf(pos));
+        }
+      }
+    }
+    if (posList!=null && posList.size()>0) {
+      int[] range=new int[posList.size()];
+      for (int i=0; i<range.length; i++)
+        range[i] = ((Integer)posList.elementAt(i)).intValue();
+      posList.clear();
+      return range;
+    }
+    return null;
+  }
+/* not needed now. 
+ * Provenance getVamsasProvenance(jalview.datamodel.Provenance jprov) {
+    jalview.datamodel.ProvenanceEntry[] entries = null;
+    // TODO: fix App and Action here.
+    Provenance prov = new Provenance();
+    org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(
+        new java.util.Date());
+    Entry provEntry;
+
+    if (jprov != null)
+    {
+      entries = jprov.getEntries();
+      for (int i = 0; i < entries.length; i++)
+      {
+        provEntry = new Entry();
+        try
+        {
+          date = new org.exolab.castor.types.Date(entries[i].getDate());
+        } catch (Exception ex)
+        {
+          ex.printStackTrace();
+
+          date = new org.exolab.castor.types.Date(entries[i].getDate());
+        }
+        provEntry.setDate(date);
+        provEntry.setUser(entries[i].getUser());
+        provEntry.setAction(entries[i].getAction());
+        prov.addEntry(provEntry);
+      }
+    }
+    else
+    {
+      provEntry = new Entry();
+      provEntry.setDate(date);
+      provEntry.setUser(System.getProperty("user.name")); // TODO: ext string
+      provEntry.setApp("JVAPP"); // TODO: ext string
+      provEntry.setAction(action);
+      prov.addEntry(provEntry);
+    }
+
+    return prov;
+  }
+  */
+  jalview.datamodel.Provenance getJalviewProvenance(Provenance prov) {
+    // TODO: fix App and Action entries and check use of provenance in jalview.
+    jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
+    for (int i = 0; i < prov.getEntryCount(); i++)
+    {
+      jprov.addEntry(prov.getEntry(i).getUser(), prov.getEntry(i).getAction(),
+          prov.getEntry(i).getDate().toDate(), prov.getEntry(i).getId());
+    }
+
+    return jprov;
+  }
+
+  /**
+   * 
+   * @return default initial provenance list for a Jalview created vamsas
+   *         object.
+   */
+  Provenance dummyProvenance() {
+    return dummyProvenance(null);
+  }
+
+  Entry dummyPEntry(String action) {
+    Entry entry = new Entry();
+    entry.setApp("Jalview");
+    if (action != null)
+      entry.setAction(action);
+    else
+      entry.setAction("created.");
+    entry.setDate(new org.exolab.castor.types.Date(new java.util.Date()));
+    entry.setUser(System.getProperty("user.name"));
+    return entry;
+  }
+
+  Provenance dummyProvenance(String action) {
+    Provenance prov = new Provenance();
+    prov.addEntry(dummyPEntry(action));
+    return prov;
+  }
+
+  void addProvenance(Provenance p, String action) {
+    p.addEntry(dummyPEntry(action));
+  }
+
+}
index 0906d12..d7cd478 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.io;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.gui.*;\r
-\r
-import org.apache.axis.client.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-\r
-import javax.xml.namespace.QName;\r
-import jalview.analysis.AlignSeq;\r
-\r
-import uk.ac.ebi.www.*;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class WSWUBlastClient\r
-{\r
-    AlignmentPanel ap;\r
-    AlignmentI al;\r
-    CutAndPasteTransfer output = new CutAndPasteTransfer();\r
-    int jobsRunning = 0;\r
-\r
-    Vector suggestedIds = new Vector();\r
-    /**\r
-     * Creates a new WSWUBlastClient object.\r
-     *\r
-     * @param al DOCUMENT ME!\r
-     * @param ids DOCUMENT ME!\r
-     */\r
-    public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)\r
-    {\r
-        this.ap = ap;\r
-        this.al = al;\r
-        output.setText(\r
-            "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered."\r
-            +"\nIn order to display these features, try changing the names of your sequences to the ids suggested below."\r
-            +"\n\nRunning WSWUBlast at EBI."\r
-            +"\nPlease quote Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R."\r
-            +"\nSOAP-based services provided by the European Bioinformatics Institute."\r
-            +"\nNucleic Acids Res. 33(1):W25-W28 (2005));");\r
-\r
-        Desktop.addInternalFrame(output,\r
-            "BLASTing for unidentified sequences ", 800, 300);\r
-\r
-        for (int i = 0; i < ids.size(); i++)\r
-        {\r
-            Sequence sequence = (Sequence)ids.get(i);\r
-            System.out.println(sequence.getName());\r
-\r
-            BlastThread thread = new BlastThread(sequence);\r
-            thread.start();\r
-            jobsRunning++;\r
-        }\r
-\r
-        ImageTwirler thread = new ImageTwirler();\r
-        thread.start();\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param id1 DOCUMENT ME!\r
-     * @param res DOCUMENT ME!\r
-     */\r
-    void parseResult(Sequence seq, String res)\r
-    {\r
-        StringTokenizer st = new StringTokenizer(res, "\n");\r
-        String data;\r
-        String id2;\r
-        int maxFound = 90;\r
-        StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");\r
-\r
-        while (st.hasMoreTokens())\r
-        {\r
-            data = st.nextToken();\r
-\r
-            if (data.indexOf(">UNIPROT") > -1)\r
-            {\r
-                int index = data.indexOf(">UNIPROT") + 9;\r
-                id2 = data.substring(index, data.indexOf(" ", index));\r
-\r
-                boolean identitiesFound = false;\r
-                while (!identitiesFound)\r
-                {\r
-                    data = st.nextToken();\r
-\r
-                    if (data.indexOf("Identities") > -1)\r
-                    {\r
-                       identitiesFound = true;\r
-\r
-                       int value = Integer.parseInt(data.substring(data.indexOf(\r
-                           "(") + 1,\r
-                                                                   data.indexOf("%")));\r
-\r
-                        if (value >= maxFound)\r
-                        {\r
-                            maxFound = value;\r
-                            buffer.append(" " + id2 + " " + value + "%; ");\r
-                            suggestedIds.addElement( new Object[]{seq, id2});\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        output.appendText(buffer.toString());\r
-    }\r
-\r
-    void updateIds()\r
-    {\r
-        // This must be outside the run() body as java 1.5\r
-     // will not return any value from the OptionPane to the expired thread.\r
-      int reply = JOptionPane.showConfirmDialog(\r
-          Desktop.desktop, "Automatically update suggested ids?",\r
-          "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);\r
-\r
-      if (reply == JOptionPane.YES_OPTION)\r
-      {\r
-        Enumeration keys = suggestedIds.elements();\r
-        while(keys.hasMoreElements())\r
-        {\r
-          Object [] object = (Object[])keys.nextElement();\r
-\r
-          Sequence oldseq = (Sequence)object[0];\r
-\r
-          oldseq.setName( object[1].toString() );\r
-\r
-          // Oldseq is actually in the dataset, we must find the\r
-          // Visible seq and change its name also.\r
-          for (int i = 0; i < al.getHeight(); i++)\r
-          {\r
-            if (al.getSequenceAt(i).getDatasetSequence() == oldseq)\r
-            {\r
-              al.getSequenceAt(i).setName(oldseq.getName());\r
-              break;\r
-            }\r
-          }\r
-\r
-          Vector entries = oldseq.getDBRef();\r
-          if (entries != null)\r
-          {\r
-            DBRefEntry entry = (DBRefEntry) entries.elementAt(0);\r
-            oldseq.addDBRef(new jalview.datamodel.\r
-                                                 DBRefEntry("UNIPROT",\r
-                "0",\r
-                entry.getAccessionId()));\r
-          }\r
-        }\r
-      }\r
-      ap.repaint();\r
-\r
-    }\r
-\r
-    class ImageTwirler extends Thread\r
-    {\r
-        ImageIcon[] imageIcon;\r
-        int imageIndex = 0;\r
-\r
-        public ImageTwirler()\r
-        {\r
-            imageIcon = new ImageIcon[9];\r
-\r
-            for (int i = 0; i < 9; i++)\r
-            {\r
-                java.net.URL url = getClass().getResource("/images/dna" +\r
-                        (i + 1) + ".gif");\r
-\r
-                if (url != null)\r
-                {\r
-                    imageIcon[i] = new ImageIcon(url);\r
-                }\r
-            }\r
-        }\r
-\r
-        public void run()\r
-        {\r
-            while (jobsRunning > 0)\r
-            {\r
-                try\r
-                {\r
-                    Thread.sleep(100);\r
-                    imageIndex++;\r
-                    imageIndex %= 9;\r
-                    output.setFrameIcon(imageIcon[imageIndex]);\r
-                    output.setTitle("BLASTing for unidentified sequences - " +\r
-                        jobsRunning + " jobs running.");\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
-\r
-            if (jobsRunning == 0)\r
-            {\r
-              updateIds();\r
-            }\r
-        }\r
-    }\r
-\r
-    class BlastThread extends Thread\r
-    {\r
-        Sequence sequence;\r
-        String jobid;\r
-        boolean jobComplete = false;\r
-\r
-        BlastThread(Sequence sequence)\r
-        {\r
-          System.out.println("blasting for: "+sequence.getName());\r
-          this.sequence = sequence;\r
-        }\r
-\r
-        public void run()\r
-        {\r
-            StartJob();\r
-\r
-            while (!jobComplete)\r
-            {\r
-                try\r
-                {\r
-                  WSWUBlastService service =  new WSWUBlastServiceLocator();\r
-                  WSWUBlast wublast = service.getWSWUBlast();\r
-                  WSFile[] results = wublast.getResults(jobid);\r
-\r
-                  if(results!=null)\r
-                  {\r
-                      String result = new String(wublast.poll(jobid, "tooloutput"));\r
-                      parseResult(sequence, result);\r
-                      jobComplete = true;\r
-                      jobsRunning--;\r
-                  }\r
-                  else\r
-                  {\r
-                    Thread.sleep(10000);\r
-                    System.out.println("WSWuBlastClient: I'm alive " +\r
-                                       sequence.getName() + " " + jobid); // log.debug\r
-                  }\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
-        }\r
-\r
-        void StartJob()\r
-        {\r
-          InputParams params = new InputParams();\r
-\r
-          params.setProgram("blastp");\r
-          params.setDatabase("uniprot");\r
-          params.setMatrix("pam10");\r
-\r
-          params.setNumal(5);\r
-          params.setSensitivity("low");\r
-          params.setSort("totalscore");\r
-          params.setOutformat("txt");\r
-          params.setAsync(true);\r
-\r
-            try\r
-            {\r
-              Data inputs[] = new Data[1];\r
-              Data input= new Data();\r
-              input.setType("sequence");\r
-              input.setContent(AlignSeq.extractGaps("-. ",sequence.getSequence()));\r
-              inputs[0]=input;\r
-\r
-              WSWUBlastService service = new WSWUBlastServiceLocator();\r
-              WSWUBlast wublast = service.getWSWUBlast();\r
-              jobid = wublast.runWUBlast(params, inputs);\r
-            }\r
-            catch (Exception exp)\r
-            {\r
-              jobComplete = true;\r
-              jobsRunning--;\r
-              System.err.println("WSWUBlastClient error:\n" + exp.toString());\r
-              exp.printStackTrace();\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.io;
+
+import jalview.datamodel.*;
+
+import jalview.gui.*;
+
+import org.apache.axis.client.*;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import javax.xml.namespace.QName;
+import jalview.analysis.AlignSeq;
+
+import uk.ac.ebi.www.*;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class WSWUBlastClient
+{
+    AlignmentPanel ap;
+    AlignmentI al;
+    CutAndPasteTransfer output = new CutAndPasteTransfer();
+    int jobsRunning = 0;
+
+    Vector suggestedIds = new Vector();
+    /**
+     * Creates a new WSWUBlastClient object.
+     *
+     * @param al DOCUMENT ME!
+     * @param ids DOCUMENT ME!
+     */
+    public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)
+    {
+        this.ap = ap;
+        this.al = al;
+        output.setText(
+            "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered."
+            +"\nIn order to display these features, try changing the names of your sequences to the ids suggested below."
+            +"\n\nRunning WSWUBlast at EBI."
+            +"\nPlease quote Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R."
+            +"\nSOAP-based services provided by the European Bioinformatics Institute."
+            +"\nNucleic Acids Res. 33(1):W25-W28 (2005));");
+
+        Desktop.addInternalFrame(output,
+            "BLASTing for unidentified sequences ", 800, 300);
+
+        for (int i = 0; i < ids.size(); i++)
+        {
+            Sequence sequence = (Sequence)ids.get(i);
+            System.out.println(sequence.getName());
+
+            BlastThread thread = new BlastThread(sequence);
+            thread.start();
+            jobsRunning++;
+        }
+
+        ImageTwirler thread = new ImageTwirler();
+        thread.start();
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param id1 DOCUMENT ME!
+     * @param res DOCUMENT ME!
+     */
+    void parseResult(Sequence seq, String res)
+    {
+        StringTokenizer st = new StringTokenizer(res, "\n");
+        String data;
+        String id2;
+        int maxFound = 90;
+        StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");
+
+        while (st.hasMoreTokens())
+        {
+            data = st.nextToken();
+
+            if (data.indexOf(">UNIPROT") > -1)
+            {
+                int index = data.indexOf(">UNIPROT") + 9;
+                id2 = data.substring(index, data.indexOf(" ", index));
+
+                boolean identitiesFound = false;
+                while (!identitiesFound)
+                {
+                    data = st.nextToken();
+
+                    if (data.indexOf("Identities") > -1)
+                    {
+                       identitiesFound = true;
+
+                       int value = Integer.parseInt(data.substring(data.indexOf(
+                           "(") + 1,
+                                                                   data.indexOf("%")));
+
+                        if (value >= maxFound)
+                        {
+                            maxFound = value;
+                            buffer.append(" " + id2 + " " + value + "%; ");
+                            suggestedIds.addElement( new Object[]{seq, id2});
+                        }
+                    }
+                }
+            }
+        }
+
+        output.appendText(buffer.toString());
+    }
+
+    void updateIds()
+    {
+        // This must be outside the run() body as java 1.5
+     // will not return any value from the OptionPane to the expired thread.
+      int reply = JOptionPane.showConfirmDialog(
+          Desktop.desktop, "Automatically update suggested ids?",
+          "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);
+
+      if (reply == JOptionPane.YES_OPTION)
+      {
+        Enumeration keys = suggestedIds.elements();
+        while(keys.hasMoreElements())
+        {
+          Object [] object = (Object[])keys.nextElement();
+
+          Sequence oldseq = (Sequence)object[0];
+
+          oldseq.setName( object[1].toString() );
+
+          // Oldseq is actually in the dataset, we must find the
+          // Visible seq and change its name also.
+          for (int i = 0; i < al.getHeight(); i++)
+          {
+            if (al.getSequenceAt(i).getDatasetSequence() == oldseq)
+            {
+              al.getSequenceAt(i).setName(oldseq.getName());
+              break;
+            }
+          }
+
+          DBRefEntry [] entries = oldseq.getDBRef();
+          if (entries != null)
+          {
+            oldseq.addDBRef(new jalview.datamodel.
+                                                 DBRefEntry(jalview.datamodel.DBRefSource.UNIPROT,
+                "0",
+                entries[0].getAccessionId()));
+          }
+        }
+      }
+      ap.repaint();
+
+    }
+
+    class ImageTwirler extends Thread
+    {
+        ImageIcon[] imageIcon;
+        int imageIndex = 0;
+
+        public ImageTwirler()
+        {
+            imageIcon = new ImageIcon[9];
+
+            for (int i = 0; i < 9; i++)
+            {
+                java.net.URL url = getClass().getResource("/images/dna" +
+                        (i + 1) + ".gif");
+
+                if (url != null)
+                {
+                    imageIcon[i] = new ImageIcon(url);
+                }
+            }
+        }
+
+        public void run()
+        {
+            while (jobsRunning > 0)
+            {
+                try
+                {
+                    Thread.sleep(100);
+                    imageIndex++;
+                    imageIndex %= 9;
+                    output.setFrameIcon(imageIcon[imageIndex]);
+                    output.setTitle("BLASTing for unidentified sequences - " +
+                        jobsRunning + " jobs running.");
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+
+            if (jobsRunning == 0)
+            {
+              updateIds();
+            }
+        }
+    }
+
+    class BlastThread extends Thread
+    {
+        Sequence sequence;
+        String jobid;
+        boolean jobComplete = false;
+
+        BlastThread(Sequence sequence)
+        {
+          System.out.println("blasting for: "+sequence.getName());
+          this.sequence = sequence;
+        }
+
+        public void run()
+        {
+            StartJob();
+
+            while (!jobComplete)
+            {
+                try
+                {
+                  WSWUBlastService service =  new WSWUBlastServiceLocator();
+                  WSWUBlast wublast = service.getWSWUBlast();
+                  WSFile[] results = wublast.getResults(jobid);
+
+                  if(results!=null)
+                  {
+                      String result = new String(wublast.poll(jobid, "tooloutput"));
+                      parseResult(sequence, result);
+                      jobComplete = true;
+                      jobsRunning--;
+                  }
+                  else
+                  {
+                    Thread.sleep(10000);
+                    System.out.println("WSWuBlastClient: I'm alive " +
+                                       sequence.getName() + " " + jobid); // log.debug
+                  }
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+        }
+
+        void StartJob()
+        {
+          InputParams params = new InputParams();
+
+          params.setProgram("blastp");
+          params.setDatabase("uniprot");
+          params.setMatrix("pam10");
+
+          params.setNumal(5);
+          params.setSensitivity("low");
+          params.setSort("totalscore");
+          params.setOutformat("txt");
+          params.setAsync(true);
+
+            try
+            {
+              Data inputs[] = new Data[1];
+              Data input= new Data();
+              input.setType("sequence");
+              input.setContent(AlignSeq.extractGaps("-. ",sequence.getSequence()));
+              inputs[0]=input;
+
+              WSWUBlastService service = new WSWUBlastServiceLocator();
+              WSWUBlast wublast = service.getWSWUBlast();
+              jobid = wublast.runWUBlast(params, inputs);
+            }
+            catch (Exception exp)
+            {
+              jobComplete = true;
+              jobsRunning--;
+              System.err.println("WSWUBlastClient error:\n" + exp.toString());
+              exp.printStackTrace();
+            }
+        }
+    }
+}
index bddc504..2c99170 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import javax.swing.*;\r
-\r
-import jalview.schemes.*;\r
-\r
-public class GAlignFrame\r
-    extends JInternalFrame\r
-{\r
-  protected JMenuBar alignFrameMenuBar = new JMenuBar();\r
-  protected JMenu fileMenu = new JMenu();\r
-  protected JMenuItem closeMenuItem = new JMenuItem();\r
-  protected JMenu editMenu = new JMenu();\r
-  protected JMenu viewMenu = new JMenu();\r
-  protected JMenu colourMenu = new JMenu();\r
-  protected JMenu calculateMenu = new JMenu();\r
-  protected JMenu webService = new JMenu();\r
-  protected JMenuItem webServiceNoServices;\r
-  protected JMenuItem selectAllSequenceMenuItem = new JMenuItem();\r
-  protected JMenuItem deselectAllSequenceMenuItem = new JMenuItem();\r
-  protected JMenuItem invertSequenceMenuItem = new JMenuItem();\r
-  protected JMenuItem remove2LeftMenuItem = new JMenuItem();\r
-  protected JMenuItem remove2RightMenuItem = new JMenuItem();\r
-  protected JMenuItem removeGappedColumnMenuItem = new JMenuItem();\r
-  protected JMenuItem removeAllGapsMenuItem = new JMenuItem();\r
-  public JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem();\r
-  protected JMenuItem sortPairwiseMenuItem = new JMenuItem();\r
-  protected JMenuItem sortIDMenuItem = new JMenuItem();\r
-  protected JMenuItem sortGroupMenuItem = new JMenuItem();\r
-  protected JMenuItem removeRedundancyMenuItem = new JMenuItem();\r
-  protected JMenuItem pairwiseAlignmentMenuItem = new JMenuItem();\r
-  protected JMenuItem PCAMenuItem = new JMenuItem();\r
-  protected JMenuItem averageDistanceTreeMenuItem = new JMenuItem();\r
-  protected JMenuItem neighbourTreeMenuItem = new JMenuItem();\r
-  protected JMenuItem clustalAlignMenuItem = new JMenuItem();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  public JLabel statusBar = new JLabel();\r
-  protected JMenuItem saveAlignmentMenu = new JMenuItem();\r
-  protected JMenu outputTextboxMenu = new JMenu();\r
-  protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem hydrophobicityColour = new\r
-      JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();\r
-  protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();\r
-  JMenuItem njTreeBlosumMenuItem = new JMenuItem();\r
-  JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem();\r
-  public JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem();\r
-  JMenuItem htmlMenuItem = new JMenuItem();\r
-  JMenuItem overviewMenuItem = new JMenuItem();\r
-  protected JMenuItem undoMenuItem = new JMenuItem();\r
-  protected JMenuItem redoMenuItem = new JMenuItem();\r
-  public JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();\r
-  JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();\r
-  public JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem();\r
-  JMenuItem printMenuItem = new JMenuItem();\r
-  public JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem();\r
-  JMenuItem findMenuItem = new JMenuItem();\r
-  JMenu searchMenu = new JMenu();\r
-  public JCheckBoxMenuItem abovePIDThreshold = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem();\r
-  protected JRadioButtonMenuItem nucleotideColour = new JRadioButtonMenuItem();\r
-  JMenuItem deleteGroups = new JMenuItem();\r
-  JMenuItem delete = new JMenuItem();\r
-  JMenuItem copy = new JMenuItem();\r
-  JMenuItem cut = new JMenuItem();\r
-  JMenu jMenu1 = new JMenu();\r
-  JMenuItem pasteNew = new JMenuItem();\r
-  JMenuItem pasteThis = new JMenuItem();\r
-  public JCheckBoxMenuItem applyToAllGroups = new JCheckBoxMenuItem();\r
-  JMenuItem createPNG = new JMenuItem();\r
-  protected JMenuItem font = new JMenuItem();\r
-  public JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem();\r
-  JMenuItem epsFile = new JMenuItem();\r
-  JMenuItem LoadtreeMenuItem = new JMenuItem();\r
-  public JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem();\r
-  protected JMenuItem modifyPID = new JMenuItem();\r
-  protected JMenuItem modifyConservation = new JMenuItem();\r
-  protected JMenu sortByTreeMenu = new JMenu();\r
-  protected JMenu sort = new JMenu();\r
-  JMenu calculate = new JMenu();\r
-  JMenu jMenu2 = new JMenu();\r
-  JMenuItem padGapsMenuitem = new JMenuItem();\r
-  protected ButtonGroup colours = new ButtonGroup();\r
-  JMenuItem vamsasStore = new JMenuItem();\r
-  protected JCheckBoxMenuItem showTranslation = new JCheckBoxMenuItem();\r
-  //protected JTabbedPane tabbedPane = new JTabbedPane();\r
-  public JMenuItem featureSettings = new JMenuItem();\r
-  JMenuItem fetchSequence = new JMenuItem();\r
-  protected JCheckBoxMenuItem smoothFont = new JCheckBoxMenuItem();\r
-  JMenuItem annotationColour = new JMenuItem();\r
-  JMenuItem fetchSeqFeatures = new JMenuItem();\r
-\r
-\r
-\r
-  JMenuItem associatedData = new JMenuItem();\r
-  public GAlignFrame()\r
-  {\r
-\r
-\r
-    try\r
-    {\r
-      jbInit();\r
-      setJMenuBar(alignFrameMenuBar);\r
-\r
-      // dynamically fill save as menu with available formats\r
-      for (int i = 0; i < jalview.io.FormatAdapter.formats.size(); i++)\r
-      {\r
-        JMenuItem item = new JMenuItem( (String) jalview.io.FormatAdapter.formats.\r
-                             elementAt(\r
-                                 i));\r
-        item.addActionListener(new java.awt.event.ActionListener()\r
-        {\r
-          public void actionPerformed(ActionEvent e)\r
-          {\r
-            outputText_actionPerformed(e);\r
-          }\r
-        });\r
-\r
-        outputTextboxMenu.add(item);\r
-      }\r
-    }\r
-    catch (Exception e)\r
-    {\r
-    }\r
-\r
-\r
-    if(jalview.gui.UserDefinedColours.getUserColourSchemes()!=null)\r
-    {\r
-      java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
-          getUserColourSchemes().keys();\r
-\r
-      while (userColours.hasMoreElements())\r
-      {\r
-        final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
-            nextElement().toString());\r
-        radioItem.setName("USER_DEFINED");\r
-        radioItem.addMouseListener(new MouseAdapter()\r
-            {\r
-              public void mousePressed(MouseEvent evt)\r
-              {\r
-                if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
-                {\r
-                  radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
-\r
-                  int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
-                      "Remove from default list?",\r
-                      "Remove user defined colour",\r
-                      JOptionPane.YES_NO_OPTION);\r
-                  if(option == JOptionPane.YES_OPTION)\r
-                  {\r
-                    jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
-                    colourMenu.remove(radioItem);\r
-                  }\r
-                  else\r
-                    radioItem.addActionListener(new ActionListener()\r
-                    {\r
-                      public void actionPerformed(ActionEvent evt)\r
-                      {\r
-                        userDefinedColour_actionPerformed(evt);\r
-                      }\r
-                    });\r
-                }\r
-              }\r
-            });\r
-        radioItem.addActionListener(new ActionListener()\r
-        {\r
-          public void actionPerformed(ActionEvent evt)\r
-          {\r
-            userDefinedColour_actionPerformed(evt);\r
-          }\r
-        });\r
-        colourMenu.insert(radioItem, 15);\r
-        colours.add(radioItem);\r
-      }\r
-    }\r
-    colours.add(noColourmenuItem);\r
-    colours.add(clustalColour);\r
-    colours.add(zappoColour);\r
-    colours.add(taylorColour);\r
-    colours.add(hydrophobicityColour);\r
-    colours.add(helixColour);\r
-    colours.add(strandColour);\r
-    colours.add(turnColour);\r
-    colours.add(buriedColour);\r
-    colours.add(userDefinedColour);\r
-    colours.add(PIDColour);\r
-    colours.add(BLOSUM62Colour);\r
-    colours.add(nucleotideColour);\r
-\r
-    setColourSelected(jalview.bin.Cache.getDefault("DEFAULT_COLOUR", "None"));\r
-\r
-\r
-  }\r
-\r
-  public void setColourSelected(String defaultColour)\r
-  {\r
-\r
-    if (defaultColour != null)\r
-    {\r
-      int index = ColourSchemeProperty.getColourIndexFromName(defaultColour);\r
-\r
-      switch (index)\r
-      {\r
-        case ColourSchemeProperty.NONE:\r
-              noColourmenuItem.setSelected(true);\r
-              break;\r
-        case ColourSchemeProperty.CLUSTAL:\r
-          clustalColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.BLOSUM:\r
-          BLOSUM62Colour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.PID:\r
-          PIDColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.ZAPPO:\r
-          zappoColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.TAYLOR:\r
-          taylorColour.setSelected(true);\r
-          break;\r
-\r
-        case ColourSchemeProperty.HYDROPHOBIC:\r
-          hydrophobicityColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.HELIX:\r
-          helixColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.STRAND:\r
-          strandColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.TURN:\r
-          turnColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.BURIED:\r
-          buriedColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.NUCLEOTIDE:\r
-          nucleotideColour.setSelected(true);\r
-\r
-          break;\r
-\r
-        case ColourSchemeProperty.USER_DEFINED:\r
-          userDefinedColour.setSelected(true);\r
-\r
-          break;\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    fileMenu.setMnemonic('F');\r
-    fileMenu.setText("File");\r
-    saveAlignmentMenu.setMnemonic('L');\r
-    saveAlignmentMenu.setText("Save As");\r
-    saveAlignmentMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.\r
-        awt.event.KeyEvent.VK_S, java.awt.event.KeyEvent.CTRL_MASK, false));\r
-    saveAlignmentMenu.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        saveAlignmentMenu_actionPerformed(e);\r
-      }\r
-    });\r
-    closeMenuItem.setMnemonic('C');\r
-    closeMenuItem.setText("Close");\r
-    closeMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        closeMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    editMenu.setText("Edit");\r
-    viewMenu.setText("View");\r
-    colourMenu.setText("Colour");\r
-    calculateMenu.setText("Calculate");\r
-    webService.setText("Web Service");\r
-    selectAllSequenceMenuItem.setText("Select all");\r
-    selectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_A,\r
-        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));\r
-    selectAllSequenceMenuItem.addActionListener(new java.awt.event.\r
-                                                ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        selectAllSequenceMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    deselectAllSequenceMenuItem.setText("Deselect All");\r
-    deselectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke.\r
-                                               getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_ESCAPE, 0, false));\r
-    deselectAllSequenceMenuItem.addActionListener(new java.awt.event.\r
-                                                  ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        deselectAllSequenceMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    invertSequenceMenuItem.setText("Invert Selection");\r
-    invertSequenceMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        invertSequenceMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    remove2LeftMenuItem.setText("Remove Left");\r
-    remove2LeftMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        remove2LeftMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    remove2RightMenuItem.setText("Remove Right");\r
-    remove2RightMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        remove2RightMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    removeGappedColumnMenuItem.setText("Remove Empty Columns");\r
-    removeGappedColumnMenuItem.addActionListener(new java.awt.event.\r
-                                                 ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        removeGappedColumnMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    removeAllGapsMenuItem.setText("Remove All Gaps");\r
-    removeAllGapsMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        removeAllGapsMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    viewBoxesMenuItem.setText("Boxes");\r
-    viewBoxesMenuItem.setState(true);\r
-    viewBoxesMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        viewBoxesMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    viewTextMenuItem.setText("Text");\r
-    viewTextMenuItem.setState(true);\r
-    viewTextMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        viewTextMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    sortPairwiseMenuItem.setText("by Pairwise Identity");\r
-    sortPairwiseMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        sortPairwiseMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    sortIDMenuItem.setText("by ID");\r
-    sortIDMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        sortIDMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    sortGroupMenuItem.setText("by Group");\r
-    sortGroupMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        sortGroupMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    removeRedundancyMenuItem.setText("Remove Redundancy...");\r
-    removeRedundancyMenuItem.addActionListener(new java.awt.event.\r
-                                               ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        removeRedundancyMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    pairwiseAlignmentMenuItem.setText("Pairwise Alignments...");\r
-    pairwiseAlignmentMenuItem.addActionListener(new java.awt.event.\r
-                                                ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        pairwiseAlignmentMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    PCAMenuItem.setText("Principal Component Analysis");\r
-    PCAMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        PCAMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    averageDistanceTreeMenuItem.setText(\r
-        "Average Distance Using % Identity");\r
-    averageDistanceTreeMenuItem.addActionListener(new java.awt.event.\r
-                                                  ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        averageDistanceTreeMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    neighbourTreeMenuItem.setText("Neighbour Joining Using % Identity");\r
-    neighbourTreeMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        neighbourTreeMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    this.getContentPane().setLayout(borderLayout1);\r
-    alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));\r
-    statusBar.setBackground(Color.white);\r
-    statusBar.setFont(new java.awt.Font("Verdana", 0, 11));\r
-    statusBar.setBorder(BorderFactory.createLineBorder(Color.black));\r
-    statusBar.setText("Status bar");\r
-    outputTextboxMenu.setMnemonic('T');\r
-    outputTextboxMenu.setText("Output to Textbox");\r
-    clustalColour.setText("Clustalx");\r
-\r
-    clustalColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        clustalColour_actionPerformed(e);\r
-      }\r
-    });\r
-    zappoColour.setText("Zappo");\r
-    zappoColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        zappoColour_actionPerformed(e);\r
-      }\r
-    });\r
-    taylorColour.setText("Taylor");\r
-    taylorColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        taylorColour_actionPerformed(e);\r
-      }\r
-    });\r
-    hydrophobicityColour.setText("Hydrophobicity");\r
-    hydrophobicityColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        hydrophobicityColour_actionPerformed(e);\r
-      }\r
-    });\r
-    helixColour.setText("Helix Propensity");\r
-    helixColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        helixColour_actionPerformed(e);\r
-      }\r
-    });\r
-    strandColour.setText("Strand Propensity");\r
-    strandColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        strandColour_actionPerformed(e);\r
-      }\r
-    });\r
-    turnColour.setText("Turn Propensity");\r
-    turnColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        turnColour_actionPerformed(e);\r
-      }\r
-    });\r
-    buriedColour.setText("Buried Index");\r
-    buriedColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        buriedColour_actionPerformed(e);\r
-      }\r
-    });\r
-    userDefinedColour.setText("User Defined...");\r
-    userDefinedColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        userDefinedColour_actionPerformed(e);\r
-      }\r
-    });\r
-    PIDColour.setText("Percentage Identity");\r
-    PIDColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        PIDColour_actionPerformed(e);\r
-      }\r
-    });\r
-    BLOSUM62Colour.setText("BLOSUM62 Score");\r
-    BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        BLOSUM62Colour_actionPerformed(e);\r
-      }\r
-    });\r
-    avDistanceTreeBlosumMenuItem.setText(\r
-        "Average Distance Using BLOSUM62");\r
-    avDistanceTreeBlosumMenuItem.addActionListener(new java.awt.event.\r
-        ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        avTreeBlosumMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    njTreeBlosumMenuItem.setText("Neighbour Joining using BLOSUM62");\r
-    njTreeBlosumMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        njTreeBlosumMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    annotationPanelMenuItem.setActionCommand("");\r
-    annotationPanelMenuItem.setText("Show Annotations");\r
-    annotationPanelMenuItem.setState( jalview.bin.Cache.getDefault("SHOW_ANNOTATIONS",true));\r
-    annotationPanelMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        annotationPanelMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    colourTextMenuItem.setText("Colour Text");\r
-    colourTextMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        colourTextMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    htmlMenuItem.setText("HTML");\r
-    htmlMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        htmlMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    overviewMenuItem.setText("Overview Window");\r
-    overviewMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        overviewMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    undoMenuItem.setEnabled(false);\r
-    undoMenuItem.setMnemonic('Z');\r
-    undoMenuItem.setText("Undo");\r
-    undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_Z,\r
-        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));\r
-    undoMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        undoMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    redoMenuItem.setEnabled(false);\r
-    redoMenuItem.setMnemonic('0');\r
-    redoMenuItem.setText("Redo");\r
-    redoMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        redoMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    conservationMenuItem.setText("By Conservation");\r
-    conservationMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        conservationMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    noColourmenuItem.setText("None");\r
-    noColourmenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        noColourmenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    wrapMenuItem.setText("Wrap");\r
-    wrapMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        wrapMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    printMenuItem.setText("Print");\r
-    printMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        printMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    renderGapsMenuItem.setText("Show Gaps");\r
-    renderGapsMenuItem.setState(true);\r
-    renderGapsMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        renderGapsMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    findMenuItem.setText("Find...");\r
-    findMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_F,\r
-        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));\r
-    findMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        findMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    searchMenu.setText("Search");\r
-\r
-    abovePIDThreshold.setText("Above Identity Threshold");\r
-    abovePIDThreshold.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        abovePIDThreshold_actionPerformed(e);\r
-      }\r
-    });\r
-    showSeqFeatures.setText("Show Sequence Features");\r
-    showSeqFeatures.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent actionEvent)\r
-      {\r
-        showSeqFeatures_actionPerformed(actionEvent);\r
-      }\r
-    });\r
-    nucleotideColour.setText("Nucleotide");\r
-    nucleotideColour.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        nucleotideColour_actionPerformed(e);\r
-      }\r
-    });\r
-    deleteGroups.setText("Undefine groups");\r
-    deleteGroups.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        deleteGroups_actionPerformed(e);\r
-      }\r
-    });\r
-    copy.setText("Copy");\r
-    copy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_C,\r
-        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));\r
-    copy.setMnemonic(KeyEvent.VK_C);\r
-\r
-    copy.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        copy_actionPerformed(e);\r
-      }\r
-    });\r
-    cut.setText("Cut");\r
-    cut.setAccelerator(javax.swing.KeyStroke.getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_X,\r
-        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));\r
-    cut.setMnemonic(KeyEvent.VK_X);\r
-    cut.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        cut_actionPerformed(e);\r
-      }\r
-    });\r
-    delete.setText("Delete");\r
-    delete.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        delete_actionPerformed(e);\r
-      }\r
-    });\r
-    jMenu1.setMnemonic('V');\r
-    jMenu1.setText("Paste");\r
-    pasteNew.setText("To New Alignment");\r
-    pasteNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(\r
-        java.awt.event.KeyEvent.VK_V,\r
-        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));\r
-    pasteNew.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        pasteNew_actionPerformed(e);\r
-      }\r
-    });\r
-    pasteThis.setText("Add To This Alignment");\r
-    pasteThis.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        pasteThis_actionPerformed(e);\r
-      }\r
-    });\r
-    applyToAllGroups.setText("Apply Colour To All Groups");\r
-    applyToAllGroups.setState(true);\r
-    applyToAllGroups.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        applyToAllGroups_actionPerformed(e);\r
-      }\r
-    });\r
-    createPNG.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        createPNG(null);\r
-      }\r
-    });\r
-    createPNG.setActionCommand("Save As PNG Image");\r
-    createPNG.setText("PNG");\r
-    font.setText("Font...");\r
-    font.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        font_actionPerformed(e);\r
-      }\r
-    });\r
-\r
-    seqLimits.setText("Show Sequence Limits");\r
-    seqLimits.setState( jalview.bin.Cache.getDefault("SHOW_JVSUFFIX",true));\r
-    seqLimits.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        seqLimit_actionPerformed(e);\r
-      }\r
-    });\r
-    epsFile.setText("EPS");\r
-    epsFile.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        createEPS(null);\r
-      }\r
-    });\r
-    LoadtreeMenuItem.setActionCommand("Load a tree for this sequence set");\r
-    LoadtreeMenuItem.setText("Load Associated Tree");\r
-    LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        LoadtreeMenuItem_actionPerformed(e);\r
-      }\r
-    });\r
-    scaleAbove.setVisible(false);\r
-    scaleAbove.setText("Scale Above");\r
-    scaleAbove.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        scaleAbove_actionPerformed(e);\r
-      }\r
-    });\r
-    scaleLeft.setVisible(false);\r
-    scaleLeft.setSelected(true);\r
-    scaleLeft.setText("Scale Left");\r
-    scaleLeft.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        scaleLeft_actionPerformed(e);\r
-      }\r
-    });\r
-    scaleRight.setVisible(false);\r
-    scaleRight.setSelected(true);\r
-    scaleRight.setText("Scale Right");\r
-    scaleRight.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        scaleRight_actionPerformed(e);\r
-      }\r
-    });\r
-    modifyPID.setText("Modify Identity Threshold...");\r
-    modifyPID.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        modifyPID_actionPerformed(e);\r
-      }\r
-    });\r
-    modifyConservation.setText("Modify Conservation Threshold...");\r
-    modifyConservation.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        modifyConservation_actionPerformed(e);\r
-      }\r
-    });\r
-    sortByTreeMenu.setText("By Tree Order");\r
-    sort.setText("Sort");\r
-    calculate.setText("Calculate Tree");\r
-\r
-    jMenu2.setText("Export");\r
-    padGapsMenuitem.setText("Pad Gaps");\r
-    padGapsMenuitem.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        padGapsMenuitem_actionPerformed(e);\r
-      }\r
-    });\r
-    vamsasStore.setVisible(false);\r
-    vamsasStore.setText("VAMSAS store");\r
-    vamsasStore.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        vamsasStore_actionPerformed(e);\r
-      }\r
-    });\r
-    showTranslation.setText("Translate cDNA");\r
-    showTranslation.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        showTranslation_actionPerformed(e);\r
-      }\r
-    });\r
-\r
-   /* tabbedPane.addChangeListener(new ChangeListener()\r
-        {\r
-          public void stateChanged(ChangeEvent ece)\r
-          {\r
-\r
-            tabSelected();\r
-          }\r
-        });*/\r
-    featureSettings.setText("Feature Settings...");\r
-    featureSettings.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        featureSettings_actionPerformed(e);\r
-      }\r
-    });\r
-    fetchSequence.setText("Fetch Sequence(s)...");\r
-    fetchSequence.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        fetchSequence_actionPerformed(e);\r
-      }\r
-    });\r
-    smoothFont.setText("Smooth Fonts");\r
-    smoothFont.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        smoothFont_actionPerformed(e);\r
-      }\r
-    });\r
-    smoothFont.setState( jalview.bin.Cache.getDefault("ANTI_ALIAS",false));\r
-    annotationColour.setText("By Annotation...");\r
-    annotationColour.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        annotationColour_actionPerformed(e);\r
-      }\r
-    });\r
-    fetchSeqFeatures.setText("Fetch Sequence Features");\r
-    fetchSeqFeatures.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        fetchSeqFeatures_actionPerformed(e);\r
-      }\r
-    });\r
-    associatedData.setText("Load Features / Annotations");\r
-    associatedData.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        associatedData_actionPerformed(e);\r
-      }\r
-    });\r
-    alignFrameMenuBar.add(fileMenu);\r
-    alignFrameMenuBar.add(editMenu);\r
-    alignFrameMenuBar.add(searchMenu);\r
-    alignFrameMenuBar.add(viewMenu);\r
-    alignFrameMenuBar.add(colourMenu);\r
-    alignFrameMenuBar.add(calculateMenu);\r
-    alignFrameMenuBar.add(webService);\r
-    fileMenu.add(fetchSequence);\r
-    fileMenu.addSeparator();\r
-    fileMenu.add(vamsasStore);\r
-    fileMenu.add(saveAlignmentMenu);\r
-    fileMenu.add(jMenu2);\r
-    fileMenu.add(outputTextboxMenu);\r
-    fileMenu.add(printMenuItem);\r
-    fileMenu.addSeparator();\r
-    fileMenu.add(LoadtreeMenuItem);\r
-    fileMenu.add(associatedData);\r
-    fileMenu.addSeparator();\r
-    fileMenu.add(closeMenuItem);\r
-    editMenu.add(undoMenuItem);\r
-    editMenu.add(redoMenuItem);\r
-    editMenu.add(cut);\r
-    editMenu.add(copy);\r
-    editMenu.add(jMenu1);\r
-    editMenu.add(delete);\r
-    editMenu.addSeparator();\r
-    editMenu.add(selectAllSequenceMenuItem);\r
-    editMenu.add(deselectAllSequenceMenuItem);\r
-    editMenu.add(invertSequenceMenuItem);\r
-    editMenu.add(deleteGroups);\r
-    editMenu.addSeparator();\r
-    editMenu.add(remove2LeftMenuItem);\r
-    editMenu.add(remove2RightMenuItem);\r
-    editMenu.add(removeGappedColumnMenuItem);\r
-    editMenu.add(removeAllGapsMenuItem);\r
-    editMenu.add(removeRedundancyMenuItem);\r
-    editMenu.addSeparator();\r
-    editMenu.add(padGapsMenuitem);\r
-    searchMenu.add(findMenuItem);\r
-    viewMenu.add(font);\r
-    viewMenu.add(smoothFont);\r
-    viewMenu.addSeparator();\r
-    viewMenu.add(wrapMenuItem);\r
-    viewMenu.add(seqLimits);\r
-    viewMenu.add(scaleAbove);\r
-    viewMenu.add(scaleLeft);\r
-    viewMenu.add(scaleRight);\r
-    viewMenu.add(viewBoxesMenuItem);\r
-    viewMenu.add(viewTextMenuItem);\r
-    viewMenu.add(colourTextMenuItem);\r
-    viewMenu.add(renderGapsMenuItem);\r
-    viewMenu.add(annotationPanelMenuItem);\r
-    viewMenu.addSeparator();\r
-    viewMenu.add(fetchSeqFeatures);\r
-    viewMenu.add(showSeqFeatures);\r
-    viewMenu.add(featureSettings);\r
-    viewMenu.addSeparator();\r
-    viewMenu.add(overviewMenuItem);\r
-    colourMenu.add(applyToAllGroups);\r
-    colourMenu.addSeparator();\r
-    colourMenu.add(noColourmenuItem);\r
-    colourMenu.add(clustalColour);\r
-    colourMenu.add(BLOSUM62Colour);\r
-    colourMenu.add(PIDColour);\r
-    colourMenu.add(zappoColour);\r
-    colourMenu.add(taylorColour);\r
-    colourMenu.add(hydrophobicityColour);\r
-    colourMenu.add(helixColour);\r
-    colourMenu.add(strandColour);\r
-    colourMenu.add(turnColour);\r
-    colourMenu.add(buriedColour);\r
-    colourMenu.add(nucleotideColour);\r
-    colourMenu.add(userDefinedColour);\r
-    colourMenu.addSeparator();\r
-    colourMenu.add(annotationColour);\r
-    colourMenu.add(conservationMenuItem);\r
-    colourMenu.add(modifyConservation);\r
-    colourMenu.add(abovePIDThreshold);\r
-    colourMenu.add(modifyPID);\r
-    calculateMenu.add(sort);\r
-    calculateMenu.add(calculate);\r
-    calculateMenu.addSeparator();\r
-    calculateMenu.add(pairwiseAlignmentMenuItem);\r
-    calculateMenu.add(PCAMenuItem);\r
-    calculateMenu.addSeparator();\r
-    calculateMenu.add(showTranslation);\r
-    webServiceNoServices=new JMenuItem("<No Services>");\r
-    webService.add(webServiceNoServices);\r
-    this.getContentPane().add(statusBar, BorderLayout.SOUTH);\r
-  //  this.getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER);\r
-    jMenu1.add(pasteNew);\r
-    jMenu1.add(pasteThis);\r
-    sort.add(sortIDMenuItem);\r
-    sort.add(sortGroupMenuItem);\r
-    sort.add(sortPairwiseMenuItem);\r
-    calculate.add(averageDistanceTreeMenuItem);\r
-    calculate.add(neighbourTreeMenuItem);\r
-    calculate.add(avDistanceTreeBlosumMenuItem);\r
-    calculate.add(njTreeBlosumMenuItem);\r
-    jMenu2.add(htmlMenuItem);\r
-    jMenu2.add(epsFile);\r
-    jMenu2.add(createPNG);\r
-  }\r
-\r
-  protected void outputText_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void closeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void redoMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void undoMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void viewTextMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void overviewMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void sortIDMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void PCAMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void clustalColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void zappoColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void taylorColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void hydrophobicityColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void helixColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void strandColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void turnColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void buriedColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void userDefinedColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void PIDColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void printMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void findMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void abovePIDThreshold_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void showSeqFeatures_actionPerformed(ActionEvent actionEvent)\r
-  {\r
-  }\r
-\r
-  protected void nucleotideColour_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void deleteGroups_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void copy_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void cut_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void delete_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void pasteNew_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void pasteThis_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void createPNG(java.io.File f)\r
-  {\r
-  }\r
-\r
-  protected void font_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void seqLimit_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void seqDBRef_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-\r
-  public void createEPS(java.io.File f)\r
-  {\r
-  }\r
-\r
-  protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void jpred_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void scaleAbove_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void scaleLeft_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void scaleRight_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void modifyPID_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void modifyConservation_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-\r
-\r
-  protected void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void padGapsMenuitem_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-\r
-  public void vamsasStore_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void vamsasLoad_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void showTranslation_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void tabSelected()\r
-  {\r
-\r
-  }\r
-\r
-  public void featureSettings_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void fetchSequence_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void smoothFont_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void annotationColour_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void fetchSeqFeatures_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void associatedData_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+import jalview.schemes.*;
+import java.awt.BorderLayout;
+
+public class GAlignFrame
+    extends JInternalFrame
+{
+  protected JMenuBar alignFrameMenuBar = new JMenuBar();
+  protected JMenu fileMenu = new JMenu();
+  protected JMenuItem closeMenuItem = new JMenuItem();
+  protected JMenu editMenu = new JMenu();
+  protected JMenu viewMenu = new JMenu();
+  protected JMenu colourMenu = new JMenu();
+  protected JMenu calculateMenu = new JMenu();
+  protected JMenu webService = new JMenu();
+  protected JMenuItem webServiceNoServices;
+  protected JMenuItem selectAllSequenceMenuItem = new JMenuItem();
+  protected JMenuItem deselectAllSequenceMenuItem = new JMenuItem();
+  protected JMenuItem invertSequenceMenuItem = new JMenuItem();
+  protected JMenuItem remove2LeftMenuItem = new JMenuItem();
+  protected JMenuItem remove2RightMenuItem = new JMenuItem();
+  protected JMenuItem removeGappedColumnMenuItem = new JMenuItem();
+  protected JMenuItem removeAllGapsMenuItem = new JMenuItem();
+  public JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem();
+  protected JMenuItem sortPairwiseMenuItem = new JMenuItem();
+  protected JMenuItem sortIDMenuItem = new JMenuItem();
+  protected JMenuItem sortGroupMenuItem = new JMenuItem();
+  protected JMenuItem removeRedundancyMenuItem = new JMenuItem();
+  protected JMenuItem pairwiseAlignmentMenuItem = new JMenuItem();
+  protected JMenuItem PCAMenuItem = new JMenuItem();
+  protected JMenuItem averageDistanceTreeMenuItem = new JMenuItem();
+  protected JMenuItem neighbourTreeMenuItem = new JMenuItem();
+  protected JMenuItem clustalAlignMenuItem = new JMenuItem();
+  BorderLayout borderLayout1 = new BorderLayout();
+  public JLabel statusBar = new JLabel();
+  protected JMenuItem saveAlignmentMenu = new JMenuItem();
+  protected JMenu outputTextboxMenu = new JMenu();
+  protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem hydrophobicityColour = new
+      JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
+  protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
+  JMenuItem njTreeBlosumMenuItem = new JMenuItem();
+  JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem();
+  public JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem();
+  JMenuItem htmlMenuItem = new JMenuItem();
+  JMenuItem overviewMenuItem = new JMenuItem();
+  protected JMenuItem undoMenuItem = new JMenuItem();
+  protected JMenuItem redoMenuItem = new JMenuItem();
+  public JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
+  JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
+  public JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem();
+  JMenuItem printMenuItem = new JMenuItem();
+  public JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem();
+  JMenuItem findMenuItem = new JMenuItem();
+  JMenu searchMenu = new JMenu();
+  public JCheckBoxMenuItem abovePIDThreshold = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem();
+  protected JRadioButtonMenuItem nucleotideColour = new JRadioButtonMenuItem();
+  JMenuItem deleteGroups = new JMenuItem();
+  JMenuItem delete = new JMenuItem();
+  JMenuItem copy = new JMenuItem();
+  JMenuItem cut = new JMenuItem();
+  JMenu jMenu1 = new JMenu();
+  JMenuItem pasteNew = new JMenuItem();
+  JMenuItem pasteThis = new JMenuItem();
+  public JCheckBoxMenuItem applyToAllGroups = new JCheckBoxMenuItem();
+  JMenuItem createPNG = new JMenuItem();
+  protected JMenuItem font = new JMenuItem();
+  public JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem();
+  JMenuItem epsFile = new JMenuItem();
+  JMenuItem LoadtreeMenuItem = new JMenuItem();
+  public JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem();
+  protected JMenuItem modifyPID = new JMenuItem();
+  protected JMenuItem modifyConservation = new JMenuItem();
+  protected JMenu sortByTreeMenu = new JMenu();
+  protected JMenu sort = new JMenu();
+  JMenu calculate = new JMenu();
+  JMenu jMenu2 = new JMenu();
+  protected JCheckBoxMenuItem padGapsMenuitem = new JCheckBoxMenuItem();
+  protected ButtonGroup colours = new ButtonGroup();
+  JMenuItem vamsasStore = new JMenuItem();
+  protected JMenuItem showTranslation = new JMenuItem();
+  public JMenuItem featureSettings = new JMenuItem();
+  JMenuItem fetchSequence = new JMenuItem();
+  protected JCheckBoxMenuItem smoothFont = new JCheckBoxMenuItem();
+  JMenuItem annotationColour = new JMenuItem();
+  JMenuItem associatedData = new JMenuItem();
+  protected JCheckBoxMenuItem autoCalculate = new JCheckBoxMenuItem();
+  JMenu addSequenceMenu = new JMenu();
+  JMenuItem addFromFile = new JMenuItem();
+  JMenuItem addFromText = new JMenuItem();
+  JMenuItem addFromURL = new JMenuItem();
+  JMenuItem exportAnnotations = new JMenuItem();
+  JMenuItem exportFeatures = new JMenuItem();
+  protected JPanel statusPanel = new JPanel();
+  GridLayout gridLayout1 = new GridLayout();
+  JMenu jMenu3 = new JMenu();
+  JMenuItem showAllSeqs = new JMenuItem();
+  JMenuItem showAllColumns = new JMenuItem();
+  JMenu jMenu4 = new JMenu();
+  JMenuItem hideSelSequences = new JMenuItem();
+  JMenuItem hideSelColumns = new JMenuItem();
+  protected JCheckBoxMenuItem hiddenMarkers = new JCheckBoxMenuItem();
+  JMenuItem invertColSel = new JMenuItem();
+
+  public GAlignFrame()
+  {
+
+
+    try
+    {
+      jbInit();
+      setJMenuBar(alignFrameMenuBar);
+
+      // dynamically fill save as menu with available formats
+      for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
+      {
+        JMenuItem item = new JMenuItem( jalview.io.FormatAdapter.WRITEABLE_FORMATS[i] );
+
+        item.addActionListener(new java.awt.event.ActionListener()
+        {
+          public void actionPerformed(ActionEvent e)
+          {
+            outputText_actionPerformed(e);
+          }
+        });
+
+        outputTextboxMenu.add(item);
+      }
+    }
+    catch (Exception e)
+    {
+    }
+
+
+    if(jalview.gui.UserDefinedColours.getUserColourSchemes()!=null)
+    {
+      java.util.Enumeration userColours = jalview.gui.UserDefinedColours.
+          getUserColourSchemes().keys();
+
+      while (userColours.hasMoreElements())
+      {
+        final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.
+            nextElement().toString());
+        radioItem.setName("USER_DEFINED");
+        radioItem.addMouseListener(new MouseAdapter()
+            {
+              public void mousePressed(MouseEvent evt)
+              {
+                if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))
+                {
+                  radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+                  int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,
+                      "Remove from default list?",
+                      "Remove user defined colour",
+                      JOptionPane.YES_NO_OPTION);
+                  if(option == JOptionPane.YES_OPTION)
+                  {
+                    jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());
+                    colourMenu.remove(radioItem);
+                  }
+                  else
+                    radioItem.addActionListener(new ActionListener()
+                    {
+                      public void actionPerformed(ActionEvent evt)
+                      {
+                        userDefinedColour_actionPerformed(evt);
+                      }
+                    });
+                }
+              }
+            });
+        radioItem.addActionListener(new ActionListener()
+        {
+          public void actionPerformed(ActionEvent evt)
+          {
+            userDefinedColour_actionPerformed(evt);
+          }
+        });
+        colourMenu.insert(radioItem, 15);
+        colours.add(radioItem);
+      }
+    }
+    colours.add(noColourmenuItem);
+    colours.add(clustalColour);
+    colours.add(zappoColour);
+    colours.add(taylorColour);
+    colours.add(hydrophobicityColour);
+    colours.add(helixColour);
+    colours.add(strandColour);
+    colours.add(turnColour);
+    colours.add(buriedColour);
+    colours.add(userDefinedColour);
+    colours.add(PIDColour);
+    colours.add(BLOSUM62Colour);
+    colours.add(nucleotideColour);
+
+    setColourSelected(jalview.bin.Cache.getDefault("DEFAULT_COLOUR", "None"));
+
+
+  }
+
+  public void setColourSelected(String defaultColour)
+  {
+
+    if (defaultColour != null)
+    {
+      int index = ColourSchemeProperty.getColourIndexFromName(defaultColour);
+
+      switch (index)
+      {
+        case ColourSchemeProperty.NONE:
+              noColourmenuItem.setSelected(true);
+              break;
+        case ColourSchemeProperty.CLUSTAL:
+          clustalColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.BLOSUM:
+          BLOSUM62Colour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.PID:
+          PIDColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.ZAPPO:
+          zappoColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.TAYLOR:
+          taylorColour.setSelected(true);
+          break;
+
+        case ColourSchemeProperty.HYDROPHOBIC:
+          hydrophobicityColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.HELIX:
+          helixColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.STRAND:
+          strandColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.TURN:
+          turnColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.BURIED:
+          buriedColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.NUCLEOTIDE:
+          nucleotideColour.setSelected(true);
+
+          break;
+
+        case ColourSchemeProperty.USER_DEFINED:
+          userDefinedColour.setSelected(true);
+
+          break;
+      }
+    }
+
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    fileMenu.setMnemonic('F');
+    fileMenu.setText("File");
+    saveAlignmentMenu.setMnemonic('L');
+    saveAlignmentMenu.setText("Save As");
+    saveAlignmentMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.
+        awt.event.KeyEvent.VK_S, java.awt.event.KeyEvent.CTRL_MASK, false));
+    saveAlignmentMenu.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        saveAlignmentMenu_actionPerformed(e);
+      }
+    });
+    closeMenuItem.setMnemonic('C');
+    closeMenuItem.setText("Close");
+    closeMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        closeMenuItem_actionPerformed(e);
+      }
+    });
+    editMenu.setText("Edit");
+    viewMenu.setText("View");
+    colourMenu.setText("Colour");
+    calculateMenu.setText("Calculate");
+    webService.setText("Web Service");
+    selectAllSequenceMenuItem.setText("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()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        selectAllSequenceMenuItem_actionPerformed(e);
+      }
+    });
+    deselectAllSequenceMenuItem.setText("Deselect All");
+    deselectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke.
+                                               getKeyStroke(
+        java.awt.event.KeyEvent.VK_ESCAPE, 0, false));
+    deselectAllSequenceMenuItem.addActionListener(new java.awt.event.
+                                                  ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        deselectAllSequenceMenuItem_actionPerformed(e);
+      }
+    });
+    invertSequenceMenuItem.setText("Invert Sequence Selection");
+    invertSequenceMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        invertSequenceMenuItem_actionPerformed(e);
+      }
+    });
+    remove2LeftMenuItem.setText("Remove Left");
+    remove2LeftMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        remove2LeftMenuItem_actionPerformed(e);
+      }
+    });
+    remove2RightMenuItem.setText("Remove Right");
+    remove2RightMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        remove2RightMenuItem_actionPerformed(e);
+      }
+    });
+    removeGappedColumnMenuItem.setText("Remove Empty Columns");
+    removeGappedColumnMenuItem.addActionListener(new java.awt.event.
+                                                 ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        removeGappedColumnMenuItem_actionPerformed(e);
+      }
+    });
+    removeAllGapsMenuItem.setText("Remove All Gaps");
+    removeAllGapsMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        removeAllGapsMenuItem_actionPerformed(e);
+      }
+    });
+    viewBoxesMenuItem.setText("Boxes");
+    viewBoxesMenuItem.setState(true);
+    viewBoxesMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        viewBoxesMenuItem_actionPerformed(e);
+      }
+    });
+    viewTextMenuItem.setText("Text");
+    viewTextMenuItem.setState(true);
+    viewTextMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        viewTextMenuItem_actionPerformed(e);
+      }
+    });
+    sortPairwiseMenuItem.setText("by Pairwise Identity");
+    sortPairwiseMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        sortPairwiseMenuItem_actionPerformed(e);
+      }
+    });
+    sortIDMenuItem.setText("by ID");
+    sortIDMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        sortIDMenuItem_actionPerformed(e);
+      }
+    });
+    sortGroupMenuItem.setText("by Group");
+    sortGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        sortGroupMenuItem_actionPerformed(e);
+      }
+    });
+    removeRedundancyMenuItem.setText("Remove Redundancy...");
+    removeRedundancyMenuItem.addActionListener(new java.awt.event.
+                                               ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        removeRedundancyMenuItem_actionPerformed(e);
+      }
+    });
+    pairwiseAlignmentMenuItem.setText("Pairwise Alignments...");
+    pairwiseAlignmentMenuItem.addActionListener(new java.awt.event.
+                                                ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        pairwiseAlignmentMenuItem_actionPerformed(e);
+      }
+    });
+    PCAMenuItem.setText("Principal Component Analysis");
+    PCAMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        PCAMenuItem_actionPerformed(e);
+      }
+    });
+    averageDistanceTreeMenuItem.setText(
+        "Average Distance Using % Identity");
+    averageDistanceTreeMenuItem.addActionListener(new java.awt.event.
+                                                  ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        averageDistanceTreeMenuItem_actionPerformed(e);
+      }
+    });
+    neighbourTreeMenuItem.setText("Neighbour Joining Using % Identity");
+    neighbourTreeMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      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);
+    statusBar.setFont(new java.awt.Font("Verdana", 0, 11));
+    statusBar.setBorder(BorderFactory.createLineBorder(Color.black));
+    statusBar.setText("Status bar");
+    outputTextboxMenu.setMnemonic('T');
+    outputTextboxMenu.setText("Output to Textbox");
+    clustalColour.setText("Clustalx");
+
+    clustalColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        clustalColour_actionPerformed(e);
+      }
+    });
+    zappoColour.setText("Zappo");
+    zappoColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        zappoColour_actionPerformed(e);
+      }
+    });
+    taylorColour.setText("Taylor");
+    taylorColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        taylorColour_actionPerformed(e);
+      }
+    });
+    hydrophobicityColour.setText("Hydrophobicity");
+    hydrophobicityColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        hydrophobicityColour_actionPerformed(e);
+      }
+    });
+    helixColour.setText("Helix Propensity");
+    helixColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        helixColour_actionPerformed(e);
+      }
+    });
+    strandColour.setText("Strand Propensity");
+    strandColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        strandColour_actionPerformed(e);
+      }
+    });
+    turnColour.setText("Turn Propensity");
+    turnColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        turnColour_actionPerformed(e);
+      }
+    });
+    buriedColour.setText("Buried Index");
+    buriedColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        buriedColour_actionPerformed(e);
+      }
+    });
+    userDefinedColour.setText("User Defined...");
+    userDefinedColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        userDefinedColour_actionPerformed(e);
+      }
+    });
+    PIDColour.setText("Percentage Identity");
+    PIDColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        PIDColour_actionPerformed(e);
+      }
+    });
+    BLOSUM62Colour.setText("BLOSUM62 Score");
+    BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        BLOSUM62Colour_actionPerformed(e);
+      }
+    });
+    avDistanceTreeBlosumMenuItem.setText(
+        "Average Distance Using BLOSUM62");
+    avDistanceTreeBlosumMenuItem.addActionListener(new java.awt.event.
+        ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        avTreeBlosumMenuItem_actionPerformed(e);
+      }
+    });
+    njTreeBlosumMenuItem.setText("Neighbour Joining using BLOSUM62");
+    njTreeBlosumMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        njTreeBlosumMenuItem_actionPerformed(e);
+      }
+    });
+    annotationPanelMenuItem.setActionCommand("");
+    annotationPanelMenuItem.setText("Show Annotations");
+    annotationPanelMenuItem.setState( jalview.bin.Cache.getDefault("SHOW_ANNOTATIONS",true));
+    annotationPanelMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        annotationPanelMenuItem_actionPerformed(e);
+      }
+    });
+    colourTextMenuItem.setText("Colour Text");
+    colourTextMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        colourTextMenuItem_actionPerformed(e);
+      }
+    });
+    htmlMenuItem.setText("HTML");
+    htmlMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        htmlMenuItem_actionPerformed(e);
+      }
+    });
+    overviewMenuItem.setText("Overview Window");
+    overviewMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        overviewMenuItem_actionPerformed(e);
+      }
+    });
+    undoMenuItem.setEnabled(false);
+    undoMenuItem.setMnemonic('Z');
+    undoMenuItem.setText("Undo");
+    undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+        java.awt.event.KeyEvent.VK_Z,
+        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
+    undoMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        undoMenuItem_actionPerformed(e);
+      }
+    });
+    redoMenuItem.setEnabled(false);
+    redoMenuItem.setMnemonic('0');
+    redoMenuItem.setText("Redo");
+    redoMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        redoMenuItem_actionPerformed(e);
+      }
+    });
+    conservationMenuItem.setText("By Conservation");
+    conservationMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        conservationMenuItem_actionPerformed(e);
+      }
+    });
+    noColourmenuItem.setText("None");
+    noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        noColourmenuItem_actionPerformed(e);
+      }
+    });
+    wrapMenuItem.setText("Wrap");
+    wrapMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        wrapMenuItem_actionPerformed(e);
+      }
+    });
+    printMenuItem.setText("Print");
+    printMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        printMenuItem_actionPerformed(e);
+      }
+    });
+    renderGapsMenuItem.setText("Show Gaps");
+    renderGapsMenuItem.setState(true);
+    renderGapsMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        renderGapsMenuItem_actionPerformed(e);
+      }
+    });
+    findMenuItem.setText("Find...");
+    findMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+        java.awt.event.KeyEvent.VK_F,
+        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
+    findMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        findMenuItem_actionPerformed(e);
+      }
+    });
+    searchMenu.setText("Search");
+
+    abovePIDThreshold.setText("Above Identity Threshold");
+    abovePIDThreshold.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        abovePIDThreshold_actionPerformed(e);
+      }
+    });
+    showSeqFeatures.setText("Show Sequence Features");
+    showSeqFeatures.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent actionEvent)
+      {
+        showSeqFeatures_actionPerformed(actionEvent);
+      }
+    });
+    nucleotideColour.setText("Nucleotide");
+    nucleotideColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        nucleotideColour_actionPerformed(e);
+      }
+    });
+    deleteGroups.setText("Undefine groups");
+    deleteGroups.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        deleteGroups_actionPerformed(e);
+      }
+    });
+    copy.setText("Copy");
+    copy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+        java.awt.event.KeyEvent.VK_C,
+        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
+    copy.setMnemonic(KeyEvent.VK_C);
+
+    copy.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        copy_actionPerformed(e);
+      }
+    });
+    cut.setText("Cut");
+    cut.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+        java.awt.event.KeyEvent.VK_X,
+        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
+    cut.setMnemonic(KeyEvent.VK_X);
+    cut.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        cut_actionPerformed(e);
+      }
+    });
+    delete.setText("Delete");
+    delete.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        delete_actionPerformed(e);
+      }
+    });
+    jMenu1.setMnemonic('V');
+    jMenu1.setText("Paste");
+    pasteNew.setText("To New Alignment");
+    pasteNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+        java.awt.event.KeyEvent.VK_V,
+        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
+    pasteNew.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        pasteNew_actionPerformed(e);
+      }
+    });
+    pasteThis.setText("Add To This Alignment");
+    pasteThis.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        pasteThis_actionPerformed(e);
+      }
+    });
+    applyToAllGroups.setText("Apply Colour To All Groups");
+    applyToAllGroups.setState(true);
+    applyToAllGroups.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        applyToAllGroups_actionPerformed(e);
+      }
+    });
+    createPNG.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        createPNG(null);
+      }
+    });
+    createPNG.setActionCommand("Save As PNG Image");
+    createPNG.setText("PNG");
+    font.setText("Font...");
+    font.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        font_actionPerformed(e);
+      }
+    });
+
+    seqLimits.setText("Show Sequence Limits");
+    seqLimits.setState( jalview.bin.Cache.getDefault("SHOW_JVSUFFIX",true));
+    seqLimits.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        seqLimit_actionPerformed(e);
+      }
+    });
+    epsFile.setText("EPS");
+    epsFile.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        createEPS(null);
+      }
+    });
+    LoadtreeMenuItem.setActionCommand("Load a tree for this sequence set");
+    LoadtreeMenuItem.setText("Load Associated Tree");
+    LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        LoadtreeMenuItem_actionPerformed(e);
+      }
+    });
+    scaleAbove.setVisible(false);
+    scaleAbove.setText("Scale Above");
+    scaleAbove.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        scaleAbove_actionPerformed(e);
+      }
+    });
+    scaleLeft.setVisible(false);
+    scaleLeft.setSelected(true);
+    scaleLeft.setText("Scale Left");
+    scaleLeft.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        scaleLeft_actionPerformed(e);
+      }
+    });
+    scaleRight.setVisible(false);
+    scaleRight.setSelected(true);
+    scaleRight.setText("Scale Right");
+    scaleRight.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        scaleRight_actionPerformed(e);
+      }
+    });
+    modifyPID.setText("Modify Identity Threshold...");
+    modifyPID.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        modifyPID_actionPerformed(e);
+      }
+    });
+    modifyConservation.setText("Modify Conservation Threshold...");
+    modifyConservation.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        modifyConservation_actionPerformed(e);
+      }
+    });
+    sortByTreeMenu.setText("By Tree Order");
+    sort.setText("Sort");
+    calculate.setText("Calculate Tree");
+
+    jMenu2.setText("Export");
+    padGapsMenuitem.setText("Pad Gaps");
+    padGapsMenuitem.setState( jalview.bin.Cache.getDefault("PAD_GAPS", false));
+    padGapsMenuitem.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        padGapsMenuitem_actionPerformed(e);
+      }
+    });
+    vamsasStore.setVisible(false);
+    vamsasStore.setText("VAMSAS store");
+    vamsasStore.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        vamsasStore_actionPerformed(e);
+      }
+    });
+    showTranslation.setText("Translate cDNA");
+    showTranslation.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        showTranslation_actionPerformed(e);
+      }
+    });
+
+   /* tabbedPane.addChangeListener(new ChangeListener()
+        {
+          public void stateChanged(ChangeEvent ece)
+          {
+
+            tabSelected();
+          }
+        });*/
+    featureSettings.setText("Feature Settings...");
+    featureSettings.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        featureSettings_actionPerformed(e);
+      }
+    });
+    fetchSequence.setText("Fetch Sequence(s)...");
+    fetchSequence.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        fetchSequence_actionPerformed(e);
+      }
+    });
+    smoothFont.setText("Smooth Fonts");
+    smoothFont.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        smoothFont_actionPerformed(e);
+      }
+    });
+    smoothFont.setState( jalview.bin.Cache.getDefault("ANTI_ALIAS",false));
+    annotationColour.setText("By Annotation...");
+    annotationColour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        annotationColour_actionPerformed(e);
+      }
+    });
+    associatedData.setText("Load Features / Annotations");
+    associatedData.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        associatedData_actionPerformed(e);
+      }
+    });
+    autoCalculate.setText("Autocalculate Consensus");
+    autoCalculate.setState( jalview.bin.Cache.getDefault("AUTO_CALC_CONSENSUS", true));
+    autoCalculate.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        autoCalculate_actionPerformed(e);
+      }
+    });
+    addSequenceMenu.setText("Add Sequences");
+    addFromFile.setText("From File");
+    addFromFile.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        addFromFile_actionPerformed(e);
+      }
+    });
+    addFromText.setText("From Textbox");
+    addFromText.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        addFromText_actionPerformed(e);
+      }
+    });
+    addFromURL.setText("From URL");
+    addFromURL.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        addFromURL_actionPerformed(e);
+      }
+    });
+    exportFeatures.setText("Export Features...");
+    exportFeatures.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        exportFeatures_actionPerformed(e);
+      }
+    });
+    exportAnnotations.setText("Export Annotations...");
+    exportAnnotations.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        exportAnnotations_actionPerformed(e);
+      }
+    });
+    statusPanel.setLayout(gridLayout1);
+    jMenu3.setText("Show");
+    showAllSeqs.setText("All Sequences");
+    showAllSeqs.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        showAllSeqs_actionPerformed(e);
+      }
+    });
+    showAllColumns.setText("All Columns");
+    showAllColumns.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        showAllColumns_actionPerformed(e);
+      }
+    });
+    jMenu4.setText("Hide");
+    hideSelSequences.setText("Selected Sequences");
+    hideSelSequences.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        hideSelSequences_actionPerformed(e);
+      }
+    });
+    hideSelColumns.setText("Selected Columns");
+    hideSelColumns.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        hideSelColumns_actionPerformed(e);
+      }
+    });
+    hiddenMarkers.setText("Hidden Markers");
+    hiddenMarkers.setState(true);
+    hiddenMarkers.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        hiddenMarkers_actionPerformed(e);
+      }
+    });
+    invertColSel.setText("Invert Column Selection");
+    invertColSel.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        invertColSel_actionPerformed(e);
+      }
+    });
+
+    alignFrameMenuBar.add(fileMenu);
+    alignFrameMenuBar.add(editMenu);
+    alignFrameMenuBar.add(searchMenu);
+    alignFrameMenuBar.add(viewMenu);
+    alignFrameMenuBar.add(colourMenu);
+    alignFrameMenuBar.add(calculateMenu);
+    alignFrameMenuBar.add(webService);
+    fileMenu.add(addSequenceMenu);
+    fileMenu.add(fetchSequence);
+    fileMenu.addSeparator();
+    fileMenu.add(vamsasStore);
+    fileMenu.add(saveAlignmentMenu);
+    fileMenu.add(jMenu2);
+    fileMenu.add(outputTextboxMenu);
+    fileMenu.add(printMenuItem);
+    fileMenu.addSeparator();
+    fileMenu.add(exportFeatures);
+    fileMenu.add(exportAnnotations);
+    fileMenu.add(LoadtreeMenuItem);
+    fileMenu.add(associatedData);
+    fileMenu.addSeparator();
+    fileMenu.add(closeMenuItem);
+    editMenu.add(undoMenuItem);
+    editMenu.add(redoMenuItem);
+    editMenu.add(cut);
+    editMenu.add(copy);
+    editMenu.add(jMenu1);
+    editMenu.add(delete);
+    editMenu.addSeparator();
+    editMenu.add(selectAllSequenceMenuItem);
+    editMenu.add(deselectAllSequenceMenuItem);
+    editMenu.add(invertSequenceMenuItem);
+    editMenu.add(invertColSel);
+    editMenu.add(deleteGroups);
+    editMenu.addSeparator();
+    editMenu.add(remove2LeftMenuItem);
+    editMenu.add(remove2RightMenuItem);
+    editMenu.add(removeGappedColumnMenuItem);
+    editMenu.add(removeAllGapsMenuItem);
+    editMenu.add(removeRedundancyMenuItem);
+    editMenu.addSeparator();
+    editMenu.add(padGapsMenuitem);
+    searchMenu.add(findMenuItem);
+    viewMenu.add(font);
+    viewMenu.add(smoothFont);
+    viewMenu.addSeparator();
+    viewMenu.add(jMenu3);
+    viewMenu.add(jMenu4);
+    viewMenu.add(hiddenMarkers);
+    viewMenu.addSeparator();
+    viewMenu.add(wrapMenuItem);
+    viewMenu.add(seqLimits);
+    viewMenu.add(scaleAbove);
+    viewMenu.add(scaleLeft);
+    viewMenu.add(scaleRight);
+    viewMenu.add(viewBoxesMenuItem);
+    viewMenu.add(viewTextMenuItem);
+    viewMenu.add(colourTextMenuItem);
+    viewMenu.add(renderGapsMenuItem);
+    viewMenu.add(annotationPanelMenuItem);
+    viewMenu.addSeparator();
+    viewMenu.add(showSeqFeatures);
+    viewMenu.add(featureSettings);
+    viewMenu.addSeparator();
+    viewMenu.add(overviewMenuItem);
+    colourMenu.add(applyToAllGroups);
+    colourMenu.addSeparator();
+    colourMenu.add(noColourmenuItem);
+    colourMenu.add(clustalColour);
+    colourMenu.add(BLOSUM62Colour);
+    colourMenu.add(PIDColour);
+    colourMenu.add(zappoColour);
+    colourMenu.add(taylorColour);
+    colourMenu.add(hydrophobicityColour);
+    colourMenu.add(helixColour);
+    colourMenu.add(strandColour);
+    colourMenu.add(turnColour);
+    colourMenu.add(buriedColour);
+    colourMenu.add(nucleotideColour);
+    colourMenu.add(userDefinedColour);
+    colourMenu.addSeparator();
+    colourMenu.add(conservationMenuItem);
+    colourMenu.add(modifyConservation);
+    colourMenu.add(abovePIDThreshold);
+    colourMenu.add(modifyPID);
+    colourMenu.add(annotationColour);
+    calculateMenu.add(sort);
+    calculateMenu.add(calculate);
+    calculateMenu.addSeparator();
+    calculateMenu.add(pairwiseAlignmentMenuItem);
+    calculateMenu.add(PCAMenuItem);
+    calculateMenu.addSeparator();
+    calculateMenu.add(showTranslation);
+    calculateMenu.add(autoCalculate);
+    webServiceNoServices=new JMenuItem("<No Services>");
+    webService.add(webServiceNoServices);jMenu1.add(pasteNew);
+    jMenu1.add(pasteThis);
+    sort.add(sortIDMenuItem);
+    sort.add(sortGroupMenuItem);
+    sort.add(sortPairwiseMenuItem);
+    calculate.add(averageDistanceTreeMenuItem);
+    calculate.add(neighbourTreeMenuItem);
+    calculate.add(avDistanceTreeBlosumMenuItem);
+    calculate.add(njTreeBlosumMenuItem);
+    jMenu2.add(htmlMenuItem);
+    jMenu2.add(epsFile);
+    jMenu2.add(createPNG);
+    addSequenceMenu.add(addFromFile);
+    addSequenceMenu.add(addFromText);
+    addSequenceMenu.add(addFromURL);
+    this.getContentPane().add(statusPanel, java.awt.BorderLayout.SOUTH);
+    statusPanel.add(statusBar, null);
+    jMenu3.add(showAllColumns);
+    jMenu3.add(showAllSeqs);
+    jMenu4.add(hideSelColumns);
+    jMenu4.add(hideSelSequences);
+  }
+
+  protected void outputText_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void addFromFile_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void addFromText_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void addFromURL_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void exportFeatures_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void exportAnnotations_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  protected void htmlMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void closeMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void redoMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void undoMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void invertSequenceMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void remove2LeftMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void remove2RightMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void wrapMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void viewBoxesMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void viewTextMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void colourTextMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void annotationPanelMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void overviewMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void sortIDMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void sortGroupMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void PCAMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void clustalColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void zappoColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void taylorColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void hydrophobicityColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void helixColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void strandColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void turnColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void buriedColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void userDefinedColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void PIDColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void BLOSUM62Colour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void noColourmenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void conservationMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void printMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void findMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void abovePIDThreshold_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void showSeqFeatures_actionPerformed(ActionEvent actionEvent)
+  {
+  }
+
+  protected void nucleotideColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void deleteGroups_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void copy_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void cut_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void delete_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void pasteNew_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void pasteThis_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void applyToAllGroups_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void createPNG(java.io.File f)
+  {
+  }
+
+  protected void font_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void seqLimit_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void seqDBRef_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+
+  public void createEPS(java.io.File f)
+  {
+  }
+
+  protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void jpred_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void scaleAbove_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void scaleLeft_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void scaleRight_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void modifyPID_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void modifyConservation_actionPerformed(ActionEvent e)
+  {
+  }
+
+
+
+  protected void saveAlignmentMenu_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void padGapsMenuitem_actionPerformed(ActionEvent e)
+  {
+  }
+
+
+  public void vamsasStore_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void vamsasLoad_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void showTranslation_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void featureSettings_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void fetchSequence_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void smoothFont_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void annotationColour_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+
+  public void associatedData_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void autoCalculate_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void showAllSeqs_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void showAllColumns_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void hideSelSequences_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void hideSelColumns_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void hiddenMarkers_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void findPdbId_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void enterPdbId_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void pdbFile_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void invertColSel_actionPerformed(ActionEvent e)
+  {
+
+  }
+}
index a412125..4cdd9cd 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import javax.swing.*;\r
-import javax.swing.border.*;\r
-\r
-public class GAlignmentPanel\r
-    extends JPanel\r
-{\r
-  protected JPanel sequenceHolderPanel = new JPanel();\r
-  protected JScrollBar vscroll = new JScrollBar();\r
-  protected JScrollBar hscroll = new JScrollBar();\r
-  protected JPanel seqPanelHolder = new JPanel();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  BorderLayout borderLayout3 = new BorderLayout();\r
-  protected JPanel scalePanelHolder = new JPanel();\r
-  protected JPanel idPanelHolder = new JPanel();\r
-  BorderLayout borderLayout5 = new BorderLayout();\r
-  protected JPanel idSpaceFillerPanel1 = new JPanel();\r
-  public JPanel annotationSpaceFillerHolder = new JPanel();\r
-  BorderLayout borderLayout6 = new BorderLayout();\r
-  ButtonGroup buttonGroup1 = new ButtonGroup();\r
-  BorderLayout borderLayout7 = new BorderLayout();\r
-  JPanel hscrollHolder = new JPanel();\r
-  BorderLayout borderLayout10 = new BorderLayout();\r
-  protected JPanel hscrollFillerPanel = new JPanel();\r
-  BorderLayout borderLayout11 = new BorderLayout();\r
-  public JScrollPane annotationScroller = new JScrollPane();\r
-  Border border1;\r
-  BorderLayout borderLayout4 = new BorderLayout();\r
-\r
-  public GAlignmentPanel()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    border1 = BorderFactory.createLineBorder(Color.gray, 1);\r
-    idPanelHolder.setBorder(null);\r
-    idPanelHolder.setPreferredSize(new Dimension(70, 10));\r
-    this.setLayout(borderLayout7);\r
-    sequenceHolderPanel.setMaximumSize(new Dimension(2147483647, 2147483647));\r
-    sequenceHolderPanel.setMinimumSize(new Dimension(150, 150));\r
-    sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));\r
-    sequenceHolderPanel.setLayout(borderLayout3);\r
-    seqPanelHolder.setLayout(borderLayout1);\r
-    scalePanelHolder.setBackground(Color.white);\r
-    scalePanelHolder.setMinimumSize(new Dimension(10, 80));\r
-    scalePanelHolder.setPreferredSize(new Dimension(10, 30));\r
-    scalePanelHolder.setLayout(borderLayout6);\r
-    idPanelHolder.setLayout(borderLayout5);\r
-    idSpaceFillerPanel1.setBackground(Color.white);\r
-    idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));\r
-    idSpaceFillerPanel1.setLayout(borderLayout11);\r
-    annotationSpaceFillerHolder.setBackground(Color.white);\r
-    annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));\r
-    annotationSpaceFillerHolder.setLayout(borderLayout4);\r
-    hscroll.setOrientation(JScrollBar.HORIZONTAL);\r
-    hscrollHolder.setLayout(borderLayout10);\r
-    hscrollFillerPanel.setBackground(Color.white);\r
-    hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));\r
-    hscrollHolder.setBackground(Color.white);\r
-    annotationScroller.setBorder(null);\r
-    annotationScroller.setPreferredSize(new Dimension(10, 80));\r
-    this.setPreferredSize(new Dimension(220, 166));\r
-\r
-    sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);\r
-    sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);\r
-    seqPanelHolder.add(vscroll, BorderLayout.EAST);\r
-    sequenceHolderPanel.add(annotationScroller, BorderLayout.SOUTH);\r
-\r
-    //  jPanel3.add(secondaryPanelHolder,  BorderLayout.SOUTH);\r
-    this.add(idPanelHolder, BorderLayout.WEST);\r
-    idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);\r
-    idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);\r
-    this.add(hscrollHolder, BorderLayout.SOUTH);\r
-    hscrollHolder.add(hscroll, BorderLayout.CENTER);\r
-    hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);\r
-    this.add(sequenceHolderPanel, BorderLayout.CENTER);\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.jbgui;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+
+public class GAlignmentPanel
+    extends JPanel
+{
+  protected JPanel sequenceHolderPanel = new JPanel();
+  protected JScrollBar vscroll = new JScrollBar();
+  protected JScrollBar hscroll = new JScrollBar();
+  protected JPanel seqPanelHolder = new JPanel();
+  BorderLayout borderLayout1 = new BorderLayout();
+  BorderLayout borderLayout3 = new BorderLayout();
+  protected JPanel scalePanelHolder = new JPanel();
+  protected JPanel idPanelHolder = new JPanel();
+  BorderLayout borderLayout5 = new BorderLayout();
+  protected JPanel idSpaceFillerPanel1 = new JPanel();
+  public JPanel annotationSpaceFillerHolder = new JPanel();
+  BorderLayout borderLayout6 = new BorderLayout();
+  ButtonGroup buttonGroup1 = new ButtonGroup();
+  BorderLayout borderLayout7 = new BorderLayout();
+  JPanel hscrollHolder = new JPanel();
+  BorderLayout borderLayout10 = new BorderLayout();
+  protected JPanel hscrollFillerPanel = new JPanel();
+  BorderLayout borderLayout11 = new BorderLayout();
+  public JScrollPane annotationScroller = new JScrollPane();
+  Border border1;
+  BorderLayout borderLayout4 = new BorderLayout();
+
+  public GAlignmentPanel()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    border1 = BorderFactory.createLineBorder(Color.gray, 1);
+    idPanelHolder.setBorder(null);
+    idPanelHolder.setPreferredSize(new Dimension(70, 10));
+    this.setLayout(borderLayout7);
+    sequenceHolderPanel.setMaximumSize(new Dimension(2147483647, 2147483647));
+    sequenceHolderPanel.setMinimumSize(new Dimension(150, 150));
+    sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
+    sequenceHolderPanel.setLayout(borderLayout3);
+    seqPanelHolder.setLayout(borderLayout1);
+    scalePanelHolder.setBackground(Color.white);
+    scalePanelHolder.setMinimumSize(new Dimension(10, 80));
+    scalePanelHolder.setPreferredSize(new Dimension(10, 30));
+    scalePanelHolder.setLayout(borderLayout6);
+    idPanelHolder.setLayout(borderLayout5);
+    idSpaceFillerPanel1.setBackground(Color.white);
+    idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
+    idSpaceFillerPanel1.setLayout(borderLayout11);
+    annotationSpaceFillerHolder.setBackground(Color.white);
+    annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
+    annotationSpaceFillerHolder.setLayout(borderLayout4);
+    hscroll.setOrientation(JScrollBar.HORIZONTAL);
+    hscrollHolder.setLayout(borderLayout10);
+    hscrollFillerPanel.setBackground(Color.white);
+    hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
+    hscrollHolder.setBackground(Color.white);
+    annotationScroller.setBorder(null);
+    annotationScroller.setPreferredSize(new Dimension(10, 80));
+    this.setPreferredSize(new Dimension(220, 166));
+
+    sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
+    sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
+    seqPanelHolder.add(vscroll, BorderLayout.EAST);
+    sequenceHolderPanel.add(annotationScroller, BorderLayout.SOUTH);
+
+    //  jPanel3.add(secondaryPanelHolder,  BorderLayout.SOUTH);
+    this.add(idPanelHolder, BorderLayout.WEST);
+    idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
+    idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
+    this.add(hscrollHolder, BorderLayout.SOUTH);
+    hscrollHolder.add(hscroll, BorderLayout.CENTER);
+    hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
+    this.add(sequenceHolderPanel, BorderLayout.CENTER);
+  }
+}
index a917ebe..b037919 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import java.beans.PropertyChangeEvent;\r
-import java.beans.PropertyVetoException;\r
-import java.beans.VetoableChangeListener;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GCutAndPasteTransfer extends JInternalFrame\r
-{\r
-    protected JTextArea textarea = new JTextArea();\r
-    protected JScrollPane scrollPane = new JScrollPane();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-    JMenuBar editMenubar = new JMenuBar();\r
-    JMenu editMenu = new JMenu();\r
-    JMenuItem copyItem = new JMenuItem();\r
-    JMenuItem pasteMenu = new JMenuItem();\r
-    BorderLayout borderLayout2 = new BorderLayout();\r
-    protected JPanel inputButtonPanel = new JPanel();\r
-    JButton ok = new JButton();\r
-    JButton cancel = new JButton();\r
-  JMenuItem selectAll = new JMenuItem();\r
-\r
-  /**\r
-     * Creates a new GCutAndPasteTransfer object.\r
-     */\r
-    public GCutAndPasteTransfer()\r
-    {\r
-        try\r
-        {\r
-            setJMenuBar(editMenubar);\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        scrollPane.setBorder(null);\r
-        ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-        ok.setText("Accept");\r
-        ok.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    ok_actionPerformed(e);\r
-                }\r
-            });\r
-        cancel.setText("Cancel");\r
-        cancel.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    cancel_actionPerformed(e);\r
-                }\r
-            });\r
-        textarea.setBorder(null);\r
-        textarea.addVetoableChangeListener(new VetoableChangeListener()\r
-            {\r
-                public void vetoableChange(PropertyChangeEvent evt)\r
-                {\r
-                    try\r
-                    {\r
-                        textarea_vetoableChange(evt);\r
-                    }\r
-                    catch (java.beans.PropertyVetoException exception0)\r
-                    {\r
-                        exception0.printStackTrace();\r
-                    }\r
-                }\r
-            });\r
-    selectAll.setText("Select All");\r
-    selectAll.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        selectAll_actionPerformed(e);\r
-      }\r
-    });\r
-    editMenubar.add(editMenu);\r
-        textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));\r
-        textarea.addMouseListener(new java.awt.event.MouseAdapter()\r
-            {\r
-                public void mousePressed(MouseEvent e)\r
-                {\r
-                    textarea_mousePressed(e);\r
-                }\r
-            });\r
-        editMenu.setText("Edit");\r
-        pasteMenu.setText("Paste");\r
-        pasteMenu.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    pasteMenu_actionPerformed(e);\r
-                }\r
-            });\r
-        copyItem.setText("Copy");\r
-        copyItem.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    copyItem_actionPerformed(e);\r
-                }\r
-            });\r
-        this.getContentPane().setLayout(borderLayout2);\r
-        scrollPane.setBorder(null);\r
-        scrollPane.getViewport().add(textarea, null);\r
-    editMenu.add(selectAll);\r
-    editMenu.add(copyItem);\r
-        editMenu.add(pasteMenu);\r
-        this.getContentPane().add(scrollPane, java.awt.BorderLayout.CENTER);\r
-        inputButtonPanel.add(ok);\r
-        inputButtonPanel.add(cancel);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void textarea_mousePressed(MouseEvent e)\r
-    {\r
-\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void copyItem_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void pasteMenu_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void ok_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param evt DOCUMENT ME!\r
-     *\r
-     * @throws PropertyVetoException DOCUMENT ME!\r
-     */\r
-    public void textarea_vetoableChange(PropertyChangeEvent evt)\r
-        throws PropertyVetoException\r
-    {\r
-    }\r
-\r
-    public void selectAll_actionPerformed(ActionEvent e)\r
-    {\r
-      textarea.selectAll();\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GCutAndPasteTransfer extends JInternalFrame
+{
+    protected JTextArea textarea = new JTextArea();
+    protected JScrollPane scrollPane = new JScrollPane();
+    BorderLayout borderLayout1 = new BorderLayout();
+    JMenuBar editMenubar = new JMenuBar();
+    JMenu editMenu = new JMenu();
+    JMenuItem copyItem = new JMenuItem();
+    JMenuItem pasteMenu = new JMenuItem();
+    BorderLayout borderLayout2 = new BorderLayout();
+    protected JPanel inputButtonPanel = new JPanel();
+    JButton ok = new JButton();
+    JButton cancel = new JButton();
+  JMenuItem selectAll = new JMenuItem();
+  JMenu jMenu1 = new JMenu();
+  JMenuItem save = new JMenuItem();
+
+  /**
+     * Creates a new GCutAndPasteTransfer object.
+     */
+    public GCutAndPasteTransfer()
+    {
+        try
+        {
+            setJMenuBar(editMenubar);
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        scrollPane.setBorder(null);
+        ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+        ok.setText("Accept");
+        ok.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    ok_actionPerformed(e);
+                }
+            });
+        cancel.setText("Close");
+        cancel.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    cancel_actionPerformed(e);
+                }
+            });
+        textarea.setBorder(null);
+
+    selectAll.setText("Select All");
+    selectAll.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        selectAll_actionPerformed(e);
+      }
+    });
+    jMenu1.setText("File");
+    save.setText("Save");
+    save.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        save_actionPerformed(e);
+      }
+    });
+    editMenubar.add(jMenu1);
+    editMenubar.add(editMenu);
+        textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
+        textarea.addMouseListener(new java.awt.event.MouseAdapter()
+            {
+                public void mousePressed(MouseEvent e)
+                {
+                    textarea_mousePressed(e);
+                }
+            });
+        editMenu.setText("Edit");
+        pasteMenu.setText("Paste");
+        pasteMenu.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    pasteMenu_actionPerformed(e);
+                }
+            });
+        copyItem.setText("Copy");
+        copyItem.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    copyItem_actionPerformed(e);
+                }
+            });
+        this.getContentPane().setLayout(borderLayout2);
+        scrollPane.setBorder(null);
+        scrollPane.getViewport().add(textarea, null);
+    editMenu.add(selectAll);
+    editMenu.add(copyItem);
+        editMenu.add(pasteMenu);
+        this.getContentPane().add(scrollPane, java.awt.BorderLayout.CENTER);
+        inputButtonPanel.add(ok);
+        inputButtonPanel.add(cancel);
+    jMenu1.add(save);
+  }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void textarea_mousePressed(MouseEvent e)
+    {
+
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void copyItem_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void pasteMenu_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void ok_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void cancel_actionPerformed(ActionEvent e)
+    {
+    }
+
+
+    public void selectAll_actionPerformed(ActionEvent e)
+    {
+      textarea.selectAll();
+    }
+
+  public void save_actionPerformed(ActionEvent e)
+  {
+
+  }
+}
index 499efd5..a52da7f 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GDesktop extends JFrame\r
-{\r
-    protected static JMenu windowMenu = new JMenu();\r
-    JMenuBar DesktopMenubar = new JMenuBar();\r
-    JMenu FileMenu = new JMenu();\r
-    JMenu HelpMenu = new JMenu();\r
-    protected JMenu VamsasMenu = new JMenu();\r
-    JMenuItem inputLocalFileMenuItem = new JMenuItem();\r
-    JMenuItem inputURLMenuItem = new JMenuItem();\r
-    JMenuItem inputTextboxMenuItem = new JMenuItem();\r
-    JMenuItem quit = new JMenuItem();\r
-    JMenuItem aboutMenuItem = new JMenuItem();\r
-    JMenuItem documentationMenuItem = new JMenuItem();\r
-    FlowLayout flowLayout1 = new FlowLayout();\r
-    JMenu toolsMenu = new JMenu();\r
-    JMenuItem preferences = new JMenuItem();\r
-    JMenuItem saveState = new JMenuItem();\r
-    JMenuItem loadState = new JMenuItem();\r
-    JMenu jMenu1 = new JMenu();\r
-  protected JMenuItem vamsasLoad = new JMenuItem();\r
-  JMenuItem inputSequence = new JMenuItem();\r
-  protected JMenuItem vamsasStop = new JMenuItem();\r
-\r
-  /**\r
-     * Creates a new GDesktop object.\r
-     */\r
-    public GDesktop()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-            this.setJMenuBar(DesktopMenubar);\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        FileMenu.setMnemonic('F');\r
-        FileMenu.setText("File");\r
-        HelpMenu.setText("Help");\r
-        VamsasMenu.setText("Vamsas");\r
-        VamsasMenu.setMnemonic('V');\r
-        VamsasMenu.setToolTipText("Share data with other vamsas applications.");\r
-        inputLocalFileMenuItem.setMnemonic('L');\r
-        inputLocalFileMenuItem.setText("from File");\r
-        inputLocalFileMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    inputLocalFileMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-        inputURLMenuItem.setMnemonic('U');\r
-        inputURLMenuItem.setText("from URL");\r
-        inputURLMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    inputURLMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-        inputTextboxMenuItem.setMnemonic('C');\r
-        inputTextboxMenuItem.setText("from Textbox");\r
-        inputTextboxMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    inputTextboxMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-        quit.setMnemonic('Q');\r
-        quit.setText("Quit");\r
-        quit.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    quit();\r
-                }\r
-            });\r
-        aboutMenuItem.setText("About");\r
-        aboutMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    aboutMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-        documentationMenuItem.setText("Documentation");\r
-        documentationMenuItem.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    documentationMenuItem_actionPerformed(e);\r
-                }\r
-            });\r
-        this.getContentPane().setLayout(flowLayout1);\r
-        windowMenu.setText("Window");\r
-        preferences.setText("Preferences...");\r
-        preferences.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    preferences_actionPerformed(e);\r
-                }\r
-            });\r
-        toolsMenu.setText("Tools");\r
-        saveState.setMnemonic('S');\r
-        saveState.setText("Save Project");\r
-        saveState.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    saveState_actionPerformed(e);\r
-                }\r
-            });\r
-        loadState.setMnemonic('L');\r
-        loadState.setText("Load Project");\r
-        loadState.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    loadState_actionPerformed(e);\r
-                }\r
-            });\r
-        jMenu1.setMnemonic('I');\r
-        jMenu1.setText("Input Alignment");\r
-    vamsasLoad.setText("Start Vamsas Session...");\r
-    vamsasLoad.setVisible(true);\r
-    vamsasLoad.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        vamsasLoad_actionPerformed(e);\r
-      }\r
-    });\r
-    inputSequence.setText("Fetch Sequence(s)...");\r
-    inputSequence.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        inputSequence_actionPerformed(e);\r
-      }\r
-    });\r
-    vamsasStop.setText("Stop Vamsas Session");\r
-    vamsasStop.setVisible(false);\r
-    vamsasStop.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        vamsasStop_actionPerformed(e);\r
-      }\r
-    });    DesktopMenubar.add(FileMenu);\r
-        DesktopMenubar.add(toolsMenu);\r
-        DesktopMenubar.add(VamsasMenu);\r
-        DesktopMenubar.add(HelpMenu);\r
-        DesktopMenubar.add(windowMenu);\r
-        FileMenu.addSeparator();\r
-        FileMenu.add(jMenu1);\r
-    FileMenu.add(inputSequence);\r
-    FileMenu.addSeparator();\r
-        FileMenu.add(saveState);\r
-        FileMenu.add(loadState);\r
-    FileMenu.addSeparator();\r
-    FileMenu.add(quit);\r
-        HelpMenu.add(aboutMenuItem);\r
-        HelpMenu.add(documentationMenuItem);\r
-        VamsasMenu.add(vamsasLoad);\r
-        VamsasMenu.add(vamsasStop);\r
-        toolsMenu.add(preferences);\r
-        jMenu1.add(inputLocalFileMenuItem);\r
-        jMenu1.add(inputURLMenuItem);\r
-        jMenu1.add(inputTextboxMenuItem);\r
-      }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void inputLocalFileMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void inputURLMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void inputTextboxMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    protected void quit()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void aboutMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void documentationMenuItem_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void SaveState_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void preferences_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void saveState_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void loadState_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void loadJalviewAlign_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-  public void vamsasLoad_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void inputSequence_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-  public void vamsasStop_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GDesktop extends JFrame
+{
+    protected static JMenu windowMenu = new JMenu();
+    JMenuBar DesktopMenubar = new JMenuBar();
+    JMenu FileMenu = new JMenu();
+    JMenu HelpMenu = new JMenu();
+    protected JMenu VamsasMenu = new JMenu();
+    JMenuItem inputLocalFileMenuItem = new JMenuItem();
+    JMenuItem inputURLMenuItem = new JMenuItem();
+    JMenuItem inputTextboxMenuItem = new JMenuItem();
+    JMenuItem quit = new JMenuItem();
+    JMenuItem aboutMenuItem = new JMenuItem();
+    JMenuItem documentationMenuItem = new JMenuItem();
+    FlowLayout flowLayout1 = new FlowLayout();
+    JMenu toolsMenu = new JMenu();
+    JMenuItem preferences = new JMenuItem();
+    JMenuItem saveState = new JMenuItem();
+    JMenuItem loadState = new JMenuItem();
+    JMenu jMenu1 = new JMenu();
+  protected JMenuItem vamsasLoad = new JMenuItem();
+  JMenuItem inputSequence = new JMenuItem();
+  protected JMenuItem vamsasStop = new JMenuItem();
+
+  /**
+     * Creates a new GDesktop object.
+     */
+    public GDesktop()
+    {
+        try
+        {
+            jbInit();
+            this.setJMenuBar(DesktopMenubar);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        FileMenu.setMnemonic('F');
+        FileMenu.setText("File");
+        HelpMenu.setText("Help");
+        VamsasMenu.setText("Vamsas");
+        VamsasMenu.setMnemonic('V');
+        VamsasMenu.setToolTipText("Share data with other vamsas applications.");
+        inputLocalFileMenuItem.setMnemonic('L');
+        inputLocalFileMenuItem.setText("from File");
+        inputLocalFileMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    inputLocalFileMenuItem_actionPerformed(null);
+                }
+            });
+        inputURLMenuItem.setMnemonic('U');
+        inputURLMenuItem.setText("from URL");
+        inputURLMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    inputURLMenuItem_actionPerformed(null);
+                }
+            });
+        inputTextboxMenuItem.setMnemonic('C');
+        inputTextboxMenuItem.setText("from Textbox");
+        inputTextboxMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    inputTextboxMenuItem_actionPerformed(null);
+                }
+            });
+        quit.setMnemonic('Q');
+        quit.setText("Quit");
+        quit.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    quit();
+                }
+            });
+        aboutMenuItem.setText("About");
+        aboutMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    aboutMenuItem_actionPerformed(e);
+                }
+            });
+        documentationMenuItem.setText("Documentation");
+        documentationMenuItem.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    documentationMenuItem_actionPerformed(e);
+                }
+            });
+        this.getContentPane().setLayout(flowLayout1);
+        windowMenu.setText("Window");
+        preferences.setText("Preferences...");
+        preferences.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    preferences_actionPerformed(e);
+                }
+            });
+        toolsMenu.setText("Tools");
+        saveState.setMnemonic('S');
+        saveState.setText("Save Project");
+        saveState.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    saveState_actionPerformed(e);
+                }
+            });
+        loadState.setMnemonic('L');
+        loadState.setText("Load Project");
+        loadState.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    loadState_actionPerformed(e);
+                }
+            });
+        jMenu1.setMnemonic('I');
+        jMenu1.setText("Input Alignment");
+    vamsasLoad.setText("Start Vamsas Session...");
+    vamsasLoad.setVisible(true);
+    vamsasLoad.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        vamsasLoad_actionPerformed(e);
+      }
+    });
+    inputSequence.setText("Fetch Sequence(s)...");
+    inputSequence.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        inputSequence_actionPerformed(e);
+      }
+    });
+    vamsasStop.setText("Stop Vamsas Session");
+    vamsasStop.setVisible(false);
+    vamsasStop.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        vamsasStop_actionPerformed(e);
+      }
+    });    DesktopMenubar.add(FileMenu);
+        DesktopMenubar.add(toolsMenu);
+        DesktopMenubar.add(VamsasMenu);
+        DesktopMenubar.add(HelpMenu);
+        DesktopMenubar.add(windowMenu);
+        FileMenu.addSeparator();
+        FileMenu.add(jMenu1);
+    FileMenu.add(inputSequence);
+    FileMenu.addSeparator();
+        FileMenu.add(saveState);
+        FileMenu.add(loadState);
+    FileMenu.addSeparator();
+    FileMenu.add(quit);
+        HelpMenu.add(aboutMenuItem);
+        HelpMenu.add(documentationMenuItem);
+        VamsasMenu.add(vamsasLoad);
+        VamsasMenu.add(vamsasStop);
+        toolsMenu.add(preferences);
+        jMenu1.add(inputLocalFileMenuItem);
+        jMenu1.add(inputURLMenuItem);
+        jMenu1.add(inputTextboxMenuItem);
+      }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void inputLocalFileMenuItem_actionPerformed(jalview.gui.AlignViewport av)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void inputURLMenuItem_actionPerformed(jalview.gui.AlignViewport av)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void inputTextboxMenuItem_actionPerformed(jalview.gui.AlignViewport av)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    protected void quit()
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void aboutMenuItem_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void documentationMenuItem_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void SaveState_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void preferences_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void saveState_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void loadState_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void loadJalviewAlign_actionPerformed(ActionEvent e)
+    {
+    }
+
+  public void vamsasLoad_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void inputSequence_actionPerformed(ActionEvent e)
+  {
+
+  }
+  public void vamsasStop_actionPerformed(ActionEvent e)
+  {
+
+  }
+}
index c0b5d0e..07ffbe3 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import javax.swing.*;\r
-import javax.swing.event.*;\r
-import jalview.io.FormatAdapter;\r
-import jalview.datamodel.SequenceI;\r
-\r
-public class GFinder\r
-    extends JPanel\r
-{\r
-  JLabel jLabel1 = new JLabel();\r
-  protected JButton findAll = new JButton();\r
-  protected JButton findNext = new JButton();\r
-  JPanel jPanel1 = new JPanel();\r
-  GridLayout gridLayout1 = new GridLayout();\r
-  protected JButton createNewGroup = new JButton();\r
-  JScrollPane jScrollPane1 = new JScrollPane();\r
-  protected JTextArea textfield = new JTextArea();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  JPanel jPanel2 = new JPanel();\r
-  JPanel jPanel3 = new JPanel();\r
-  JPanel jPanel4 = new JPanel();\r
-  BorderLayout borderLayout2 = new BorderLayout();\r
-  JPanel jPanel5 = new JPanel();\r
-  JPanel jPanel6 = new JPanel();\r
-  public GFinder()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel1.setText("Find");\r
-    this.setLayout(borderLayout1);\r
-    findAll.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    findAll.setText("Find all");\r
-    findAll.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        findAll_actionPerformed(e);\r
-      }\r
-    });\r
-    findNext.setEnabled(false);\r
-    findNext.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    findNext.setText("Find Next");\r
-    findNext.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        findNext_actionPerformed(e);\r
-      }\r
-    });\r
-    jPanel1.setLayout(gridLayout1);\r
-    gridLayout1.setHgap(0);\r
-    gridLayout1.setRows(3);\r
-    gridLayout1.setVgap(2);\r
-    createNewGroup.setEnabled(false);\r
-    createNewGroup.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    createNewGroup.setToolTipText("");\r
-    createNewGroup.setMargin(new Insets(0, 0, 0, 0));\r
-    createNewGroup.setText("New Feature");\r
-    createNewGroup.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        createNewGroup_actionPerformed(e);\r
-      }\r
-    });\r
-    textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 12));\r
-    textfield.setText("");\r
-    textfield.setLineWrap(true);\r
-    textfield.addCaretListener(new CaretListener()\r
-    {\r
-      public void caretUpdate(CaretEvent e)\r
-      {\r
-        textfield_caretUpdate(e);\r
-      }\r
-    });\r
-    textfield.addKeyListener(new java.awt.event.KeyAdapter() {\r
-        public void keyPressed(KeyEvent e) {\r
-            textfield_keyPressed(e);\r
-        }\r
-    });\r
-\r
-    borderLayout1.setHgap(5);\r
-    borderLayout1.setVgap(5);\r
-    jPanel4.setLayout(borderLayout2);\r
-    jPanel2.setPreferredSize(new Dimension(10, 1));\r
-    jPanel3.setPreferredSize(new Dimension(10, 1));\r
-    jPanel1.add(findNext, null);\r
-    jPanel1.add(findAll, null);\r
-    jPanel1.add(createNewGroup, null);\r
-    this.add(jLabel1, java.awt.BorderLayout.WEST);\r
-    this.add(jPanel1, java.awt.BorderLayout.EAST);\r
-    this.add(jPanel2, java.awt.BorderLayout.SOUTH);\r
-    this.add(jPanel3, java.awt.BorderLayout.NORTH);\r
-    this.add(jPanel4, java.awt.BorderLayout.CENTER);\r
-    jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER);\r
-    jPanel4.add(jPanel5, java.awt.BorderLayout.SOUTH);\r
-    jPanel4.add(jPanel6, java.awt.BorderLayout.NORTH);\r
-    jScrollPane1.getViewport().add(textfield);\r
-  }\r
-\r
-  protected void findNext_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void findAll_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-\r
-  protected void textfield_keyPressed(KeyEvent e)\r
-  {\r
-\r
-    if(e.getKeyCode()==KeyEvent.VK_ENTER)\r
-    {\r
-      e.consume();\r
-      findNext_actionPerformed(null);\r
-    }\r
-    findNext.setEnabled(true);\r
-  }\r
-\r
-  public void createNewGroup_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void textfield_caretUpdate(CaretEvent e)\r
-  {\r
-    if (textfield.getText().indexOf(">") > -1)\r
-    {\r
-      SwingUtilities.invokeLater(new Runnable()\r
-      {\r
-        public void run()\r
-        {\r
-          String str = textfield.getText();\r
-          SequenceI[] sequences = null;\r
-          try{sequences = new FormatAdapter().readFile(str, "Paste", "FASTA");}\r
-          catch(Exception ex){}\r
-          if(sequences!=null && sequences.length>0)\r
-          {\r
-            str = jalview.analysis.AlignSeq.extractGaps(\r
-                jalview.util.Comparison.GapChars, sequences[0].getSequence());\r
-\r
-            textfield.setText(str);\r
-          }\r
-        }\r
-      });\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import jalview.io.FormatAdapter;
+import jalview.datamodel.SequenceI;
+import java.awt.BorderLayout;
+
+public class GFinder
+    extends JPanel
+{
+  JLabel jLabel1 = new JLabel();
+  protected JButton findAll = new JButton();
+  protected JButton findNext = new JButton();
+  JPanel jPanel1 = new JPanel();
+  GridLayout gridLayout1 = new GridLayout();
+  protected JButton createNewGroup = new JButton();
+  JScrollPane jScrollPane1 = new JScrollPane();
+  protected JTextArea textfield = new JTextArea();
+  BorderLayout borderLayout1 = new BorderLayout();
+  JPanel jPanel2 = new JPanel();
+  JPanel jPanel3 = new JPanel();
+  JPanel jPanel4 = new JPanel();
+  BorderLayout borderLayout2 = new BorderLayout();
+  JPanel jPanel6 = new JPanel();
+  protected JCheckBox caseSensitive = new JCheckBox();
+  public GFinder()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel1.setText("Find");
+    this.setLayout(borderLayout1);
+    findAll.setFont(new java.awt.Font("Verdana", 0, 12));
+    findAll.setText("Find all");
+    findAll.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        findAll_actionPerformed(e);
+      }
+    });
+    findNext.setEnabled(false);
+    findNext.setFont(new java.awt.Font("Verdana", 0, 12));
+    findNext.setText("Find Next");
+    findNext.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        findNext_actionPerformed(e);
+      }
+    });
+    jPanel1.setLayout(gridLayout1);
+    gridLayout1.setHgap(0);
+    gridLayout1.setRows(3);
+    gridLayout1.setVgap(2);
+    createNewGroup.setEnabled(false);
+    createNewGroup.setFont(new java.awt.Font("Verdana", 0, 12));
+    createNewGroup.setToolTipText("");
+    createNewGroup.setMargin(new Insets(0, 0, 0, 0));
+    createNewGroup.setText("New Feature");
+    createNewGroup.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        createNewGroup_actionPerformed(e);
+      }
+    });
+    textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 12));
+    textfield.setText("");
+    textfield.setLineWrap(true);
+    textfield.addCaretListener(new CaretListener()
+    {
+      public void caretUpdate(CaretEvent e)
+      {
+        textfield_caretUpdate(e);
+      }
+    });
+    textfield.addKeyListener(new java.awt.event.KeyAdapter() {
+        public void keyPressed(KeyEvent e) {
+            textfield_keyPressed(e);
+        }
+    });
+
+    borderLayout1.setHgap(5);
+    borderLayout1.setVgap(5);
+    jPanel4.setLayout(borderLayout2);
+    jPanel2.setPreferredSize(new Dimension(10, 1));
+    jPanel3.setPreferredSize(new Dimension(10, 1));
+    caseSensitive.setHorizontalAlignment(SwingConstants.LEFT);
+    caseSensitive.setText("Match Case");
+    jPanel1.add(findNext, null);
+    jPanel1.add(findAll, null);
+    jPanel1.add(createNewGroup, null);
+    this.add(jLabel1, java.awt.BorderLayout.WEST);
+    this.add(jPanel1, java.awt.BorderLayout.EAST);
+    this.add(jPanel2, java.awt.BorderLayout.SOUTH);
+    this.add(jPanel3, java.awt.BorderLayout.NORTH);
+    this.add(jPanel4, java.awt.BorderLayout.CENTER);
+    jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER);
+    jScrollPane1.getViewport().add(textfield);
+    jPanel4.add(jPanel6, java.awt.BorderLayout.NORTH);
+    jPanel4.add(caseSensitive, java.awt.BorderLayout.SOUTH);
+  }
+
+  protected void findNext_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void findAll_actionPerformed(ActionEvent e)
+  {
+  }
+
+
+  protected void textfield_keyPressed(KeyEvent e)
+  {
+
+    if(e.getKeyCode()==KeyEvent.VK_ENTER)
+    {
+      e.consume();
+      findNext_actionPerformed(null);
+    }
+    findNext.setEnabled(true);
+  }
+
+  public void createNewGroup_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void textfield_caretUpdate(CaretEvent e)
+  {
+    if (textfield.getText().indexOf(">") > -1)
+    {
+      SwingUtilities.invokeLater(new Runnable()
+      {
+        public void run()
+        {
+          String str = textfield.getText();
+          SequenceI[] sequences = null;
+          try{sequences = new FormatAdapter().readFile(str, "Paste", "FASTA");}
+          catch(Exception ex){}
+          if(sequences!=null && sequences.length>0)
+          {
+            str = jalview.analysis.AlignSeq.extractGaps(
+                jalview.util.Comparison.GapChars, sequences[0].getSequence());
+
+            textfield.setText(str);
+          }
+        }
+      });
+    }
+  }
+}
index 38bddef..c283e19 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GFontChooser extends JPanel\r
-{\r
-    JLabel jLabel1 = new JLabel();\r
-    protected JComboBox fontSize = new JComboBox();\r
-    protected JComboBox fontStyle = new JComboBox();\r
-    JLabel jLabel2 = new JLabel();\r
-    JLabel jLabel3 = new JLabel();\r
-    protected JComboBox fontName = new JComboBox();\r
-    JButton ok = new JButton();\r
-    JButton cancel = new JButton();\r
-    JPanel jPanel1 = new JPanel();\r
-    JPanel jPanel2 = new JPanel();\r
-    JPanel jPanel3 = new JPanel();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-    BorderLayout borderLayout2 = new BorderLayout();\r
-    BorderLayout borderLayout3 = new BorderLayout();\r
-    FlowLayout flowLayout1 = new FlowLayout();\r
-    protected JButton defaultButton = new JButton();\r
-   protected  JCheckBox monospaced = new JCheckBox();\r
-  BorderLayout borderLayout4 = new BorderLayout();\r
-\r
-  /**\r
-     * Creates a new GFontChooser object.\r
-     */\r
-    public GFontChooser()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        jLabel1.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        jLabel1.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        jLabel1.setText("Font: ");\r
-        jLabel1.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);\r
-        this.setLayout(flowLayout1);\r
-        fontSize.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        fontSize.setOpaque(false);\r
-        fontSize.setPreferredSize(new Dimension(50, 21));\r
-        fontSize.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    fontSize_actionPerformed(e);\r
-                }\r
-            });\r
-        fontStyle.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        fontStyle.setOpaque(false);\r
-        fontStyle.setPreferredSize(new Dimension(90, 21));\r
-        fontStyle.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    fontStyle_actionPerformed(e);\r
-                }\r
-            });\r
-        jLabel2.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        jLabel2.setText("Size: ");\r
-        jLabel2.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);\r
-        jLabel3.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        jLabel3.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        jLabel3.setText("Style: ");\r
-        jLabel3.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);\r
-        fontName.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        fontName.setMaximumSize(new Dimension(32767, 32767));\r
-        fontName.setMinimumSize(new Dimension(300, 21));\r
-        fontName.setOpaque(false);\r
-        fontName.setPreferredSize(new Dimension(180, 21));\r
-        fontName.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    fontName_actionPerformed(e);\r
-                }\r
-            });\r
-        ok.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        ok.setText("OK");\r
-        ok.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    ok_actionPerformed(e);\r
-                }\r
-            });\r
-        cancel.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        cancel.setText("Cancel");\r
-        cancel.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    cancel_actionPerformed(e);\r
-                }\r
-            });\r
-        this.setBackground(Color.white);\r
-        jPanel1.setOpaque(false);\r
-        jPanel1.setLayout(borderLayout1);\r
-        jPanel2.setOpaque(false);\r
-        jPanel2.setLayout(borderLayout3);\r
-        jPanel3.setOpaque(false);\r
-        jPanel3.setLayout(borderLayout2);\r
-        flowLayout1.setAlignment(FlowLayout.CENTER);\r
-    flowLayout1.setHgap(1);\r
-    flowLayout1.setVgap(5);\r
-    defaultButton.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    defaultButton.setText("Set as Default");\r
-        defaultButton.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    defaultButton_actionPerformed(e);\r
-                }\r
-            });\r
-    monospaced.setEnabled(false);\r
-    monospaced.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    monospaced.setOpaque(false);\r
-    monospaced.setToolTipText("Monospaced fonts are faster to render");\r
-    monospaced.setText("Monospaced");\r
-    this.add(jPanel1, null);\r
-        jPanel1.add(jLabel1, BorderLayout.WEST);\r
-        jPanel1.add(fontName, BorderLayout.CENTER);\r
-    this.add(monospaced);\r
-    this.add(jPanel3, null);\r
-        this.add(jPanel2, null);\r
-        jPanel2.add(jLabel3, BorderLayout.WEST);\r
-        jPanel2.add(fontStyle, BorderLayout.CENTER);\r
-    jPanel3.add(jLabel2, BorderLayout.WEST);\r
-        jPanel3.add(fontSize, BorderLayout.CENTER);\r
-        this.add(ok, null);\r
-        this.add(cancel, null);\r
-        this.add(defaultButton);\r
-  }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void ok_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void fontName_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void fontSize_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void fontStyle_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void defaultButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GFontChooser extends JPanel
+{
+    JLabel jLabel1 = new JLabel();
+    protected JComboBox fontSize = new JComboBox();
+    protected JComboBox fontStyle = new JComboBox();
+    JLabel jLabel2 = new JLabel();
+    JLabel jLabel3 = new JLabel();
+    protected JComboBox fontName = new JComboBox();
+    JButton ok = new JButton();
+    JButton cancel = new JButton();
+    JPanel jPanel1 = new JPanel();
+    JPanel jPanel2 = new JPanel();
+    JPanel jPanel3 = new JPanel();
+    BorderLayout borderLayout1 = new BorderLayout();
+    BorderLayout borderLayout2 = new BorderLayout();
+    BorderLayout borderLayout3 = new BorderLayout();
+    FlowLayout flowLayout1 = new FlowLayout();
+    protected JButton defaultButton = new JButton();
+   protected  JCheckBox monospaced = new JCheckBox();
+  BorderLayout borderLayout4 = new BorderLayout();
+
+  /**
+     * Creates a new GFontChooser object.
+     */
+    public GFontChooser()
+    {
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        jLabel1.setFont(new java.awt.Font("Verdana", 0, 11));
+        jLabel1.setHorizontalAlignment(SwingConstants.RIGHT);
+        jLabel1.setText("Font: ");
+        jLabel1.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);
+        this.setLayout(flowLayout1);
+        fontSize.setFont(new java.awt.Font("Verdana", 0, 11));
+        fontSize.setOpaque(false);
+        fontSize.setPreferredSize(new Dimension(50, 21));
+        fontSize.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    fontSize_actionPerformed(e);
+                }
+            });
+        fontStyle.setFont(new java.awt.Font("Verdana", 0, 11));
+        fontStyle.setOpaque(false);
+        fontStyle.setPreferredSize(new Dimension(90, 21));
+        fontStyle.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    fontStyle_actionPerformed(e);
+                }
+            });
+        jLabel2.setFont(new java.awt.Font("Verdana", 0, 11));
+        jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);
+        jLabel2.setText("Size: ");
+        jLabel2.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);
+        jLabel3.setFont(new java.awt.Font("Verdana", 0, 11));
+        jLabel3.setHorizontalAlignment(SwingConstants.RIGHT);
+        jLabel3.setText("Style: ");
+        jLabel3.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);
+        fontName.setFont(new java.awt.Font("Verdana", 0, 11));
+        fontName.setMaximumSize(new Dimension(32767, 32767));
+        fontName.setMinimumSize(new Dimension(300, 21));
+        fontName.setOpaque(false);
+        fontName.setPreferredSize(new Dimension(180, 21));
+        fontName.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    fontName_actionPerformed(e);
+                }
+            });
+        ok.setFont(new java.awt.Font("Verdana", 0, 11));
+        ok.setText("OK");
+        ok.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    ok_actionPerformed(e);
+                }
+            });
+        cancel.setFont(new java.awt.Font("Verdana", 0, 11));
+        cancel.setText("Cancel");
+        cancel.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    cancel_actionPerformed(e);
+                }
+            });
+        this.setBackground(Color.white);
+        jPanel1.setOpaque(false);
+        jPanel1.setLayout(borderLayout1);
+        jPanel2.setOpaque(false);
+        jPanel2.setLayout(borderLayout3);
+        jPanel3.setOpaque(false);
+        jPanel3.setLayout(borderLayout2);
+        flowLayout1.setAlignment(FlowLayout.CENTER);
+    flowLayout1.setHgap(1);
+    flowLayout1.setVgap(5);
+    defaultButton.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    defaultButton.setText("Set as Default");
+        defaultButton.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    defaultButton_actionPerformed(e);
+                }
+            });
+    monospaced.setEnabled(false);
+    monospaced.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    monospaced.setOpaque(false);
+    monospaced.setToolTipText("Monospaced fonts are faster to render");
+    monospaced.setText("Monospaced");
+    this.add(jPanel1, null);
+        jPanel1.add(jLabel1, BorderLayout.WEST);
+        jPanel1.add(fontName, BorderLayout.CENTER);
+    this.add(monospaced);
+    this.add(jPanel3, null);
+        this.add(jPanel2, null);
+        jPanel2.add(jLabel3, BorderLayout.WEST);
+        jPanel2.add(fontStyle, BorderLayout.CENTER);
+    jPanel3.add(jLabel2, BorderLayout.WEST);
+        jPanel3.add(fontSize, BorderLayout.CENTER);
+        this.add(ok, null);
+        this.add(cancel, null);
+        this.add(defaultButton);
+  }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void ok_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void cancel_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void fontName_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void fontSize_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void fontStyle_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void defaultButton_actionPerformed(ActionEvent e)
+    {
+    }
+}
index a142d5b..8ec540a 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import javax.swing.*;\r
-\r
-public class GPCAPanel\r
-    extends JInternalFrame\r
-{\r
-  JPanel jPanel2 = new JPanel();\r
-  JLabel jLabel1 = new JLabel();\r
-  JLabel jLabel2 = new JLabel();\r
-  JLabel jLabel3 = new JLabel();\r
-  protected JComboBox xCombobox = new JComboBox();\r
-  protected JComboBox yCombobox = new JComboBox();\r
-  protected JComboBox zCombobox = new JComboBox();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  JMenuBar jMenuBar1 = new JMenuBar();\r
-  JMenu fileMenu = new JMenu();\r
-  JMenu saveMenu = new JMenu();\r
-  JMenuItem eps = new JMenuItem();\r
-  JMenuItem png = new JMenuItem();\r
-  JMenuItem print = new JMenuItem();\r
-  JMenuItem outputValues = new JMenuItem();\r
-  JMenu viewMenu = new JMenu();\r
-  protected JCheckBoxMenuItem showLabels = new JCheckBoxMenuItem();\r
-  JMenuItem bgcolour = new JMenuItem();\r
-\r
-  public GPCAPanel()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    for (int i = 1; i < 8; i++)\r
-    {\r
-      xCombobox.addItem("dim " + i);\r
-      yCombobox.addItem("dim " + i);\r
-      zCombobox.addItem("dim " + i);\r
-    }\r
-\r
-\r
-    setJMenuBar(jMenuBar1);\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.getContentPane().setLayout(borderLayout1);\r
-    jPanel2.setLayout(flowLayout1);\r
-    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel1.setText("x=");\r
-    jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel2.setText("y=");\r
-    jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel3.setText("z=");\r
-    jPanel2.setBackground(Color.white);\r
-    jPanel2.setBorder(null);\r
-    zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    zCombobox.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        zCombobox_actionPerformed(e);\r
-      }\r
-    });\r
-    yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    yCombobox.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        yCombobox_actionPerformed(e);\r
-      }\r
-    });\r
-    xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    xCombobox.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        xCombobox_actionPerformed(e);\r
-      }\r
-    });\r
-    fileMenu.setText("File");\r
-    saveMenu.setText("Save as");\r
-    eps.setText("EPS");\r
-    eps.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        eps_actionPerformed(e);\r
-      }\r
-    });\r
-    png.setText("PNG");\r
-    png.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        png_actionPerformed(e);\r
-      }\r
-    });\r
-    outputValues.setText("Output Values...");\r
-    outputValues.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        outputValues_actionPerformed(e);\r
-      }\r
-    });\r
-    print.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        print_actionPerformed(e);\r
-      }\r
-    });\r
-    viewMenu.setText("View");\r
-    showLabels.setText("Show Labels");\r
-    showLabels.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        showLabels_actionPerformed(e);\r
-      }\r
-    });\r
-    print.setText("Print");\r
-    bgcolour.setText("Background Colour...");\r
-    bgcolour.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        bgcolour_actionPerformed(e);\r
-      }\r
-    });\r
-    this.getContentPane().add(jPanel2, BorderLayout.SOUTH);\r
-    jPanel2.add(jLabel1, null);\r
-    jPanel2.add(xCombobox, null);\r
-    jPanel2.add(jLabel2, null);\r
-    jPanel2.add(yCombobox, null);\r
-    jPanel2.add(jLabel3, null);\r
-    jPanel2.add(zCombobox, null);\r
-    jMenuBar1.add(fileMenu);\r
-    jMenuBar1.add(viewMenu);\r
-    fileMenu.add(saveMenu);\r
-    fileMenu.add(outputValues);\r
-    fileMenu.add(print);\r
-    saveMenu.add(eps);\r
-    saveMenu.add(png);\r
-    viewMenu.add(showLabels);\r
-    viewMenu.add(bgcolour);\r
-  }\r
-\r
-  protected void xCombobox_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void yCombobox_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  protected void zCombobox_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void eps_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void png_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void outputValues_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void print_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void showLabels_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void bgcolour_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class GPCAPanel
+    extends JInternalFrame
+{
+  JPanel jPanel2 = new JPanel();
+  JLabel jLabel1 = new JLabel();
+  JLabel jLabel2 = new JLabel();
+  JLabel jLabel3 = new JLabel();
+  protected JComboBox xCombobox = new JComboBox();
+  protected JComboBox yCombobox = new JComboBox();
+  protected JComboBox zCombobox = new JComboBox();
+  FlowLayout flowLayout1 = new FlowLayout();
+  BorderLayout borderLayout1 = new BorderLayout();
+  JMenuBar jMenuBar1 = new JMenuBar();
+  JMenu fileMenu = new JMenu();
+  JMenu saveMenu = new JMenu();
+  JMenuItem eps = new JMenuItem();
+  JMenuItem png = new JMenuItem();
+  JMenuItem print = new JMenuItem();
+  JMenuItem outputValues = new JMenuItem();
+  JMenu viewMenu = new JMenu();
+  protected JCheckBoxMenuItem showLabels = new JCheckBoxMenuItem();
+  JMenuItem bgcolour = new JMenuItem();
+  JMenuItem originalSeqData = new JMenuItem();
+
+  public GPCAPanel()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    for (int i = 1; i < 8; i++)
+    {
+      xCombobox.addItem("dim " + i);
+      yCombobox.addItem("dim " + i);
+      zCombobox.addItem("dim " + i);
+    }
+
+
+    setJMenuBar(jMenuBar1);
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    this.getContentPane().setLayout(borderLayout1);
+    jPanel2.setLayout(flowLayout1);
+    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel1.setText("x=");
+    jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel2.setText("y=");
+    jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel3.setText("z=");
+    jPanel2.setBackground(Color.white);
+    jPanel2.setBorder(null);
+    zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    zCombobox.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        zCombobox_actionPerformed(e);
+      }
+    });
+    yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    yCombobox.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        yCombobox_actionPerformed(e);
+      }
+    });
+    xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    xCombobox.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        xCombobox_actionPerformed(e);
+      }
+    });
+    fileMenu.setText("File");
+    saveMenu.setText("Save as");
+    eps.setText("EPS");
+    eps.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        eps_actionPerformed(e);
+      }
+    });
+    png.setText("PNG");
+    png.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        png_actionPerformed(e);
+      }
+    });
+    outputValues.setText("Output Values...");
+    outputValues.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        outputValues_actionPerformed(e);
+      }
+    });
+    print.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        print_actionPerformed(e);
+      }
+    });
+    viewMenu.setText("View");
+    showLabels.setText("Show Labels");
+    showLabels.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        showLabels_actionPerformed(e);
+      }
+    });
+    print.setText("Print");
+    bgcolour.setText("Background Colour...");
+    bgcolour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        bgcolour_actionPerformed(e);
+      }
+    });
+    originalSeqData.setText("Input Data...");
+    originalSeqData.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        originalSeqData_actionPerformed(e);
+      }
+    });
+    this.getContentPane().add(jPanel2, BorderLayout.SOUTH);
+    jPanel2.add(jLabel1, null);
+    jPanel2.add(xCombobox, null);
+    jPanel2.add(jLabel2, null);
+    jPanel2.add(yCombobox, null);
+    jPanel2.add(jLabel3, null);
+    jPanel2.add(zCombobox, null);
+    jMenuBar1.add(fileMenu);
+    jMenuBar1.add(viewMenu);
+    fileMenu.add(saveMenu);
+    fileMenu.add(outputValues);
+    fileMenu.add(print);
+    fileMenu.add(originalSeqData);
+    saveMenu.add(eps);
+    saveMenu.add(png);
+    viewMenu.add(showLabels);
+    viewMenu.add(bgcolour);
+  }
+
+  protected void xCombobox_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void yCombobox_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void zCombobox_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void eps_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void png_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void outputValues_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void print_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void showLabels_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void bgcolour_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void originalSeqData_actionPerformed(ActionEvent e)
+  {
+
+  }
+}
index 7f9eea2..ac9bd9f 100755 (executable)
@@ -1,6 +1,6 @@
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GPairwiseAlignPanel extends JPanel\r
-{\r
-    protected JScrollPane scrollPane = new JScrollPane();\r
-    protected JTextArea textarea = new JTextArea();\r
-    protected JButton viewInEditorButton = new JButton();\r
-    JPanel jPanel1 = new JPanel();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-\r
-    /**\r
-     * Creates a new GPairwiseAlignPanel object.\r
-     */\r
-    public GPairwiseAlignPanel()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        this.setLayout(borderLayout1);\r
-        textarea.setFont(new java.awt.Font("Monospaced", 0, 12));\r
-        textarea.setText("");\r
-        textarea.setWrapStyleWord(false);\r
-        viewInEditorButton.setFont(new java.awt.Font("Verdana", 0, 12));\r
-        viewInEditorButton.setText("View in alignment editor");\r
-        viewInEditorButton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    viewInEditorButton_actionPerformed(e);\r
-                }\r
-            });\r
-        this.add(scrollPane, BorderLayout.CENTER);\r
-        scrollPane.getViewport().add(textarea, null);\r
-        this.add(jPanel1, BorderLayout.SOUTH);\r
-        jPanel1.add(viewInEditorButton, null);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void viewInEditorButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-}\r
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GPairwiseAlignPanel extends JPanel
+{
+    protected JScrollPane scrollPane = new JScrollPane();
+    protected JTextArea textarea = new JTextArea();
+    protected JButton viewInEditorButton = new JButton();
+    JPanel jPanel1 = new JPanel();
+    BorderLayout borderLayout1 = new BorderLayout();
+
+    /**
+     * Creates a new GPairwiseAlignPanel object.
+     */
+    public GPairwiseAlignPanel()
+    {
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        this.setLayout(borderLayout1);
+        textarea.setFont(new java.awt.Font("Monospaced", 0, 12));
+        textarea.setText("");
+        textarea.setWrapStyleWord(false);
+        viewInEditorButton.setFont(new java.awt.Font("Verdana", 0, 12));
+        viewInEditorButton.setText("View in alignment editor");
+        viewInEditorButton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    viewInEditorButton_actionPerformed(e);
+                }
+            });
+        this.add(scrollPane, BorderLayout.CENTER);
+        scrollPane.getViewport().add(textarea, null);
+        this.add(jPanel1, BorderLayout.SOUTH);
+        jPanel1.add(viewInEditorButton, null);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void viewInEditorButton_actionPerformed(ActionEvent e)
+    {
+    }
+}
index 8b10c5f..38d28f2 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-\r
-import javax.swing.*;\r
-import javax.swing.border.TitledBorder;\r
-import java.awt.event.*;\r
-import javax.swing.event.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GPreferences extends JPanel\r
-{\r
-    JTabbedPane tabbedPane = new JTabbedPane();\r
-\r
-    JButton ok = new JButton();\r
-    JButton cancel = new JButton();\r
-    JPanel okCancelPanel = new JPanel();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-    protected JCheckBox quality = new JCheckBox();\r
-    JPanel visualTab = new JPanel();\r
-  protected JCheckBox fullScreen = new JCheckBox();\r
-    protected JCheckBox conservation = new JCheckBox();\r
-    protected JCheckBox identity = new JCheckBox();\r
-    protected JCheckBox annotations = new JCheckBox();\r
-    JLabel gapLabel = new JLabel();\r
-    protected JComboBox colour = new JComboBox();\r
-    JLabel colourLabel = new JLabel();\r
-    JLabel fontLabel = new JLabel();\r
-    protected JComboBox fontSizeCB = new JComboBox();\r
-    protected JComboBox fontStyleCB = new JComboBox();\r
-    protected JComboBox fontNameCB = new JComboBox();\r
-    protected JComboBox gapSymbolCB = new JComboBox();\r
-    protected JCheckBox startupCheckbox = new JCheckBox();\r
-    protected JTextField startupFileTextfield = new JTextField();\r
-  JPanel connectTab = new JPanel();\r
-  JLabel serverLabel = new JLabel();\r
-  protected JList linkURLList = new JList();\r
-  protected JTextField proxyServerTB = new JTextField();\r
-  protected JTextField proxyPortTB = new JTextField();\r
-  JLabel portLabel = new JLabel();\r
-  JLabel browserLabel = new JLabel();\r
-  protected JTextField defaultBrowser = new JTextField();\r
-  JButton newLink = new JButton();\r
-  JButton editLink = new JButton();\r
-  JButton deleteLink = new JButton();\r
-  JScrollPane linkScrollPane = new JScrollPane();\r
-  JPanel linkPanel = new JPanel();\r
-  BorderLayout borderLayout2 = new BorderLayout();\r
-  JPanel editLinkButtons = new JPanel();\r
-  GridLayout gridLayout1 = new GridLayout();\r
-  protected JList linkNameList = new JList();\r
-  JPanel linkPanel2 = new JPanel();\r
-  BorderLayout borderLayout3 = new BorderLayout();\r
-  protected JCheckBox useProxy = new JCheckBox();\r
-  JPanel jPanel1 = new JPanel();\r
-  TitledBorder titledBorder1 = new TitledBorder("Proxy Server");\r
-  TitledBorder titledBorder2 = new TitledBorder("File Output");\r
-  GridBagLayout gridBagLayout2 = new GridBagLayout();\r
-  GridBagLayout gridBagLayout1 = new GridBagLayout();\r
-  GridBagLayout gridBagLayout3 = new GridBagLayout();\r
-  protected JComboBox sortby = new JComboBox();\r
-  JLabel sortLabel = new JLabel();\r
-  JPanel jPanel2 = new JPanel();\r
-  GridLayout gridLayout2 = new GridLayout();\r
-  JPanel jPanel3 = new JPanel();\r
-  JPanel exportTab = new JPanel();\r
-  JLabel epsLabel = new JLabel();\r
-  protected JComboBox epsRendering = new JComboBox();\r
-  JLabel jLabel1 = new JLabel();\r
-  protected  JCheckBox blcjv = new JCheckBox();\r
-  protected  JCheckBox pileupjv = new JCheckBox();\r
-  protected  JCheckBox clustaljv = new JCheckBox();\r
-  protected  JCheckBox msfjv = new JCheckBox();\r
-  protected  JCheckBox fastajv = new JCheckBox();\r
-  protected  JCheckBox pfamjv = new JCheckBox();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  protected  JCheckBox pirjv = new JCheckBox();\r
-  JPanel jPanel11 = new JPanel();\r
-  Font verdana11 = new java.awt.Font("Verdana", Font.PLAIN, 11);\r
-  protected JCheckBox seqLimit = new JCheckBox();\r
-  GridLayout gridLayout3 = new GridLayout();\r
-  protected JCheckBox smoothFont = new JCheckBox();\r
-  /**\r
-     * Creates a new GPreferences object.\r
-     */\r
-    public GPreferences()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-            ex.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        this.setLayout(borderLayout1);\r
-        ok.setText("OK");\r
-        ok.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    ok_actionPerformed(e);\r
-                }\r
-            });\r
-        cancel.setText("Cancel");\r
-        cancel.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    cancel_actionPerformed(e);\r
-                }\r
-            });\r
-        quality.setEnabled(false);\r
-        quality.setFont(verdana11);\r
-        quality.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        quality.setHorizontalTextPosition(SwingConstants.LEFT);\r
-        quality.setSelected(true);\r
-        quality.setText("Quality");\r
-    visualTab.setBorder(new TitledBorder("Open new alignment"));\r
-    visualTab.setLayout(null);\r
-    fullScreen.setFont(verdana11);\r
-        fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);\r
-    fullScreen.setMargin(new Insets(2, 2, 2, 0));\r
-    fullScreen.setText("Maximise Window");\r
-    conservation.setEnabled(false);\r
-        conservation.setFont(verdana11);\r
-        conservation.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        conservation.setHorizontalTextPosition(SwingConstants.LEFT);\r
-        conservation.setSelected(true);\r
-        conservation.setText("Conservation");\r
-    identity.setEnabled(false);\r
-        identity.setFont(verdana11);\r
-        identity.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        identity.setHorizontalTextPosition(SwingConstants.LEFT);\r
-        identity.setSelected(true);\r
-        identity.setText("Consensus");\r
-    annotations.setFont(verdana11);\r
-        annotations.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        annotations.setHorizontalTextPosition(SwingConstants.LEFT);\r
-    annotations.setMargin(new Insets(2, 4, 2, 0));\r
-    annotations.setSelected(true);\r
-        annotations.setText("Show Annotations");\r
-    annotations.addActionListener(new ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    annotations_actionPerformed(e);\r
-                }\r
-            });\r
-        gapLabel.setFont(verdana11);\r
-        gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        gapLabel.setText("Gap Symbol ");\r
-    colour.setFont(verdana11);\r
-        colour.setBounds(new Rectangle(171, 180, 155, 21));\r
-        colourLabel.setFont(verdana11);\r
-        colourLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        colourLabel.setText("Colour ");\r
-    fontLabel.setFont(verdana11);\r
-        fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        fontLabel.setText("Font ");\r
-    fontSizeCB.setFont(verdana11);\r
-        fontSizeCB.setBounds(new Rectangle(318, 100, 49, 21));\r
-        fontStyleCB.setFont(verdana11);\r
-        fontStyleCB.setBounds(new Rectangle(366, 100, 70, 21));\r
-        fontNameCB.setFont(verdana11);\r
-        fontNameCB.setBounds(new Rectangle(171, 100, 147, 21));\r
-        gapSymbolCB.setFont(verdana11);\r
-        gapSymbolCB.setBounds(new Rectangle(171, 153, 69, 21));\r
-        startupCheckbox.setText("Open file");\r
-    startupCheckbox.setFont(verdana11);\r
-        startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);\r
-        startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);\r
-        startupCheckbox.setSelected(true);\r
-        startupFileTextfield.setFont(verdana11);\r
-        startupFileTextfield.setBounds(new Rectangle(171, 236, 270, 20));\r
-        startupFileTextfield.addMouseListener(new MouseAdapter()\r
-            {\r
-                public void mouseClicked(MouseEvent e)\r
-                {\r
-                    if (e.getClickCount() > 1)\r
-                    {\r
-                        startupFileTextfield_mouseClicked();\r
-                    }\r
-                }\r
-            });\r
-\r
-     connectTab.setLayout(gridBagLayout3);\r
-    serverLabel.setText("Address");\r
-    serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    serverLabel.setFont(verdana11);\r
-    proxyServerTB.setFont(verdana11);\r
-    proxyPortTB.setFont(verdana11);\r
-    portLabel.setFont(verdana11);\r
-    portLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    portLabel.setText("Port");\r
-    browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11));\r
-    browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);\r
-    browserLabel.setText("Default Browser (Unix)");\r
-    defaultBrowser.setFont(verdana11);\r
-    defaultBrowser.setText("");\r
-    newLink.setText("New");\r
-    newLink.addActionListener(new java.awt.event.ActionListener() {\r
-      public void actionPerformed(ActionEvent e) {\r
-        newLink_actionPerformed(e);\r
-      }\r
-    });\r
-    editLink.setText("Edit");\r
-    editLink.addActionListener(new java.awt.event.ActionListener() {\r
-      public void actionPerformed(ActionEvent e) {\r
-        editLink_actionPerformed(e);\r
-      }\r
-    });\r
-    deleteLink.setText("Delete");\r
-    deleteLink.addActionListener(new java.awt.event.ActionListener() {\r
-      public void actionPerformed(ActionEvent e) {\r
-        deleteLink_actionPerformed(e);\r
-      }\r
-    });\r
-\r
-    linkURLList.addListSelectionListener(new ListSelectionListener()\r
-         {\r
-            public void valueChanged(ListSelectionEvent e)\r
-            {\r
-               int index = linkURLList.getSelectedIndex();\r
-               linkNameList.setSelectedIndex(index);\r
-            }\r
-         });\r
-\r
-    linkNameList.addListSelectionListener(new ListSelectionListener()\r
-        {\r
-          public void valueChanged(ListSelectionEvent e)\r
-          {\r
-              int index = linkNameList.getSelectedIndex();\r
-              linkURLList.setSelectedIndex(index);\r
-          }\r
-        });\r
-\r
-    linkScrollPane.setBorder(null);\r
-    linkPanel.setBorder(new TitledBorder("URL link from Sequence ID"));\r
-    linkPanel.setLayout(borderLayout2);\r
-    editLinkButtons.setLayout(gridLayout1);\r
-    gridLayout1.setRows(3);\r
-    linkNameList.setFont(verdana11);\r
-    linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
-    linkPanel2.setLayout(borderLayout3);\r
-    linkURLList.setFont(verdana11);\r
-    linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
-\r
-    defaultBrowser.addMouseListener(new MouseAdapter()\r
-    {\r
-      public void mouseClicked(MouseEvent e)\r
-      {\r
-        if (e.getClickCount() > 1)\r
-            {\r
-              defaultBrowser_mouseClicked(e);\r
-            }\r
-      }\r
-    });\r
-    useProxy.setFont(verdana11);\r
-    useProxy.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    useProxy.setHorizontalTextPosition(SwingConstants.LEADING);\r
-    useProxy.setText("Use a proxy server");\r
-    useProxy.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        useProxy_actionPerformed();\r
-      }\r
-    });\r
-    jPanel1.setBorder(titledBorder1);\r
-    jPanel1.setLayout(gridBagLayout1);\r
-    sortby.setFont(verdana11);\r
-    sortby.setBounds(new Rectangle(171, 208, 155, 21));\r
-    sortLabel.setFont(verdana11);\r
-    sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    sortLabel.setText("Sort by ");\r
-    jPanel2.setBounds(new Rectangle(7, 17, 158, 245));\r
-    jPanel2.setLayout(gridLayout2);\r
-    gridLayout2.setRows(9);\r
-    jPanel3.setBounds(new Rectangle(167, 41, 274, 26));\r
-    exportTab.setLayout(null);\r
-    epsLabel.setFont(verdana11);\r
-    epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    epsLabel.setText("EPS Rendering Style");\r
-    epsLabel.setBounds(new Rectangle(9, 31, 140, 24));\r
-    epsRendering.setFont(verdana11);\r
-    epsRendering.setBounds(new Rectangle(154, 34, 187, 21));\r
-    jLabel1.setFont(verdana11);\r
-    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);\r
-    jLabel1.setText("Append /start-end (/15-380)");\r
-    jLabel1.setFont(verdana11);\r
-    fastajv.setFont(verdana11);\r
-    fastajv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    clustaljv.setText("Clustal     ");\r
-    blcjv.setText("BLC     ");\r
-    fastajv.setText("Fasta     ");\r
-    msfjv.setText("MSF     ");\r
-    pfamjv.setText("PFAM     ");\r
-    pileupjv.setText("Pileup     ");\r
-    msfjv.setFont(verdana11);\r
-    msfjv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    pirjv.setText("PIR     ");\r
-    jPanel11.setFont(verdana11);\r
-    jPanel11.setBorder(titledBorder2);\r
-    jPanel11.setBounds(new Rectangle(30, 72, 196, 182));\r
-    jPanel11.setLayout(gridLayout3);\r
-    blcjv.setFont(verdana11);\r
-    blcjv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    clustaljv.setFont(verdana11);\r
-    clustaljv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    pfamjv.setFont(verdana11);\r
-    pfamjv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    pileupjv.setFont(verdana11);\r
-    pileupjv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    pirjv.setFont(verdana11);\r
-    pirjv.setHorizontalAlignment(SwingConstants.LEFT);\r
-    seqLimit.setFont(verdana11);\r
-    seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);\r
-    seqLimit.setText("Full Sequence Id");\r
-    gridLayout3.setRows(8);\r
-    smoothFont.setFont(verdana11);\r
-    smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);\r
-    smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);\r
-    smoothFont.setText("Smooth Font");\r
-    jPanel2.add(fullScreen);\r
-\r
-    jPanel2.add(annotations);\r
-    jPanel2.add(seqLimit);\r
-    jPanel2.add(fontLabel);\r
-    jPanel2.add(smoothFont);\r
-    jPanel2.add(gapLabel);\r
-    jPanel2.add(colourLabel);\r
-    jPanel2.add(sortLabel);\r
-    jPanel2.add(startupCheckbox);\r
-    visualTab.add(colour);\r
-    visualTab.add(gapSymbolCB);\r
-    visualTab.add(startupFileTextfield);\r
-    visualTab.add(sortby);\r
-    visualTab.add(fontNameCB);\r
-    visualTab.add(fontSizeCB);\r
-    visualTab.add(fontStyleCB);\r
-    visualTab.add(jPanel3);\r
-    jPanel3.add(conservation);\r
-    jPanel3.add(identity);\r
-    jPanel3.add(quality);\r
-    visualTab.add(jPanel2);\r
-    linkPanel.add(editLinkButtons, BorderLayout.EAST);\r
-    editLinkButtons.add(newLink, null);\r
-    editLinkButtons.add(editLink, null);\r
-    editLinkButtons.add(deleteLink, null);\r
-    linkPanel.add(linkScrollPane, BorderLayout.CENTER);\r
-    linkScrollPane.getViewport().add(linkPanel2, null);\r
-    linkPanel2.add(linkURLList, BorderLayout.CENTER);\r
-    linkPanel2.add(linkNameList, BorderLayout.WEST);\r
-        okCancelPanel.add(ok);\r
-        okCancelPanel.add(cancel);\r
-    this.add(tabbedPane, java.awt.BorderLayout.CENTER);\r
-\r
-        this.add(okCancelPanel, java.awt.BorderLayout.SOUTH);\r
-    jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0\r
-        , GridBagConstraints.WEST, GridBagConstraints.NONE,\r
-        new Insets(0, 2, 4, 0), 5, 0));\r
-    jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0\r
-                                                  , GridBagConstraints.WEST,\r
-                                                  GridBagConstraints.NONE,\r
-                                                  new Insets(0, 0, 4, 0), 11, 6));\r
-    connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0\r
-        , GridBagConstraints.CENTER, GridBagConstraints.BOTH,\r
-        new Insets(16, 0, 0, 12), 359, -17));\r
-    connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0\r
-        , GridBagConstraints.CENTER, GridBagConstraints.BOTH,\r
-        new Insets(21, 0, 35, 12), 4, 6));\r
-    connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0\r
-        , GridBagConstraints.WEST, GridBagConstraints.NONE,\r
-        new Insets(16, 0, 0, 0), 5, 1));\r
-    jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0\r
-        , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,\r
-        new Insets(0, 2, 4, 2), 54, 1));\r
-    jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0\r
-        , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,\r
-        new Insets(0, 2, 4, 0), 263, 1));\r
-    connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0\r
-        , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,\r
-        new Insets(15, 0, 0, 15), 307, 1));\r
-\r
-\r
-    jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0\r
-                                                 , GridBagConstraints.WEST,\r
-                                                 GridBagConstraints.NONE,\r
-                                                 new Insets(0, 2, 5, 185), 2,\r
-                                                 -4));\r
-    DefaultListCellRenderer dlcr = new DefaultListCellRenderer();\r
-        dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);\r
-        gapSymbolCB.setRenderer(dlcr);\r
-\r
-    tabbedPane.add(visualTab, "Visual");\r
-    tabbedPane.add(connectTab,"Connections");\r
-    tabbedPane.add(exportTab, "Output");\r
-    jPanel11.add(jLabel1);\r
-    jPanel11.add(blcjv);\r
-    jPanel11.add(clustaljv);\r
-    jPanel11.add(fastajv);\r
-    jPanel11.add(msfjv);\r
-    jPanel11.add(pfamjv);\r
-    jPanel11.add(pileupjv);\r
-    jPanel11.add(pirjv);\r
-\r
-    exportTab.add(epsLabel);\r
-    exportTab.add(epsRendering);\r
-    exportTab.add(jPanel11);\r
-  }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void ok_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    public void annotations_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void startupFileTextfield_mouseClicked()\r
-    {\r
-    }\r
-\r
-\r
-  public void newLink_actionPerformed(ActionEvent e) {\r
-\r
-  }\r
-\r
-  public void editLink_actionPerformed(ActionEvent e) {\r
-\r
-  }\r
-\r
-  public void deleteLink_actionPerformed(ActionEvent e) {\r
-\r
-  }\r
-\r
-  public void defaultBrowser_mouseClicked(MouseEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void linkURLList_keyTyped(KeyEvent e)\r
-  {\r
-\r
-  }\r
-\r
-  public void useProxy_actionPerformed()\r
-  {\r
-      proxyServerTB.setEnabled(useProxy.isSelected());\r
-      proxyPortTB.setEnabled(useProxy.isSelected());\r
-  }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+
+import javax.swing.*;
+import javax.swing.border.TitledBorder;
+import java.awt.event.*;
+import javax.swing.event.*;
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.Insets;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GPreferences extends JPanel
+{
+    JTabbedPane tabbedPane = new JTabbedPane();
+
+    JButton ok = new JButton();
+    JButton cancel = new JButton();
+    JPanel okCancelPanel = new JPanel();
+    BorderLayout borderLayout1 = new BorderLayout();
+    protected JCheckBox quality = new JCheckBox();
+    JPanel visualTab = new JPanel();
+  protected JCheckBox fullScreen = new JCheckBox();
+    protected JCheckBox conservation = new JCheckBox();
+    protected JCheckBox identity = new JCheckBox();
+    protected JCheckBox annotations = new JCheckBox();
+    JLabel gapLabel = new JLabel();
+    protected JComboBox colour = new JComboBox();
+    JLabel colourLabel = new JLabel();
+    JLabel fontLabel = new JLabel();
+    protected JComboBox fontSizeCB = new JComboBox();
+    protected JComboBox fontStyleCB = new JComboBox();
+    protected JComboBox fontNameCB = new JComboBox();
+    protected JComboBox gapSymbolCB = new JComboBox();
+    protected JCheckBox startupCheckbox = new JCheckBox();
+    protected JTextField startupFileTextfield = new JTextField();
+  JPanel connectTab = new JPanel();
+  JLabel serverLabel = new JLabel();
+  protected JList linkURLList = new JList();
+  protected JTextField proxyServerTB = new JTextField();
+  protected JTextField proxyPortTB = new JTextField();
+  JLabel portLabel = new JLabel();
+  JLabel browserLabel = new JLabel();
+  protected JTextField defaultBrowser = new JTextField();
+  JButton newLink = new JButton();
+  JButton editLink = new JButton();
+  JButton deleteLink = new JButton();
+  JScrollPane linkScrollPane = new JScrollPane();
+  JPanel linkPanel = new JPanel();
+  BorderLayout borderLayout2 = new BorderLayout();
+  JPanel editLinkButtons = new JPanel();
+  GridLayout gridLayout1 = new GridLayout();
+  protected JList linkNameList = new JList();
+  JPanel linkPanel2 = new JPanel();
+  BorderLayout borderLayout3 = new BorderLayout();
+  protected JCheckBox useProxy = new JCheckBox();
+  JPanel jPanel1 = new JPanel();
+  TitledBorder titledBorder1 = new TitledBorder("Proxy Server");
+  TitledBorder titledBorder2 = new TitledBorder("File Output");
+  GridBagLayout gridBagLayout2 = new GridBagLayout();
+  GridBagLayout gridBagLayout1 = new GridBagLayout();
+  GridBagLayout gridBagLayout3 = new GridBagLayout();
+  protected JComboBox sortby = new JComboBox();
+  JLabel sortLabel = new JLabel();
+  JPanel jPanel2 = new JPanel();
+  GridLayout gridLayout2 = new GridLayout();
+  JPanel jPanel3 = new JPanel();
+  JPanel exportTab = new JPanel();
+  JLabel epsLabel = new JLabel();
+  protected JComboBox epsRendering = new JComboBox();
+  JLabel jLabel1 = new JLabel();
+  protected  JCheckBox blcjv = new JCheckBox();
+  protected  JCheckBox pileupjv = new JCheckBox();
+  protected  JCheckBox clustaljv = new JCheckBox();
+  protected  JCheckBox msfjv = new JCheckBox();
+  protected  JCheckBox fastajv = new JCheckBox();
+  protected  JCheckBox pfamjv = new JCheckBox();
+  FlowLayout flowLayout1 = new FlowLayout();
+  protected  JCheckBox pirjv = new JCheckBox();
+  JPanel jPanel11 = new JPanel();
+  Font verdana11 = new java.awt.Font("Verdana", Font.PLAIN, 11);
+  protected JCheckBox seqLimit = new JCheckBox();
+  GridLayout gridLayout3 = new GridLayout();
+  protected JCheckBox smoothFont = new JCheckBox();
+  JPanel calcTab = new JPanel();
+  protected JCheckBox autoCalculateConsCheck = new JCheckBox();
+  protected JCheckBox padGaps = new JCheckBox();
+  protected JCheckBox modellerOutput = new JCheckBox();
+  protected JPanel dasPanel = new JPanel();
+  BorderLayout borderLayout4 = new BorderLayout();
+  protected JCheckBox wrap = new JCheckBox();
+  /**
+     * Creates a new GPreferences object.
+     */
+    public GPreferences()
+    {
+        try
+        {
+            jbInit();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        this.setLayout(borderLayout1);
+        ok.setText("OK");
+        ok.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    ok_actionPerformed(e);
+                }
+            });
+        cancel.setText("Cancel");
+        cancel.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    cancel_actionPerformed(e);
+                }
+            });
+        quality.setEnabled(false);
+        quality.setFont(verdana11);
+        quality.setHorizontalAlignment(SwingConstants.RIGHT);
+        quality.setHorizontalTextPosition(SwingConstants.LEFT);
+        quality.setSelected(true);
+        quality.setText("Quality");
+    visualTab.setBorder(new TitledBorder("Open new alignment"));
+    visualTab.setLayout(null);
+    fullScreen.setFont(verdana11);
+        fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
+        fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
+    fullScreen.setMargin(new Insets(2, 2, 2, 0));
+    fullScreen.setText("Maximise Window");
+    conservation.setEnabled(false);
+        conservation.setFont(verdana11);
+        conservation.setHorizontalAlignment(SwingConstants.RIGHT);
+        conservation.setHorizontalTextPosition(SwingConstants.LEFT);
+        conservation.setSelected(true);
+        conservation.setText("Conservation");
+    identity.setEnabled(false);
+        identity.setFont(verdana11);
+        identity.setHorizontalAlignment(SwingConstants.RIGHT);
+        identity.setHorizontalTextPosition(SwingConstants.LEFT);
+        identity.setSelected(true);
+        identity.setText("Consensus");
+    annotations.setFont(verdana11);
+        annotations.setHorizontalAlignment(SwingConstants.RIGHT);
+        annotations.setHorizontalTextPosition(SwingConstants.LEFT);
+    annotations.setMargin(new Insets(2, 2, 2, 0));
+    annotations.setSelected(true);
+        annotations.setText("Show Annotations");
+    annotations.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    annotations_actionPerformed(e);
+                }
+            });
+        gapLabel.setFont(verdana11);
+        gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+        gapLabel.setText("Gap Symbol ");
+    colour.setFont(verdana11);
+        colour.setBounds(new Rectangle(172, 188, 155, 21));
+        colourLabel.setFont(verdana11);
+        colourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+        colourLabel.setText("Colour ");
+    fontLabel.setFont(verdana11);
+        fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+        fontLabel.setText("Font ");
+    fontSizeCB.setFont(verdana11);
+        fontSizeCB.setBounds(new Rectangle(317, 92, 49, 21));
+        fontStyleCB.setFont(verdana11);
+        fontStyleCB.setBounds(new Rectangle(364, 92, 70, 21));
+        fontNameCB.setFont(verdana11);
+        fontNameCB.setBounds(new Rectangle(171, 92, 147, 21));
+        gapSymbolCB.setFont(verdana11);
+        gapSymbolCB.setBounds(new Rectangle(172, 163, 69, 21));
+        startupCheckbox.setText("Open file");
+    startupCheckbox.setFont(verdana11);
+        startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);
+        startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
+        startupCheckbox.setSelected(true);
+        startupFileTextfield.setFont(verdana11);
+        startupFileTextfield.setBounds(new Rectangle(171, 236, 270, 20));
+        startupFileTextfield.addMouseListener(new MouseAdapter()
+            {
+                public void mouseClicked(MouseEvent e)
+                {
+                    if (e.getClickCount() > 1)
+                    {
+                        startupFileTextfield_mouseClicked();
+                    }
+                }
+            });
+
+     connectTab.setLayout(gridBagLayout3);
+    serverLabel.setText("Address");
+    serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    serverLabel.setFont(verdana11);
+    proxyServerTB.setFont(verdana11);
+    proxyPortTB.setFont(verdana11);
+    portLabel.setFont(verdana11);
+    portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    portLabel.setText("Port");
+    browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
+    browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
+    browserLabel.setText("Default Browser (Unix)");
+    defaultBrowser.setFont(verdana11);
+    defaultBrowser.setText("");
+    newLink.setText("New");
+    newLink.addActionListener(new java.awt.event.ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        newLink_actionPerformed(e);
+      }
+    });
+    editLink.setText("Edit");
+    editLink.addActionListener(new java.awt.event.ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        editLink_actionPerformed(e);
+      }
+    });
+    deleteLink.setText("Delete");
+    deleteLink.addActionListener(new java.awt.event.ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        deleteLink_actionPerformed(e);
+      }
+    });
+
+    linkURLList.addListSelectionListener(new ListSelectionListener()
+         {
+            public void valueChanged(ListSelectionEvent e)
+            {
+               int index = linkURLList.getSelectedIndex();
+               linkNameList.setSelectedIndex(index);
+            }
+         });
+
+    linkNameList.addListSelectionListener(new ListSelectionListener()
+        {
+          public void valueChanged(ListSelectionEvent e)
+          {
+              int index = linkNameList.getSelectedIndex();
+              linkURLList.setSelectedIndex(index);
+          }
+        });
+
+    linkScrollPane.setBorder(null);
+    linkPanel.setBorder(new TitledBorder("URL link from Sequence ID"));
+    linkPanel.setLayout(borderLayout2);
+    editLinkButtons.setLayout(gridLayout1);
+    gridLayout1.setRows(3);
+    linkNameList.setFont(verdana11);
+    linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    linkPanel2.setLayout(borderLayout3);
+    linkURLList.setFont(verdana11);
+    linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+    defaultBrowser.addMouseListener(new MouseAdapter()
+    {
+      public void mouseClicked(MouseEvent e)
+      {
+        if (e.getClickCount() > 1)
+            {
+              defaultBrowser_mouseClicked(e);
+            }
+      }
+    });
+    useProxy.setFont(verdana11);
+    useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
+    useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
+    useProxy.setText("Use a proxy server");
+    useProxy.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        useProxy_actionPerformed();
+      }
+    });
+    jPanel1.setBorder(titledBorder1);
+    jPanel1.setLayout(gridBagLayout1);
+    sortby.setFont(verdana11);
+    sortby.setBounds(new Rectangle(171, 213, 155, 21));
+    sortLabel.setFont(verdana11);
+    sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    sortLabel.setText("Sort by ");
+    jPanel2.setBounds(new Rectangle(7, 17, 158, 245));
+    jPanel2.setLayout(gridLayout2);
+    gridLayout2.setRows(10);
+    jPanel3.setBounds(new Rectangle(169, 39, 274, 26));
+    exportTab.setLayout(null);
+    epsLabel.setFont(verdana11);
+    epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    epsLabel.setText("EPS Rendering Style");
+    epsLabel.setBounds(new Rectangle(9, 31, 140, 24));
+    epsRendering.setFont(verdana11);
+    epsRendering.setBounds(new Rectangle(154, 34, 187, 21));
+    jLabel1.setFont(verdana11);
+    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
+    jLabel1.setText("Append /start-end (/15-380)");
+    jLabel1.setFont(verdana11);
+    fastajv.setFont(verdana11);
+    fastajv.setHorizontalAlignment(SwingConstants.LEFT);
+    clustaljv.setText("Clustal     ");
+    blcjv.setText("BLC     ");
+    fastajv.setText("Fasta     ");
+    msfjv.setText("MSF     ");
+    pfamjv.setText("PFAM     ");
+    pileupjv.setText("Pileup     ");
+    msfjv.setFont(verdana11);
+    msfjv.setHorizontalAlignment(SwingConstants.LEFT);
+    pirjv.setText("PIR     ");
+    jPanel11.setFont(verdana11);
+    jPanel11.setBorder(titledBorder2);
+    jPanel11.setBounds(new Rectangle(30, 72, 196, 182));
+    jPanel11.setLayout(gridLayout3);
+    blcjv.setFont(verdana11);
+    blcjv.setHorizontalAlignment(SwingConstants.LEFT);
+    clustaljv.setFont(verdana11);
+    clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
+    pfamjv.setFont(verdana11);
+    pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
+    pileupjv.setFont(verdana11);
+    pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
+    pirjv.setFont(verdana11);
+    pirjv.setHorizontalAlignment(SwingConstants.LEFT);
+    seqLimit.setFont(verdana11);
+    seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
+    seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
+    seqLimit.setMargin(new Insets(2, 2, 2, 0));
+    seqLimit.setText("Full Sequence Id");
+    gridLayout3.setRows(8);
+    smoothFont.setFont(verdana11);
+    smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
+    smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
+    smoothFont.setText("Smooth Font");
+    calcTab.setLayout(null);
+    autoCalculateConsCheck.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    autoCalculateConsCheck.setText("AutoCalculate Consensus");
+    autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
+    padGaps.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    padGaps.setText("Pad gaps when editing");
+    padGaps.setBounds(new Rectangle(22, 94, 168, 23));
+    modellerOutput.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    modellerOutput.setText("Use Modeller Output");
+    modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
+    dasPanel.setLayout(borderLayout4);
+    wrap.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    wrap.setHorizontalAlignment(SwingConstants.TRAILING);
+    wrap.setHorizontalTextPosition(SwingConstants.LEADING);
+    wrap.setText("Wrap Alignment");
+    jPanel2.add(fullScreen);
+
+    jPanel2.add(annotations);
+    jPanel2.add(seqLimit);
+    jPanel2.add(fontLabel);
+    jPanel2.add(smoothFont);
+    jPanel2.add(wrap);
+    jPanel2.add(gapLabel);
+    jPanel2.add(colourLabel);
+    jPanel2.add(sortLabel);
+    jPanel2.add(startupCheckbox);
+    visualTab.add(sortby);
+    visualTab.add(gapSymbolCB);
+    visualTab.add(colour);
+    visualTab.add(fontNameCB);
+    visualTab.add(fontSizeCB);
+    visualTab.add(fontStyleCB);
+    visualTab.add(jPanel3);
+    visualTab.add(startupFileTextfield);
+    jPanel3.add(conservation);
+    jPanel3.add(identity);
+    jPanel3.add(quality);
+    visualTab.add(jPanel2);
+    linkPanel.add(editLinkButtons, BorderLayout.EAST);
+    editLinkButtons.add(newLink, null);
+    editLinkButtons.add(editLink, null);
+    editLinkButtons.add(deleteLink, null);
+    linkPanel.add(linkScrollPane, BorderLayout.CENTER);
+    linkScrollPane.getViewport().add(linkPanel2, null);
+    linkPanel2.add(linkURLList, BorderLayout.CENTER);
+    linkPanel2.add(linkNameList, BorderLayout.WEST);
+        okCancelPanel.add(ok);
+        okCancelPanel.add(cancel);
+    this.add(tabbedPane, java.awt.BorderLayout.CENTER);
+
+        this.add(okCancelPanel, java.awt.BorderLayout.SOUTH);
+    jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
+        , GridBagConstraints.WEST, GridBagConstraints.NONE,
+        new Insets(0, 2, 4, 0), 5, 0));
+    jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0
+                                                  , GridBagConstraints.WEST,
+                                                  GridBagConstraints.NONE,
+                                                  new Insets(0, 0, 4, 0), 11, 6));
+    connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0
+        , GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+        new Insets(16, 0, 0, 12), 359, -17));
+    connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0
+        , GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+        new Insets(21, 0, 35, 12), 4, 6));
+    connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
+        , GridBagConstraints.WEST, GridBagConstraints.NONE,
+        new Insets(16, 0, 0, 0), 5, 1));
+    jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0
+        , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+        new Insets(0, 2, 4, 2), 54, 1));
+    jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0
+        , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+        new Insets(0, 2, 4, 0), 263, 1));
+    connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0
+        , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+        new Insets(15, 0, 0, 15), 307, 1));
+
+
+    jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0
+                                                 , GridBagConstraints.WEST,
+                                                 GridBagConstraints.NONE,
+                                                 new Insets(0, 2, 5, 185), 2,
+                                                 -4));
+    DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
+        dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
+        gapSymbolCB.setRenderer(dlcr);
+
+    tabbedPane.add(visualTab, "Visual");
+    tabbedPane.add(connectTab,"Connections");
+    tabbedPane.add(exportTab, "Output");
+    jPanel11.add(jLabel1);
+    jPanel11.add(blcjv);
+    jPanel11.add(clustaljv);
+    jPanel11.add(fastajv);
+    jPanel11.add(msfjv);
+    jPanel11.add(pfamjv);
+    jPanel11.add(pileupjv);
+    jPanel11.add(pirjv);
+    exportTab.add(modellerOutput);
+    tabbedPane.add(calcTab, "Editing");
+    calcTab.add(autoCalculateConsCheck);
+    calcTab.add(padGaps);
+    tabbedPane.add(dasPanel, "DAS Settings");
+
+    exportTab.add(epsLabel);
+    exportTab.add(epsRendering);
+    exportTab.add(jPanel11);
+  }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void ok_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void cancel_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void annotations_actionPerformed(ActionEvent e)
+    {
+    }
+
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void startupFileTextfield_mouseClicked()
+    {
+    }
+
+
+  public void newLink_actionPerformed(ActionEvent e) {
+
+  }
+
+  public void editLink_actionPerformed(ActionEvent e) {
+
+  }
+
+  public void deleteLink_actionPerformed(ActionEvent e) {
+
+  }
+
+  public void defaultBrowser_mouseClicked(MouseEvent e)
+  {
+
+  }
+
+  public void linkURLList_keyTyped(KeyEvent e)
+  {
+
+  }
+
+  public void useProxy_actionPerformed()
+  {
+      proxyServerTB.setEnabled(useProxy.isSelected());
+      proxyPortTB.setEnabled(useProxy.isSelected());
+  }
+}
index 6b308b4..a7d5568 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import javax.swing.JTextField;\r
-import javax.swing.JLabel;\r
-import javax.swing.*;\r
-import java.awt.event.KeyAdapter;\r
-import java.awt.event.KeyEvent;\r
-\r
-public class GSequenceLink\r
-    extends Panel\r
-{\r
-  public GSequenceLink()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.setLayout(gridBagLayout1);\r
-    nameTB.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    nameTB.setBounds(new Rectangle(77, 10, 310, 23));\r
-    nameTB.addKeyListener(new KeyAdapter()\r
-    {\r
-      public void keyTyped(KeyEvent e)\r
-      {\r
-        nameTB_keyTyped(e);\r
-      }\r
-    });\r
-    urlTB.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    urlTB.setText("http://www.");\r
-    urlTB.setBounds(new Rectangle(78, 40, 309, 23));\r
-    urlTB.addKeyListener(new KeyAdapter()\r
-    {\r
-      public void keyTyped(KeyEvent e)\r
-      {\r
-        urlTB_keyTyped(e);\r
-      }\r
-    });\r
-    jLabel1.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    jLabel1.setHorizontalAlignment(SwingConstants.TRAILING);\r
-    jLabel1.setText("Link Name");\r
-    jLabel1.setBounds(new Rectangle(4, 10, 71, 24));\r
-    jLabel2.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    jLabel2.setHorizontalAlignment(SwingConstants.TRAILING);\r
-    jLabel2.setText("URL");\r
-    jLabel2.setBounds(new Rectangle(17, 37, 54, 27));\r
-    jLabel3.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));\r
-    jLabel3.setText("Use $SEQUENCE_ID$ to specify where sequence id is in URL");\r
-    jLabel3.setBounds(new Rectangle(21, 72, 351, 15));\r
-    jPanel1.setBorder(BorderFactory.createEtchedBorder());\r
-    jPanel1.setLayout(null);\r
-    jPanel1.add(jLabel1);\r
-    jPanel1.add(nameTB);\r
-    jPanel1.add(urlTB);\r
-    jPanel1.add(jLabel2);\r
-    jPanel1.add(jLabel3);\r
-    this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0\r
-                                             , GridBagConstraints.CENTER,\r
-                                             GridBagConstraints.BOTH,\r
-                                             new Insets(5, 4, 6, 5), 390, 100));\r
-  }\r
-\r
-  public void setName(String name)\r
-  {\r
-    nameTB.setText(name);\r
-  }\r
-\r
-  public void setURL(String url)\r
-  {\r
-    urlTB.setText(url);\r
-  }\r
-\r
-  public String getName()\r
-  {\r
-    return nameTB.getText();\r
-  }\r
-\r
-  public String getURL()\r
-  {\r
-    return urlTB.getText();\r
-  }\r
-\r
-  public boolean checkValid()\r
-  {\r
-    if(urlTB.getText().indexOf("$SEQUENCE_ID$")==-1)\r
-    {\r
-      JOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,\r
-                                            "Sequence URL must contain $SEQUENCE_ID$",\r
-           "URL not valid", JOptionPane.WARNING_MESSAGE);\r
-      return false;\r
-    }\r
-    return true;\r
-  }\r
-\r
-\r
-\r
-  JTextField nameTB = new JTextField();\r
-  JTextField urlTB = new JTextField();\r
-  JLabel jLabel1 = new JLabel();\r
-  JLabel jLabel2 = new JLabel();\r
-  JLabel jLabel3 = new JLabel();\r
-  JPanel jPanel1 = new JPanel();\r
-  GridBagLayout gridBagLayout1 = new GridBagLayout();\r
-  public void nameTB_keyTyped(KeyEvent e)\r
-  {\r
-    if(e.getKeyChar()=='|')\r
-     {\r
-       e.consume();\r
-     }\r
-  }\r
-\r
-  public void urlTB_keyTyped(KeyEvent e)\r
-  {\r
-    if (e.getKeyChar() == '|' || e.getKeyChar()==' ')\r
-    {\r
-      e.consume();\r
-    }\r
-\r
-  }\r
-}\r
-\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import javax.swing.JTextField;
+import javax.swing.JLabel;
+import javax.swing.*;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+public class GSequenceLink
+    extends Panel
+{
+  public GSequenceLink()
+  {
+    try
+    {
+      jbInit();
+    }
+    catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    this.setLayout(gridBagLayout1);
+    nameTB.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    nameTB.setBounds(new Rectangle(77, 10, 310, 23));
+    nameTB.addKeyListener(new KeyAdapter()
+    {
+      public void keyTyped(KeyEvent e)
+      {
+        nameTB_keyTyped(e);
+      }
+    });
+    urlTB.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    urlTB.setText("http://www.");
+    urlTB.setBounds(new Rectangle(78, 40, 309, 23));
+    urlTB.addKeyListener(new KeyAdapter()
+    {
+      public void keyTyped(KeyEvent e)
+      {
+        urlTB_keyTyped(e);
+      }
+    });
+    jLabel1.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    jLabel1.setHorizontalAlignment(SwingConstants.TRAILING);
+    jLabel1.setText("Link Name");
+    jLabel1.setBounds(new Rectangle(4, 10, 71, 24));
+    jLabel2.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    jLabel2.setHorizontalAlignment(SwingConstants.TRAILING);
+    jLabel2.setText("URL");
+    jLabel2.setBounds(new Rectangle(17, 37, 54, 27));
+    jLabel3.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+    jLabel3.setText("Use $SEQUENCE_ID$ to specify where sequence id is in URL");
+    jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
+    jPanel1.setBorder(BorderFactory.createEtchedBorder());
+    jPanel1.setLayout(null);
+    jPanel1.add(jLabel1);
+    jPanel1.add(nameTB);
+    jPanel1.add(urlTB);
+    jPanel1.add(jLabel2);
+    jPanel1.add(jLabel3);
+    this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0
+                                             , GridBagConstraints.CENTER,
+                                             GridBagConstraints.BOTH,
+                                             new Insets(5, 4, 6, 5), 390, 100));
+  }
+
+  public void setName(String name)
+  {
+    nameTB.setText(name);
+  }
+
+  public void setURL(String url)
+  {
+    urlTB.setText(url);
+  }
+
+  public String getName()
+  {
+    return nameTB.getText();
+  }
+
+  public String getURL()
+  {
+    return urlTB.getText();
+  }
+
+  public boolean checkValid()
+  {
+    if(urlTB.getText().indexOf("$SEQUENCE_ID$")==-1)
+    {
+      JOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+                                            "Sequence URL must contain $SEQUENCE_ID$",
+           "URL not valid", JOptionPane.WARNING_MESSAGE);
+      return false;
+    }
+    return true;
+  }
+
+
+
+  JTextField nameTB = new JTextField();
+  JTextField urlTB = new JTextField();
+  JLabel jLabel1 = new JLabel();
+  JLabel jLabel2 = new JLabel();
+  JLabel jLabel3 = new JLabel();
+  JPanel jPanel1 = new JPanel();
+  GridBagLayout gridBagLayout1 = new GridBagLayout();
+  public void nameTB_keyTyped(KeyEvent e)
+  {
+    if(e.getKeyChar()=='|')
+     {
+       e.consume();
+     }
+  }
+
+  public void urlTB_keyTyped(KeyEvent e)
+  {
+    if (e.getKeyChar() == '|' || e.getKeyChar()==' ')
+    {
+      e.consume();
+    }
+
+  }
+}
+
index c452d11..cd77229 100755 (executable)
@@ -1,6 +1,6 @@
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GSliderPanel extends JPanel\r
-{\r
-    // this is used for conservation colours, PID colours and redundancy threshold\r
-    protected JSlider slider = new JSlider();\r
-    protected JTextField valueField = new JTextField();\r
-    protected JLabel label = new JLabel();\r
-    JPanel jPanel1 = new JPanel();\r
-    GridLayout gridLayout1 = new GridLayout();\r
-    JPanel jPanel2 = new JPanel();\r
-    protected JButton applyButton = new JButton();\r
-    protected JButton undoButton = new JButton();\r
-    FlowLayout flowLayout1 = new FlowLayout();\r
-    protected JCheckBox allGroupsCheck = new JCheckBox();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-\r
-    /**\r
-     * Creates a new GSliderPanel object.\r
-     */\r
-    public GSliderPanel()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        this.setLayout(gridLayout1);\r
-        slider.setMajorTickSpacing(10);\r
-        slider.setMinorTickSpacing(1);\r
-        slider.setPaintTicks(true);\r
-        slider.setBackground(Color.white);\r
-        slider.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        slider.setDoubleBuffered(true);\r
-        valueField.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        valueField.setMinimumSize(new Dimension(6, 14));\r
-        valueField.setPreferredSize(new Dimension(50, 12));\r
-        valueField.setText("");\r
-        valueField.setHorizontalAlignment(SwingConstants.CENTER);\r
-        valueField.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    valueField_actionPerformed(e);\r
-                }\r
-            });\r
-        label.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        label.setOpaque(false);\r
-        label.setHorizontalAlignment(SwingConstants.CENTER);\r
-        label.setText("set this label text");\r
-        jPanel1.setLayout(borderLayout1);\r
-        gridLayout1.setRows(2);\r
-        jPanel2.setLayout(flowLayout1);\r
-        applyButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        applyButton.setOpaque(false);\r
-        applyButton.setText("Apply");\r
-        applyButton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    applyButton_actionPerformed(e);\r
-                }\r
-            });\r
-        undoButton.setEnabled(false);\r
-        undoButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        undoButton.setOpaque(false);\r
-        undoButton.setText("Undo");\r
-        undoButton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    undoButton_actionPerformed(e);\r
-                }\r
-            });\r
-        allGroupsCheck.setEnabled(false);\r
-        allGroupsCheck.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        allGroupsCheck.setOpaque(false);\r
-        allGroupsCheck.setText("Apply to all Groups");\r
-        allGroupsCheck.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    allGroupsCheck_actionPerformed(e);\r
-                }\r
-            });\r
-        this.setBackground(Color.white);\r
-        this.setPreferredSize(new Dimension(415, 84));\r
-        jPanel2.setOpaque(false);\r
-        jPanel1.setOpaque(false);\r
-        this.add(jPanel2, null);\r
-        jPanel2.add(label, null);\r
-        jPanel2.add(applyButton, null);\r
-        jPanel2.add(undoButton, null);\r
-        this.add(jPanel1, null);\r
-        jPanel1.add(slider, BorderLayout.WEST);\r
-        jPanel1.add(valueField, BorderLayout.CENTER);\r
-        jPanel1.add(allGroupsCheck, BorderLayout.EAST);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void valueField_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void applyButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void undoButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void allGroupsCheck_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-}\r
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import java.awt.BorderLayout;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GSliderPanel extends JPanel
+{
+    // this is used for conservation colours, PID colours and redundancy threshold
+    protected JSlider slider = new JSlider();
+    protected JTextField valueField = new JTextField();
+    protected JLabel label = new JLabel();
+    protected JPanel southPanel = new JPanel();
+    GridLayout gridLayout1 = new GridLayout();
+    JPanel jPanel2 = new JPanel();
+    protected JButton applyButton = new JButton();
+    protected JButton undoButton = new JButton();
+    FlowLayout flowLayout1 = new FlowLayout();
+    protected JCheckBox allGroupsCheck = new JCheckBox();
+    BorderLayout borderLayout1 = new BorderLayout();
+  JPanel jPanel1 = new JPanel();
+  BorderLayout borderLayout2 = new BorderLayout();
+
+  /**
+     * Creates a new GSliderPanel object.
+     */
+    public GSliderPanel()
+    {
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        this.setLayout(gridLayout1);
+        slider.setMajorTickSpacing(10);
+        slider.setMinorTickSpacing(1);
+        slider.setPaintTicks(true);
+        slider.setBackground(Color.white);
+        slider.setFont(new java.awt.Font("Verdana", 0, 11));
+        slider.setDoubleBuffered(true);
+    slider.addMouseListener(new MouseAdapter()
+    {
+      public void mouseReleased(MouseEvent e)
+      {
+        slider_mouseReleased(e);
+      }
+    });
+    valueField.setFont(new java.awt.Font("Verdana", 0, 11));
+        valueField.setMinimumSize(new Dimension(6, 14));
+        valueField.setPreferredSize(new Dimension(50, 12));
+        valueField.setText("");
+        valueField.setHorizontalAlignment(SwingConstants.CENTER);
+        valueField.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    valueField_actionPerformed(e);
+                }
+            });
+        label.setFont(new java.awt.Font("Verdana", 0, 11));
+        label.setOpaque(false);
+        label.setHorizontalAlignment(SwingConstants.CENTER);
+        label.setText("set this label text");
+    southPanel.setLayout(borderLayout1);
+        gridLayout1.setRows(2);
+        jPanel2.setLayout(flowLayout1);
+        applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
+        applyButton.setOpaque(false);
+        applyButton.setText("Apply");
+        applyButton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    applyButton_actionPerformed(e);
+                }
+            });
+        undoButton.setEnabled(false);
+        undoButton.setFont(new java.awt.Font("Verdana", 0, 11));
+        undoButton.setOpaque(false);
+        undoButton.setText("Undo");
+        undoButton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    undoButton_actionPerformed(e);
+                }
+            });
+        allGroupsCheck.setEnabled(false);
+        allGroupsCheck.setFont(new java.awt.Font("Verdana", 0, 11));
+        allGroupsCheck.setOpaque(false);
+        allGroupsCheck.setText("Apply to all Groups");
+        allGroupsCheck.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    allGroupsCheck_actionPerformed(e);
+                }
+            });
+        this.setBackground(Color.white);
+        this.setPreferredSize(new Dimension(415, 84));
+        jPanel2.setOpaque(false);
+    southPanel.setOpaque(false);
+    jPanel1.setLayout(borderLayout2);
+    jPanel1.setOpaque(false);
+    this.add(jPanel2, null);
+        jPanel2.add(label, null);
+        jPanel2.add(applyButton, null);
+        jPanel2.add(undoButton, null);
+        this.add(southPanel, null);
+    southPanel.add(jPanel1, java.awt.BorderLayout.EAST);
+    southPanel.add(slider, java.awt.BorderLayout.CENTER);
+    jPanel1.add(valueField, java.awt.BorderLayout.CENTER);
+    jPanel1.add(allGroupsCheck, java.awt.BorderLayout.EAST);
+  }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void valueField_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void applyButton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void undoButton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void allGroupsCheck_actionPerformed(ActionEvent e)
+    {
+    }
+
+    public void slider_mouseReleased(MouseEvent e)
+    {
+
+    }
+  }
index a70920c..d7c8704 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import javax.swing.*;\r
-\r
-public class GTreePanel\r
-    extends JInternalFrame\r
-{\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  public JScrollPane scrollPane = new JScrollPane();\r
-  JMenuBar jMenuBar1 = new JMenuBar();\r
-  JMenu jMenu1 = new JMenu();\r
-  JMenuItem saveAsNewick = new JMenuItem();\r
-  JMenuItem printMenu = new JMenuItem();\r
-  JMenu jMenu2 = new JMenu();\r
-  public JMenuItem font = new JMenuItem();\r
-  public JCheckBoxMenuItem bootstrapMenu = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem distanceMenu = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem fitToWindow = new JCheckBoxMenuItem();\r
-  public JCheckBoxMenuItem placeholdersMenu = new JCheckBoxMenuItem();\r
-  JMenuItem pngTree = new JMenuItem();\r
-  JMenuItem epsTree = new JMenuItem();\r
-  JMenu saveAsMenu = new JMenu();\r
-  JMenuItem textbox = new JMenuItem();\r
-  public GTreePanel()\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-      this.setJMenuBar(jMenuBar1);\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.getContentPane().setLayout(borderLayout1);\r
-    this.setBackground(Color.white);\r
-    this.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    scrollPane.setOpaque(false);\r
-    jMenu1.setText("File");\r
-    saveAsNewick.setText("Newick Format");\r
-    saveAsNewick.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        saveAsNewick_actionPerformed(e);\r
-      }\r
-    });\r
-    printMenu.setText("Print");\r
-    printMenu.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        printMenu_actionPerformed(e);\r
-      }\r
-    });\r
-    jMenu2.setText("View");\r
-    font.setText("Font...");\r
-    font.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        font_actionPerformed(e);\r
-      }\r
-    });\r
-    bootstrapMenu.setText("Show Bootstrap Values");\r
-    bootstrapMenu.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        bootstrapMenu_actionPerformed(e);\r
-      }\r
-    });\r
-    distanceMenu.setText("Show Distances");\r
-    distanceMenu.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        distanceMenu_actionPerformed(e);\r
-      }\r
-    });\r
-    fitToWindow.setSelected(true);\r
-    fitToWindow.setText("Fit To Window");\r
-    fitToWindow.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        fitToWindow_actionPerformed(e);\r
-      }\r
-    });\r
-    epsTree.setText("EPS");\r
-    epsTree.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        epsTree_actionPerformed(e);\r
-      }\r
-    });\r
-    pngTree.setText("PNG");\r
-    pngTree.addActionListener(new java.awt.event.ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        pngTree_actionPerformed(e);\r
-      }\r
-    });\r
-    saveAsMenu.setText("Save as");\r
-    placeholdersMenu.setToolTipText(\r
-        "Marks leaves of tree not associated with a sequence");\r
-    placeholdersMenu.setText("Mark Unlinked Leaves");\r
-    placeholdersMenu.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        placeholdersMenu_actionPerformed(e);\r
-      }\r
-    });\r
-    textbox.setText("Output to Textbox...");\r
-    textbox.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        textbox_actionPerformed(e);\r
-      }\r
-    });\r
-    this.getContentPane().add(scrollPane, BorderLayout.CENTER);\r
-    jMenuBar1.add(jMenu1);\r
-    jMenuBar1.add(jMenu2);\r
-    jMenu1.add(saveAsMenu);\r
-    jMenu1.add(textbox);\r
-    jMenu1.add(printMenu);\r
-    jMenu2.add(fitToWindow);\r
-    jMenu2.add(font);\r
-    jMenu2.add(distanceMenu);\r
-    jMenu2.add(bootstrapMenu);\r
-    jMenu2.add(placeholdersMenu);\r
-    saveAsMenu.add(saveAsNewick);\r
-    saveAsMenu.add(epsTree);\r
-    saveAsMenu.add(pngTree);\r
-  }\r
-\r
-  public void printMenu_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void font_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void distanceMenu_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void bootstrapMenu_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void fitToWindow_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void pngTree_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void epsTree_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void saveAsNewick_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void placeholdersMenu_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void textbox_actionPerformed(ActionEvent e)\r
-  {\r
-  }\r
-\r
-  public void fullid_actionPerformed(ActionEvent e)\r
-  {\r
-\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class GTreePanel
+    extends JInternalFrame
+{
+  BorderLayout borderLayout1 = new BorderLayout();
+  public JScrollPane scrollPane = new JScrollPane();
+  JMenuBar jMenuBar1 = new JMenuBar();
+  JMenu jMenu1 = new JMenu();
+  JMenuItem saveAsNewick = new JMenuItem();
+  JMenuItem printMenu = new JMenuItem();
+  JMenu jMenu2 = new JMenu();
+  public JMenuItem font = new JMenuItem();
+  public JCheckBoxMenuItem bootstrapMenu = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem distanceMenu = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem fitToWindow = new JCheckBoxMenuItem();
+  public JCheckBoxMenuItem placeholdersMenu = new JCheckBoxMenuItem();
+  JMenuItem pngTree = new JMenuItem();
+  JMenuItem epsTree = new JMenuItem();
+  JMenu saveAsMenu = new JMenu();
+  JMenuItem textbox = new JMenuItem();
+  public JMenuItem originalSeqData = new JMenuItem();
+  public GTreePanel()
+  {
+    try
+    {
+      jbInit();
+      this.setJMenuBar(jMenuBar1);
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+  }
+
+  private void jbInit()
+      throws Exception
+  {
+    this.getContentPane().setLayout(borderLayout1);
+    this.setBackground(Color.white);
+    this.setFont(new java.awt.Font("Verdana", 0, 12));
+    scrollPane.setOpaque(false);
+    jMenu1.setText("File");
+    saveAsNewick.setText("Newick Format");
+    saveAsNewick.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        saveAsNewick_actionPerformed(e);
+      }
+    });
+    printMenu.setText("Print");
+    printMenu.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        printMenu_actionPerformed(e);
+      }
+    });
+    jMenu2.setText("View");
+    font.setText("Font...");
+    font.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        font_actionPerformed(e);
+      }
+    });
+    bootstrapMenu.setText("Show Bootstrap Values");
+    bootstrapMenu.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        bootstrapMenu_actionPerformed(e);
+      }
+    });
+    distanceMenu.setText("Show Distances");
+    distanceMenu.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        distanceMenu_actionPerformed(e);
+      }
+    });
+    fitToWindow.setSelected(true);
+    fitToWindow.setText("Fit To Window");
+    fitToWindow.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        fitToWindow_actionPerformed(e);
+      }
+    });
+    epsTree.setText("EPS");
+    epsTree.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        epsTree_actionPerformed(e);
+      }
+    });
+    pngTree.setText("PNG");
+    pngTree.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        pngTree_actionPerformed(e);
+      }
+    });
+    saveAsMenu.setText("Save as");
+    placeholdersMenu.setToolTipText(
+        "Marks leaves of tree not associated with a sequence");
+    placeholdersMenu.setText("Mark Unlinked Leaves");
+    placeholdersMenu.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        placeholdersMenu_actionPerformed(e);
+      }
+    });
+    textbox.setText("Output to Textbox...");
+    textbox.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        textbox_actionPerformed(e);
+      }
+    });
+    originalSeqData.setText("Input Data...");
+    originalSeqData.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        originalSeqData_actionPerformed(e);
+      }
+    });
+    this.getContentPane().add(scrollPane, BorderLayout.CENTER);
+    jMenuBar1.add(jMenu1);
+    jMenuBar1.add(jMenu2);
+    jMenu1.add(saveAsMenu);
+    jMenu1.add(textbox);
+    jMenu1.add(printMenu);
+    jMenu1.add(originalSeqData);
+    jMenu2.add(fitToWindow);
+    jMenu2.add(font);
+    jMenu2.add(distanceMenu);
+    jMenu2.add(bootstrapMenu);
+    jMenu2.add(placeholdersMenu);
+    saveAsMenu.add(saveAsNewick);
+    saveAsMenu.add(epsTree);
+    saveAsMenu.add(pngTree);
+  }
+
+  public void printMenu_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void font_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void distanceMenu_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void bootstrapMenu_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void fitToWindow_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void pngTree_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void epsTree_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void saveAsNewick_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void placeholdersMenu_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void textbox_actionPerformed(ActionEvent e)
+  {
+  }
+
+  public void fullid_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+  public void originalSeqData_actionPerformed(ActionEvent e)
+  {
+
+  }
+}
index 131f202..dcc6163 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GUserDefinedColours extends JPanel\r
-{\r
-    protected JColorChooser colorChooser = new JColorChooser();\r
-    protected JPanel buttonPanel = new JPanel();\r
-    protected GridLayout gridLayout = new GridLayout();\r
-    JPanel jPanel2 = new JPanel();\r
-    protected JButton okButton = new JButton();\r
-    protected JButton applyButton = new JButton();\r
-    protected JButton loadbutton = new JButton();\r
-    protected JButton savebutton = new JButton();\r
-    protected JButton cancelButton = new JButton();\r
-  JPanel namePanel = new JPanel();\r
-  JLabel jLabel1 = new JLabel();\r
-  protected JTextField schemeName = new JTextField();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  JPanel panel1 = new JPanel();\r
-  JPanel jPanel1 = new JPanel();\r
-  JPanel jPanel3 = new JPanel();\r
-  BorderLayout borderLayout3 = new BorderLayout();\r
-  GridBagLayout gridBagLayout1 = new GridBagLayout();\r
-  BorderLayout borderLayout2 = new BorderLayout();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  BorderLayout borderLayout4 = new BorderLayout();\r
-  JPanel jPanel4 = new JPanel();\r
-  BorderLayout borderLayout5 = new BorderLayout();\r
-  JPanel jPanel6 = new JPanel();\r
-  JTextArea jTextArea1 = new JTextArea();\r
-  /**\r
-     * Creates a new GUserDefinedColours object.\r
-     */\r
-    public GUserDefinedColours()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        this.setLayout(borderLayout4);\r
-        buttonPanel.setLayout(gridLayout);\r
-        gridLayout.setColumns(4);\r
-        gridLayout.setRows(6);\r
-        okButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        okButton.setText("OK");\r
-        okButton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    okButton_actionPerformed(e);\r
-                }\r
-            });\r
-        applyButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        applyButton.setText("Apply");\r
-        applyButton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    applyButton_actionPerformed(e);\r
-                }\r
-            });\r
-        loadbutton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        loadbutton.setText("Load scheme");\r
-        loadbutton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    loadbutton_actionPerformed(e);\r
-                }\r
-            });\r
-        savebutton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        savebutton.setText("Save scheme");\r
-        savebutton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    savebutton_actionPerformed(e);\r
-                }\r
-            });\r
-        cancelButton.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        cancelButton.setText("Cancel");\r
-        cancelButton.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    cancelButton_actionPerformed(e);\r
-                }\r
-            });\r
-        this.setBackground(new Color(212, 208, 223));\r
-        jPanel2.setOpaque(false);\r
-    jPanel2.setLayout(borderLayout3);\r
-    colorChooser.setOpaque(false);\r
-    jLabel1.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    jLabel1.setText("Name");\r
-    namePanel.setMinimumSize(new Dimension(300, 31));\r
-    namePanel.setOpaque(false);\r
-    namePanel.setPreferredSize(new Dimension(240, 25));\r
-    namePanel.setToolTipText("");\r
-    namePanel.setLayout(borderLayout1);\r
-    schemeName.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    schemeName.setPreferredSize(new Dimension(105, 21));\r
-    schemeName.setText("");\r
-    schemeName.setHorizontalAlignment(SwingConstants.CENTER);\r
-    panel1.setLayout(flowLayout1);\r
-    panel1.setOpaque(false);\r
-    jPanel1.setOpaque(false);\r
-    jPanel3.setOpaque(false);\r
-    jPanel4.setLayout(borderLayout5);\r
-    jPanel6.setBackground(Color.pink);\r
-    jPanel6.setMinimumSize(new Dimension(10, 70));\r
-    jPanel6.setOpaque(false);\r
-    jPanel6.setPreferredSize(new Dimension(10, 45));\r
-    jPanel6.setLayout(null);\r
-    jTextArea1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 10));\r
-    jTextArea1.setOpaque(false);\r
-    jTextArea1.setPreferredSize(new Dimension(260, 34));\r
-    jTextArea1.setText(\r
-        "Save your colour scheme with a unique name and it will be added " +\r
-        "to the Colour menu.");\r
-    jTextArea1.setLineWrap(true);\r
-    jTextArea1.setRows(2);\r
-    jTextArea1.setWrapStyleWord(true);\r
-    jPanel3.add(savebutton);\r
-    jPanel3.add(loadbutton);\r
-    jPanel1.add(applyButton);\r
-    jPanel1.add(okButton);\r
-    jPanel1.add(cancelButton);\r
-    jPanel2.add(jPanel3, java.awt.BorderLayout.NORTH);\r
-    jPanel2.add(jPanel1, java.awt.BorderLayout.SOUTH);\r
-\r
-    namePanel.add(schemeName, java.awt.BorderLayout.CENTER);\r
-    namePanel.add(jLabel1, java.awt.BorderLayout.WEST);\r
-    panel1.add(namePanel, null);\r
-    panel1.add(buttonPanel, null);\r
-    panel1.add(jPanel2, null);\r
-    panel1.add(jTextArea1);\r
-\r
-    jPanel4.add(panel1, java.awt.BorderLayout.CENTER);\r
-    jPanel4.add(jPanel6, java.awt.BorderLayout.NORTH);\r
-    this.add(jPanel4, java.awt.BorderLayout.CENTER);\r
-    this.add(colorChooser, java.awt.BorderLayout.EAST);\r
-  }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void okButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void applyButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void loadbutton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void savebutton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void cancelButton_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import java.awt.Dimension;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GUserDefinedColours extends JPanel
+{
+    protected JColorChooser colorChooser = new JColorChooser();
+    protected JPanel buttonPanel = new JPanel();
+    protected GridLayout gridLayout = new GridLayout();
+    JPanel lowerPanel = new JPanel();
+    protected JButton okButton = new JButton();
+    protected JButton applyButton = new JButton();
+    protected JButton loadbutton = new JButton();
+    protected JButton savebutton = new JButton();
+    protected JButton cancelButton = new JButton();
+  JPanel namePanel = new JPanel();
+  JLabel jLabel1 = new JLabel();
+  protected JTextField schemeName = new JTextField();
+  BorderLayout borderLayout1 = new BorderLayout();
+  JPanel panel1 = new JPanel();
+  JPanel okCancelPanel = new JPanel();
+  JPanel saveLoadPanel = new JPanel();
+  BorderLayout borderLayout3 = new BorderLayout();
+  GridBagLayout gridBagLayout1 = new GridBagLayout();
+  BorderLayout borderLayout2 = new BorderLayout();
+  FlowLayout flowLayout1 = new FlowLayout();
+  BorderLayout borderLayout4 = new BorderLayout();
+  JPanel jPanel4 = new JPanel();
+  BorderLayout borderLayout5 = new BorderLayout();
+  JLabel label = new JLabel();
+  JPanel casePanel = new JPanel();
+  protected JCheckBox caseSensitive = new JCheckBox();
+  protected JButton lcaseColour = new JButton();
+  /**
+     * Creates a new GUserDefinedColours object.
+     */
+    public GUserDefinedColours()
+    {
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        this.setLayout(borderLayout4);
+        buttonPanel.setLayout(gridLayout);
+        gridLayout.setColumns(4);
+        gridLayout.setRows(5);
+        okButton.setFont(new java.awt.Font("Verdana", 0, 11));
+        okButton.setText("OK");
+        okButton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    okButton_actionPerformed(e);
+                }
+            });
+        applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
+        applyButton.setText("Apply");
+        applyButton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    applyButton_actionPerformed(e);
+                }
+            });
+        loadbutton.setFont(new java.awt.Font("Verdana", 0, 11));
+        loadbutton.setText("Load scheme");
+        loadbutton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    loadbutton_actionPerformed(e);
+                }
+            });
+        savebutton.setFont(new java.awt.Font("Verdana", 0, 11));
+        savebutton.setText("Save scheme");
+        savebutton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    savebutton_actionPerformed(e);
+                }
+            });
+        cancelButton.setFont(new java.awt.Font("Verdana", 0, 11));
+        cancelButton.setText("Cancel");
+        cancelButton.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    cancelButton_actionPerformed(e);
+                }
+            });
+        this.setBackground(new Color(212, 208, 223));
+    lowerPanel.setOpaque(false);
+    lowerPanel.setLayout(borderLayout3);
+    colorChooser.setOpaque(false);
+    jLabel1.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    jLabel1.setText("Name");
+    namePanel.setMinimumSize(new Dimension(300, 31));
+    namePanel.setOpaque(false);
+    namePanel.setPreferredSize(new Dimension(240, 25));
+    namePanel.setToolTipText("");
+    namePanel.setLayout(borderLayout1);
+    schemeName.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+    schemeName.setPreferredSize(new Dimension(105, 21));
+    schemeName.setText("");
+    schemeName.setHorizontalAlignment(SwingConstants.CENTER);
+    panel1.setLayout(flowLayout1);
+    panel1.setOpaque(false);
+    okCancelPanel.setOpaque(false);
+    saveLoadPanel.setOpaque(false);
+    jPanel4.setLayout(borderLayout5);
+    label.setFont(new java.awt.Font("Verdana", Font.ITALIC, 10));
+    label.setOpaque(false);
+    label.setPreferredSize(new Dimension(260, 34));
+    label.setText(
+        "<html>Save your colour scheme with a unique name and it will be added " +
+        "to the Colour menu.</html>");
+    caseSensitive.setText("Case Sensitive");
+    caseSensitive.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        caseSensitive_actionPerformed(e);
+      }
+    });
+    lcaseColour.setText("Lower Case Colour");
+    lcaseColour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        lcaseColour_actionPerformed(e);
+      }
+    });
+
+    saveLoadPanel.add(savebutton);
+    saveLoadPanel.add(loadbutton);
+    okCancelPanel.add(applyButton);
+    okCancelPanel.add(okButton);
+    okCancelPanel.add(cancelButton);
+    lowerPanel.add(saveLoadPanel, java.awt.BorderLayout.NORTH);
+    lowerPanel.add(okCancelPanel, java.awt.BorderLayout.SOUTH);
+
+    namePanel.add(schemeName, java.awt.BorderLayout.CENTER);
+    namePanel.add(jLabel1, java.awt.BorderLayout.WEST);
+    panel1.add(namePanel, null);
+    panel1.add(buttonPanel, null);
+    panel1.add(casePanel);
+    casePanel.add(caseSensitive);
+    casePanel.add(lcaseColour);
+    panel1.add(lowerPanel, null);
+    panel1.add(label);
+
+    jPanel4.add(panel1, java.awt.BorderLayout.CENTER);
+    this.add(jPanel4, java.awt.BorderLayout.CENTER);
+    this.add(colorChooser, java.awt.BorderLayout.EAST);
+  }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void okButton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void applyButton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void loadbutton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void savebutton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void cancelButton_actionPerformed(ActionEvent e)
+    {
+    }
+
+    public void caseSensitive_actionPerformed(ActionEvent e)
+    {
+
+    }
+
+    public void lcaseColour_actionPerformed(ActionEvent e)
+    {
+
+    }
+}
index 6f8bbd7..9a00c57 100755 (executable)
@@ -1,6 +1,6 @@
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package jalview.jbgui;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class GWebserviceInfo extends JPanel\r
-{\r
-    protected JTextArea infoText = new JTextArea();\r
-    JScrollPane jScrollPane1 = new JScrollPane();\r
-    JScrollPane jScrollPane2 = new JScrollPane();\r
-    protected JTextArea progressText = new JTextArea();\r
-    JPanel jPanel1 = new JPanel();\r
-    BorderLayout borderLayout1 = new BorderLayout();\r
-    BorderLayout borderLayout2 = new BorderLayout();\r
-    protected JPanel titlePanel = new JPanel();\r
-    BorderLayout borderLayout3 = new BorderLayout();\r
-    JPanel jPanel2 = new JPanel();\r
-    protected JButton cancel = new JButton();\r
-    GridBagLayout gridBagLayout1 = new GridBagLayout();\r
-\r
-    /**\r
-     * Creates a new GWebserviceInfo object.\r
-     */\r
-    public GWebserviceInfo()\r
-    {\r
-        try\r
-        {\r
-            jbInit();\r
-        }\r
-        catch (Exception e)\r
-        {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @throws Exception DOCUMENT ME!\r
-     */\r
-    private void jbInit() throws Exception\r
-    {\r
-        infoText.setFont(new java.awt.Font("Verdana", 0, 10));\r
-        infoText.setBorder(null);\r
-        infoText.setEditable(false);\r
-        infoText.setText("");\r
-        infoText.setLineWrap(true);\r
-        infoText.setWrapStyleWord(true);\r
-        this.setLayout(borderLayout1);\r
-        progressText.setFont(new java.awt.Font("Verdana", 0, 10));\r
-        progressText.setBorder(null);\r
-        progressText.setEditable(false);\r
-        progressText.setText("");\r
-        progressText.setLineWrap(true);\r
-        progressText.setWrapStyleWord(true);\r
-        jPanel1.setLayout(borderLayout2);\r
-        titlePanel.setBackground(Color.white);\r
-        titlePanel.setPreferredSize(new Dimension(0, 60));\r
-        titlePanel.setLayout(borderLayout3);\r
-        jScrollPane2.setBorder(null);\r
-        jScrollPane1.setBorder(null);\r
-        jScrollPane1.setPreferredSize(new Dimension(400, 70));\r
-        cancel.setFont(new java.awt.Font("Verdana", 0, 11));\r
-        cancel.setText("Cancel");\r
-        cancel.addActionListener(new java.awt.event.ActionListener()\r
-            {\r
-                public void actionPerformed(ActionEvent e)\r
-                {\r
-                    cancel_actionPerformed(e);\r
-                }\r
-            });\r
-        jPanel2.setLayout(gridBagLayout1);\r
-        jPanel2.setOpaque(false);\r
-        this.add(jScrollPane2, BorderLayout.CENTER);\r
-        this.add(jPanel1, BorderLayout.NORTH);\r
-        jPanel1.add(jScrollPane1, BorderLayout.CENTER);\r
-        jScrollPane1.getViewport().add(infoText, null);\r
-        jScrollPane2.getViewport().add(progressText, null);\r
-        jPanel1.add(titlePanel, BorderLayout.NORTH);\r
-        titlePanel.add(jPanel2, BorderLayout.EAST);\r
-        jPanel2.add(cancel,\r
-            new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,\r
-                GridBagConstraints.SOUTH, GridBagConstraints.NONE,\r
-                new Insets(24, 5, 21, 5), 0, 0));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param e DOCUMENT ME!\r
-     */\r
-    protected void cancel_actionPerformed(ActionEvent e)\r
-    {\r
-    }\r
-}\r
+*/
+package jalview.jbgui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class GWebserviceInfo extends JPanel
+{
+    protected JTextArea infoText = new JTextArea();
+    JScrollPane jScrollPane1 = new JScrollPane();
+    JPanel jPanel1 = new JPanel();
+    BorderLayout borderLayout1 = new BorderLayout();
+    BorderLayout borderLayout2 = new BorderLayout();
+    protected JPanel titlePanel = new JPanel();
+    BorderLayout borderLayout3 = new BorderLayout();
+    protected JPanel buttonPanel = new JPanel();
+    public JButton cancel = new JButton();
+    public JButton showResultsNewFrame = new JButton();
+    public JButton mergeResults = new JButton();
+    GridBagLayout gridBagLayout1 = new GridBagLayout();
+  /**
+     * Creates a new GWebserviceInfo object.
+     */
+    public GWebserviceInfo()
+    {
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    private void jbInit() throws Exception
+    {
+        infoText.setFont(new java.awt.Font("Verdana", 0, 10));
+        infoText.setBorder(null);
+        infoText.setEditable(false);
+        infoText.setText("");
+        infoText.setLineWrap(true);
+        infoText.setWrapStyleWord(true);
+        this.setLayout(borderLayout1);
+        jPanel1.setLayout(borderLayout2);
+        titlePanel.setBackground(Color.white);
+        titlePanel.setPreferredSize(new Dimension(0, 60));
+        titlePanel.setLayout(borderLayout3);
+        jScrollPane1.setBorder(null);
+        jScrollPane1.setPreferredSize(new Dimension(400, 70));
+        cancel.setFont(new java.awt.Font("Verdana", 0, 11));
+        cancel.setText("Cancel");
+        cancel.addActionListener(new java.awt.event.ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    cancel_actionPerformed(e);
+                }
+            });
+    buttonPanel.setLayout(gridBagLayout1);
+    buttonPanel.setOpaque(false);
+    showResultsNewFrame.setText("New Frame");
+    mergeResults.setText("Merge Results");
+    this.setBackground(Color.white);
+    this.add(jPanel1, BorderLayout.NORTH);
+        jPanel1.add(jScrollPane1, BorderLayout.CENTER);
+        jScrollPane1.getViewport().add(infoText, null);
+        jPanel1.add(titlePanel, BorderLayout.NORTH);
+        titlePanel.add(buttonPanel, BorderLayout.EAST);
+    buttonPanel.add(cancel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
+                                               , GridBagConstraints.CENTER,
+                                               GridBagConstraints.NONE,
+                                               new Insets(19, 6, 16, 4), 0, 0));
+  }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    protected void cancel_actionPerformed(ActionEvent e)
+    {
+    }
+}
index f9abbda..0a7eacd 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.math;\r
-\r
-import jalview.util.*;\r
-\r
-import java.io.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Matrix\r
-{\r
-    /**\r
-     * SMJSPUBLIC\r
-     */\r
-    public double[][] value;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int rows;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public int cols;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public double[] d; // Diagonal\r
-\r
-    /** DOCUMENT ME!! */\r
-    public double[] e; // off diagonal\r
-\r
-    /**\r
-     * Creates a new Matrix object.\r
-     *\r
-     * @param value DOCUMENT ME!\r
-     * @param rows DOCUMENT ME!\r
-     * @param cols DOCUMENT ME!\r
-     */\r
-    public Matrix(double[][] value, int rows, int cols)\r
-    {\r
-        this.rows = rows;\r
-        this.cols = cols;\r
-        this.value = value;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Matrix transpose()\r
-    {\r
-        double[][] out = new double[cols][rows];\r
-\r
-        for (int i = 0; i < cols; i++)\r
-        {\r
-            for (int j = 0; j < rows; j++)\r
-            {\r
-                out[i][j] = value[j][i];\r
-            }\r
-        }\r
-\r
-        return new Matrix(out, cols, rows);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ps DOCUMENT ME!\r
-     */\r
-    public void print(PrintStream ps)\r
-    {\r
-        for (int i = 0; i < rows; i++)\r
-        {\r
-            for (int j = 0; j < cols; j++)\r
-            {\r
-                Format.print(ps, "%8.2f", value[i][j]);\r
-            }\r
-\r
-            ps.println();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param in DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Matrix preMultiply(Matrix in)\r
-    {\r
-        double[][] tmp = new double[in.rows][this.cols];\r
-\r
-        for (int i = 0; i < in.rows; i++)\r
-        {\r
-            for (int j = 0; j < this.cols; j++)\r
-            {\r
-                tmp[i][j] = 0.0;\r
-\r
-                for (int k = 0; k < in.cols; k++)\r
-                {\r
-                    tmp[i][j] += (in.value[i][k] * this.value[k][j]);\r
-                }\r
-            }\r
-        }\r
-\r
-        return new Matrix(tmp, in.rows, this.cols);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param in DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public double[] vectorPostMultiply(double[] in)\r
-    {\r
-        double[] out = new double[in.length];\r
-\r
-        for (int i = 0; i < in.length; i++)\r
-        {\r
-            out[i] = 0.0;\r
-\r
-            for (int k = 0; k < in.length; k++)\r
-            {\r
-                out[i] += (value[i][k] * in[k]);\r
-            }\r
-        }\r
-\r
-        return out;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param in DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Matrix postMultiply(Matrix in)\r
-    {\r
-        double[][] out = new double[this.rows][in.cols];\r
-\r
-        for (int i = 0; i < this.rows; i++)\r
-        {\r
-            for (int j = 0; j < in.cols; j++)\r
-            {\r
-                out[i][j] = 0.0;\r
-\r
-                for (int k = 0; k < rows; k++)\r
-                {\r
-                    out[i][j] = out[i][j] + (value[i][k] * in.value[k][j]);\r
-                }\r
-            }\r
-        }\r
-\r
-        return new Matrix(out, this.cols, in.rows);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Matrix copy()\r
-    {\r
-        double[][] newmat = new double[rows][cols];\r
-\r
-        for (int i = 0; i < rows; i++)\r
-        {\r
-            for (int j = 0; j < cols; j++)\r
-            {\r
-                newmat[i][j] = value[i][j];\r
-            }\r
-        }\r
-\r
-        return new Matrix(newmat, rows, cols);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void tred()\r
-    {\r
-        int n = rows;\r
-        int l;\r
-        int k;\r
-        int j;\r
-        int i;\r
-\r
-        double scale;\r
-        double hh;\r
-        double h;\r
-        double g;\r
-        double f;\r
-\r
-        this.d = new double[rows];\r
-        this.e = new double[rows];\r
-\r
-        for (i = n; i >= 2; i--)\r
-        {\r
-            l = i - 1;\r
-            h = 0.0;\r
-            scale = 0.0;\r
-\r
-            if (l > 1)\r
-            {\r
-                for (k = 1; k <= l; k++)\r
-                {\r
-                    scale += Math.abs(value[i - 1][k - 1]);\r
-                }\r
-\r
-                if (scale == 0.0)\r
-                {\r
-                    e[i - 1] = value[i - 1][l - 1];\r
-                }\r
-                else\r
-                {\r
-                    for (k = 1; k <= l; k++)\r
-                    {\r
-                        value[i - 1][k - 1] /= scale;\r
-                        h += (value[i - 1][k - 1] * value[i - 1][k - 1]);\r
-                    }\r
-\r
-                    f = value[i - 1][l - 1];\r
-\r
-                    if (f > 0)\r
-                    {\r
-                        g = -1.0 * Math.sqrt(h);\r
-                    }\r
-                    else\r
-                    {\r
-                        g = Math.sqrt(h);\r
-                    }\r
-\r
-                    e[i - 1] = scale * g;\r
-                    h -= (f * g);\r
-                    value[i - 1][l - 1] = f - g;\r
-                    f = 0.0;\r
-\r
-                    for (j = 1; j <= l; j++)\r
-                    {\r
-                        value[j - 1][i - 1] = value[i - 1][j - 1] / h;\r
-                        g = 0.0;\r
-\r
-                        for (k = 1; k <= j; k++)\r
-                        {\r
-                            g += (value[j - 1][k - 1] * value[i - 1][k - 1]);\r
-                        }\r
-\r
-                        for (k = j + 1; k <= l; k++)\r
-                        {\r
-                            g += (value[k - 1][j - 1] * value[i - 1][k - 1]);\r
-                        }\r
-\r
-                        e[j - 1] = g / h;\r
-                        f += (e[j - 1] * value[i - 1][j - 1]);\r
-                    }\r
-\r
-                    hh = f / (h + h);\r
-\r
-                    for (j = 1; j <= l; j++)\r
-                    {\r
-                        f = value[i - 1][j - 1];\r
-                        g = e[j - 1] - (hh * f);\r
-                        e[j - 1] = g;\r
-\r
-                        for (k = 1; k <= j; k++)\r
-                        {\r
-                            value[j - 1][k - 1] -= ((f * e[k - 1]) +\r
-                            (g * value[i - 1][k - 1]));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-            else\r
-            {\r
-                e[i - 1] = value[i - 1][l - 1];\r
-            }\r
-\r
-            d[i - 1] = h;\r
-        }\r
-\r
-        d[0] = 0.0;\r
-        e[0] = 0.0;\r
-\r
-        for (i = 1; i <= n; i++)\r
-        {\r
-            l = i - 1;\r
-\r
-            if (d[i - 1] != 0.0)\r
-            {\r
-                for (j = 1; j <= l; j++)\r
-                {\r
-                    g = 0.0;\r
-\r
-                    for (k = 1; k <= l; k++)\r
-                    {\r
-                        g += (value[i - 1][k - 1] * value[k - 1][j - 1]);\r
-                    }\r
-\r
-                    for (k = 1; k <= l; k++)\r
-                    {\r
-                        value[k - 1][j - 1] -= (g * value[k - 1][i - 1]);\r
-                    }\r
-                }\r
-            }\r
-\r
-            d[i - 1] = value[i - 1][i - 1];\r
-            value[i - 1][i - 1] = 1.0;\r
-\r
-            for (j = 1; j <= l; j++)\r
-            {\r
-                value[j - 1][i - 1] = 0.0;\r
-                value[i - 1][j - 1] = 0.0;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void tqli()\r
-    {\r
-        int n = rows;\r
-\r
-        int m;\r
-        int l;\r
-        int iter;\r
-        int i;\r
-        int k;\r
-        double s;\r
-        double r;\r
-        double p;\r
-        ;\r
-\r
-        double g;\r
-        double f;\r
-        double dd;\r
-        double c;\r
-        double b;\r
-\r
-        for (i = 2; i <= n; i++)\r
-        {\r
-            e[i - 2] = e[i - 1];\r
-        }\r
-\r
-        e[n - 1] = 0.0;\r
-\r
-        for (l = 1; l <= n; l++)\r
-        {\r
-            iter = 0;\r
-\r
-            do\r
-            {\r
-                for (m = l; m <= (n - 1); m++)\r
-                {\r
-                    dd = Math.abs(d[m - 1]) + Math.abs(d[m]);\r
-\r
-                    if ((Math.abs(e[m - 1]) + dd) == dd)\r
-                    {\r
-                        break;\r
-                    }\r
-                }\r
-\r
-                if (m != l)\r
-                {\r
-                    iter++;\r
-\r
-                    if (iter == 30)\r
-                    {\r
-                        System.err.print("Too many iterations in tqli");\r
-                        System.exit(0); // JBPNote - should this really be here ???\r
-                    }\r
-                    else\r
-                    {\r
-                        //         System.out.println("Iteration " + iter);\r
-                    }\r
-\r
-                    g = (d[l] - d[l - 1]) / (2.0 * e[l - 1]);\r
-                    r = Math.sqrt((g * g) + 1.0);\r
-                    g = d[m - 1] - d[l - 1] + (e[l - 1] / (g + sign(r, g)));\r
-                    c = 1.0;\r
-                    s = c;\r
-                    p = 0.0;\r
-\r
-                    for (i = m - 1; i >= l; i--)\r
-                    {\r
-                        f = s * e[i - 1];\r
-                        b = c * e[i - 1];\r
-\r
-                        if (Math.abs(f) >= Math.abs(g))\r
-                        {\r
-                            c = g / f;\r
-                            r = Math.sqrt((c * c) + 1.0);\r
-                            e[i] = f * r;\r
-                            s = 1.0 / r;\r
-                            c *= s;\r
-                        }\r
-                        else\r
-                        {\r
-                            s = f / g;\r
-                            r = Math.sqrt((s * s) + 1.0);\r
-                            e[i] = g * r;\r
-                            c = 1.0 / r;\r
-                            s *= c;\r
-                        }\r
-\r
-                        g = d[i] - p;\r
-                        r = ((d[i - 1] - g) * s) + (2.0 * c * b);\r
-                        p = s * r;\r
-                        d[i] = g + p;\r
-                        g = (c * r) - b;\r
-\r
-                        for (k = 1; k <= n; k++)\r
-                        {\r
-                            f = value[k - 1][i];\r
-                            value[k - 1][i] = (s * value[k - 1][i - 1]) +\r
-                                (c * f);\r
-                            value[k - 1][i - 1] = (c * value[k - 1][i - 1]) -\r
-                                (s * f);\r
-                        }\r
-                    }\r
-\r
-                    d[l - 1] = d[l - 1] - p;\r
-                    e[l - 1] = g;\r
-                    e[m - 1] = 0.0;\r
-                }\r
-            }\r
-            while (m != l);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void tred2()\r
-    {\r
-        int n = rows;\r
-        int l;\r
-        int k;\r
-        int j;\r
-        int i;\r
-\r
-        double scale;\r
-        double hh;\r
-        double h;\r
-        double g;\r
-        double f;\r
-\r
-        this.d = new double[rows];\r
-        this.e = new double[rows];\r
-\r
-        for (i = n - 1; i >= 1; i--)\r
-        {\r
-            l = i - 1;\r
-            h = 0.0;\r
-            scale = 0.0;\r
-\r
-            if (l > 0)\r
-            {\r
-                for (k = 0; k < l; k++)\r
-                {\r
-                    scale += Math.abs(value[i][k]);\r
-                }\r
-\r
-                if (scale == 0.0)\r
-                {\r
-                    e[i] = value[i][l];\r
-                }\r
-                else\r
-                {\r
-                    for (k = 0; k < l; k++)\r
-                    {\r
-                        value[i][k] /= scale;\r
-                        h += (value[i][k] * value[i][k]);\r
-                    }\r
-\r
-                    f = value[i][l];\r
-\r
-                    if (f > 0)\r
-                    {\r
-                        g = -1.0 * Math.sqrt(h);\r
-                    }\r
-                    else\r
-                    {\r
-                        g = Math.sqrt(h);\r
-                    }\r
-\r
-                    e[i] = scale * g;\r
-                    h -= (f * g);\r
-                    value[i][l] = f - g;\r
-                    f = 0.0;\r
-\r
-                    for (j = 0; j < l; j++)\r
-                    {\r
-                        value[j][i] = value[i][j] / h;\r
-                        g = 0.0;\r
-\r
-                        for (k = 0; k < j; k++)\r
-                        {\r
-                            g += (value[j][k] * value[i][k]);\r
-                        }\r
-\r
-                        for (k = j; k < l; k++)\r
-                        {\r
-                            g += (value[k][j] * value[i][k]);\r
-                        }\r
-\r
-                        e[j] = g / h;\r
-                        f += (e[j] * value[i][j]);\r
-                    }\r
-\r
-                    hh = f / (h + h);\r
-\r
-                    for (j = 0; j < l; j++)\r
-                    {\r
-                        f = value[i][j];\r
-                        g = e[j] - (hh * f);\r
-                        e[j] = g;\r
-\r
-                        for (k = 0; k < j; k++)\r
-                        {\r
-                            value[j][k] -= ((f * e[k]) + (g * value[i][k]));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-            else\r
-            {\r
-                e[i] = value[i][l];\r
-            }\r
-\r
-            d[i] = h;\r
-        }\r
-\r
-        d[0] = 0.0;\r
-        e[0] = 0.0;\r
-\r
-        for (i = 0; i < n; i++)\r
-        {\r
-            l = i - 1;\r
-\r
-            if (d[i] != 0.0)\r
-            {\r
-                for (j = 0; j < l; j++)\r
-                {\r
-                    g = 0.0;\r
-\r
-                    for (k = 0; k < l; k++)\r
-                    {\r
-                        g += (value[i][k] * value[k][j]);\r
-                    }\r
-\r
-                    for (k = 0; k < l; k++)\r
-                    {\r
-                        value[k][j] -= (g * value[k][i]);\r
-                    }\r
-                }\r
-            }\r
-\r
-            d[i] = value[i][i];\r
-            value[i][i] = 1.0;\r
-\r
-            for (j = 0; j < l; j++)\r
-            {\r
-                value[j][i] = 0.0;\r
-                value[i][j] = 0.0;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void tqli2()\r
-    {\r
-        int n = rows;\r
-\r
-        int m;\r
-        int l;\r
-        int iter;\r
-        int i;\r
-        int k;\r
-        double s;\r
-        double r;\r
-        double p;\r
-        ;\r
-\r
-        double g;\r
-        double f;\r
-        double dd;\r
-        double c;\r
-        double b;\r
-\r
-        for (i = 2; i <= n; i++)\r
-        {\r
-            e[i - 2] = e[i - 1];\r
-        }\r
-\r
-        e[n - 1] = 0.0;\r
-\r
-        for (l = 1; l <= n; l++)\r
-        {\r
-            iter = 0;\r
-\r
-            do\r
-            {\r
-                for (m = l; m <= (n - 1); m++)\r
-                {\r
-                    dd = Math.abs(d[m - 1]) + Math.abs(d[m]);\r
-\r
-                    if ((Math.abs(e[m - 1]) + dd) == dd)\r
-                    {\r
-                        break;\r
-                    }\r
-                }\r
-\r
-                if (m != l)\r
-                {\r
-                    iter++;\r
-\r
-                    if (iter == 30)\r
-                    {\r
-                        System.err.print("Too many iterations in tqli");\r
-                        System.exit(0); // JBPNote - same as above - not a graceful exit!\r
-                    }\r
-                    else\r
-                    {\r
-                        //         System.out.println("Iteration " + iter);\r
-                    }\r
-\r
-                    g = (d[l] - d[l - 1]) / (2.0 * e[l - 1]);\r
-                    r = Math.sqrt((g * g) + 1.0);\r
-                    g = d[m - 1] - d[l - 1] + (e[l - 1] / (g + sign(r, g)));\r
-                    c = 1.0;\r
-                    s = c;\r
-                    p = 0.0;\r
-\r
-                    for (i = m - 1; i >= l; i--)\r
-                    {\r
-                        f = s * e[i - 1];\r
-                        b = c * e[i - 1];\r
-\r
-                        if (Math.abs(f) >= Math.abs(g))\r
-                        {\r
-                            c = g / f;\r
-                            r = Math.sqrt((c * c) + 1.0);\r
-                            e[i] = f * r;\r
-                            s = 1.0 / r;\r
-                            c *= s;\r
-                        }\r
-                        else\r
-                        {\r
-                            s = f / g;\r
-                            r = Math.sqrt((s * s) + 1.0);\r
-                            e[i] = g * r;\r
-                            c = 1.0 / r;\r
-                            s *= c;\r
-                        }\r
-\r
-                        g = d[i] - p;\r
-                        r = ((d[i - 1] - g) * s) + (2.0 * c * b);\r
-                        p = s * r;\r
-                        d[i] = g + p;\r
-                        g = (c * r) - b;\r
-\r
-                        for (k = 1; k <= n; k++)\r
-                        {\r
-                            f = value[k - 1][i];\r
-                            value[k - 1][i] = (s * value[k - 1][i - 1]) +\r
-                                (c * f);\r
-                            value[k - 1][i - 1] = (c * value[k - 1][i - 1]) -\r
-                                (s * f);\r
-                        }\r
-                    }\r
-\r
-                    d[l - 1] = d[l - 1] - p;\r
-                    e[l - 1] = g;\r
-                    e[m - 1] = 0.0;\r
-                }\r
-            }\r
-            while (m != l);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param a DOCUMENT ME!\r
-     * @param b DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public double sign(double a, double b)\r
-    {\r
-        if (b < 0)\r
-        {\r
-            return -Math.abs(a);\r
-        }\r
-        else\r
-        {\r
-            return Math.abs(a);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public double[] getColumn(int n)\r
-    {\r
-        double[] out = new double[rows];\r
-\r
-        for (int i = 0; i < rows; i++)\r
-        {\r
-            out[i] = value[i][n];\r
-        }\r
-\r
-        return out;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ps DOCUMENT ME!\r
-     */\r
-    public void printD(PrintStream ps)\r
-    {\r
-        for (int j = 0; j < rows; j++)\r
-        {\r
-            Format.print(ps, "%15.4e", d[j]);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ps DOCUMENT ME!\r
-     */\r
-    public void printE(PrintStream ps)\r
-    {\r
-        for (int j = 0; j < rows; j++)\r
-        {\r
-            Format.print(ps, "%15.4e", e[j]);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param args DOCUMENT ME!\r
-     */\r
-    public static void main(String[] args)\r
-    {\r
-        int n = Integer.parseInt(args[0]);\r
-        double[][] in = new double[n][n];\r
-\r
-        for (int i = 0; i < n; i++)\r
-        {\r
-            for (int j = 0; j < n; j++)\r
-            {\r
-                in[i][j] = (double) Math.random();\r
-            }\r
-        }\r
-\r
-        Matrix origmat = new Matrix(in, n, n);\r
-\r
-        //    System.out.println(" --- Original matrix ---- ");\r
-        ///    origmat.print(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- transpose matrix ---- ");\r
-        Matrix trans = origmat.transpose();\r
-\r
-        //trans.print(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- OrigT * Orig ---- ");\r
-        Matrix symm = trans.postMultiply(origmat);\r
-\r
-        //symm.print(System.out);\r
-        //System.out.println();\r
-        // Copy the symmetric matrix for later\r
-        //Matrix origsymm = symm.copy();\r
-\r
-        // This produces the tridiagonal transformation matrix\r
-        //long tstart = System.currentTimeMillis();\r
-        symm.tred();\r
-\r
-        //long tend = System.currentTimeMillis();\r
-\r
-        //System.out.println("Time take for tred = " + (tend-tstart) + "ms");\r
-        //System.out.println(" ---Tridiag transform matrix ---");\r
-        //symm.print(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- D vector ---");\r
-        //symm.printD(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- E vector ---");\r
-        //symm.printE(System.out);\r
-        //System.out.println();\r
-        // Now produce the diagonalization matrix\r
-        //tstart = System.currentTimeMillis();\r
-        symm.tqli();\r
-        //tend = System.currentTimeMillis();\r
-\r
-        //System.out.println("Time take for tqli = " + (tend-tstart) + " ms");\r
-        //System.out.println(" --- New diagonalization matrix ---");\r
-        //symm.print(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- D vector ---");\r
-        //symm.printD(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- E vector ---");\r
-        //symm.printE(System.out);\r
-        //System.out.println();\r
-        //System.out.println(" --- First eigenvector --- ");\r
-        //double[] eigenv = symm.getColumn(0);\r
-        //for (int i=0; i < eigenv.length;i++) {\r
-        //  Format.print(System.out,"%15.4f",eigenv[i]);\r
-        // }\r
-        //System.out.println();\r
-        //double[] neigenv = origsymm.vectorPostMultiply(eigenv);\r
-        //for (int i=0; i < neigenv.length;i++) {\r
-        //  Format.print(System.out,"%15.4f",neigenv[i]/symm.d[0]);\r
-        //}\r
-        //System.out.println();\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.math;
+
+import jalview.util.*;
+
+import java.io.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Matrix
+{
+    /**
+     * SMJSPUBLIC
+     */
+    public double[][] value;
+
+    /** DOCUMENT ME!! */
+    public int rows;
+
+    /** DOCUMENT ME!! */
+    public int cols;
+
+    /** DOCUMENT ME!! */
+    public double[] d; // Diagonal
+
+    /** DOCUMENT ME!! */
+    public double[] e; // off diagonal
+
+    /**
+     * Creates a new Matrix object.
+     *
+     * @param value DOCUMENT ME!
+     * @param rows DOCUMENT ME!
+     * @param cols DOCUMENT ME!
+     */
+    public Matrix(double[][] value, int rows, int cols)
+    {
+        this.rows = rows;
+        this.cols = cols;
+        this.value = value;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Matrix transpose()
+    {
+        double[][] out = new double[cols][rows];
+
+        for (int i = 0; i < cols; i++)
+        {
+            for (int j = 0; j < rows; j++)
+            {
+                out[i][j] = value[j][i];
+            }
+        }
+
+        return new Matrix(out, cols, rows);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ps DOCUMENT ME!
+     */
+    public void print(PrintStream ps)
+    {
+        for (int i = 0; i < rows; i++)
+        {
+            for (int j = 0; j < cols; j++)
+            {
+                Format.print(ps, "%8.2f", value[i][j]);
+            }
+
+            ps.println();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param in DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Matrix preMultiply(Matrix in)
+    {
+        double[][] tmp = new double[in.rows][this.cols];
+
+        for (int i = 0; i < in.rows; i++)
+        {
+            for (int j = 0; j < this.cols; j++)
+            {
+                tmp[i][j] = 0.0;
+
+                for (int k = 0; k < in.cols; k++)
+                {
+                    tmp[i][j] += (in.value[i][k] * this.value[k][j]);
+                }
+            }
+        }
+
+        return new Matrix(tmp, in.rows, this.cols);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param in DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public double[] vectorPostMultiply(double[] in)
+    {
+        double[] out = new double[in.length];
+
+        for (int i = 0; i < in.length; i++)
+        {
+            out[i] = 0.0;
+
+            for (int k = 0; k < in.length; k++)
+            {
+                out[i] += (value[i][k] * in[k]);
+            }
+        }
+
+        return out;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param in DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Matrix postMultiply(Matrix in)
+    {
+        double[][] out = new double[this.rows][in.cols];
+
+        for (int i = 0; i < this.rows; i++)
+        {
+            for (int j = 0; j < in.cols; j++)
+            {
+                out[i][j] = 0.0;
+
+                for (int k = 0; k < rows; k++)
+                {
+                    out[i][j] = out[i][j] + (value[i][k] * in.value[k][j]);
+                }
+            }
+        }
+
+        return new Matrix(out, this.cols, in.rows);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Matrix copy()
+    {
+        double[][] newmat = new double[rows][cols];
+
+        for (int i = 0; i < rows; i++)
+        {
+            for (int j = 0; j < cols; j++)
+            {
+                newmat[i][j] = value[i][j];
+            }
+        }
+
+        return new Matrix(newmat, rows, cols);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void tred()
+    {
+        int n = rows;
+        int l;
+        int k;
+        int j;
+        int i;
+
+        double scale;
+        double hh;
+        double h;
+        double g;
+        double f;
+
+        this.d = new double[rows];
+        this.e = new double[rows];
+
+        for (i = n; i >= 2; i--)
+        {
+            l = i - 1;
+            h = 0.0;
+            scale = 0.0;
+
+            if (l > 1)
+            {
+                for (k = 1; k <= l; k++)
+                {
+                    scale += Math.abs(value[i - 1][k - 1]);
+                }
+
+                if (scale == 0.0)
+                {
+                    e[i - 1] = value[i - 1][l - 1];
+                }
+                else
+                {
+                    for (k = 1; k <= l; k++)
+                    {
+                        value[i - 1][k - 1] /= scale;
+                        h += (value[i - 1][k - 1] * value[i - 1][k - 1]);
+                    }
+
+                    f = value[i - 1][l - 1];
+
+                    if (f > 0)
+                    {
+                        g = -1.0 * Math.sqrt(h);
+                    }
+                    else
+                    {
+                        g = Math.sqrt(h);
+                    }
+
+                    e[i - 1] = scale * g;
+                    h -= (f * g);
+                    value[i - 1][l - 1] = f - g;
+                    f = 0.0;
+
+                    for (j = 1; j <= l; j++)
+                    {
+                        value[j - 1][i - 1] = value[i - 1][j - 1] / h;
+                        g = 0.0;
+
+                        for (k = 1; k <= j; k++)
+                        {
+                            g += (value[j - 1][k - 1] * value[i - 1][k - 1]);
+                        }
+
+                        for (k = j + 1; k <= l; k++)
+                        {
+                            g += (value[k - 1][j - 1] * value[i - 1][k - 1]);
+                        }
+
+                        e[j - 1] = g / h;
+                        f += (e[j - 1] * value[i - 1][j - 1]);
+                    }
+
+                    hh = f / (h + h);
+
+                    for (j = 1; j <= l; j++)
+                    {
+                        f = value[i - 1][j - 1];
+                        g = e[j - 1] - (hh * f);
+                        e[j - 1] = g;
+
+                        for (k = 1; k <= j; k++)
+                        {
+                            value[j - 1][k - 1] -= ((f * e[k - 1]) +
+                            (g * value[i - 1][k - 1]));
+                        }
+                    }
+                }
+            }
+            else
+            {
+                e[i - 1] = value[i - 1][l - 1];
+            }
+
+            d[i - 1] = h;
+        }
+
+        d[0] = 0.0;
+        e[0] = 0.0;
+
+        for (i = 1; i <= n; i++)
+        {
+            l = i - 1;
+
+            if (d[i - 1] != 0.0)
+            {
+                for (j = 1; j <= l; j++)
+                {
+                    g = 0.0;
+
+                    for (k = 1; k <= l; k++)
+                    {
+                        g += (value[i - 1][k - 1] * value[k - 1][j - 1]);
+                    }
+
+                    for (k = 1; k <= l; k++)
+                    {
+                        value[k - 1][j - 1] -= (g * value[k - 1][i - 1]);
+                    }
+                }
+            }
+
+            d[i - 1] = value[i - 1][i - 1];
+            value[i - 1][i - 1] = 1.0;
+
+            for (j = 1; j <= l; j++)
+            {
+                value[j - 1][i - 1] = 0.0;
+                value[i - 1][j - 1] = 0.0;
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void tqli()
+    {
+        int n = rows;
+
+        int m;
+        int l;
+        int iter;
+        int i;
+        int k;
+        double s;
+        double r;
+        double p;
+        ;
+
+        double g;
+        double f;
+        double dd;
+        double c;
+        double b;
+
+        for (i = 2; i <= n; i++)
+        {
+            e[i - 2] = e[i - 1];
+        }
+
+        e[n - 1] = 0.0;
+
+        for (l = 1; l <= n; l++)
+        {
+            iter = 0;
+
+            do
+            {
+                for (m = l; m <= (n - 1); m++)
+                {
+                    dd = Math.abs(d[m - 1]) + Math.abs(d[m]);
+
+                    if ((Math.abs(e[m - 1]) + dd) == dd)
+                    {
+                        break;
+                    }
+                }
+
+                if (m != l)
+                {
+                    iter++;
+
+                    if (iter == 30)
+                    {
+                        System.err.print("Too many iterations in tqli");
+                        System.exit(0); // JBPNote - should this really be here ???
+                    }
+                    else
+                    {
+                        //         System.out.println("Iteration " + iter);
+                    }
+
+                    g = (d[l] - d[l - 1]) / (2.0 * e[l - 1]);
+                    r = Math.sqrt((g * g) + 1.0);
+                    g = d[m - 1] - d[l - 1] + (e[l - 1] / (g + sign(r, g)));
+                    c = 1.0;
+                    s = c;
+                    p = 0.0;
+
+                    for (i = m - 1; i >= l; i--)
+                    {
+                        f = s * e[i - 1];
+                        b = c * e[i - 1];
+
+                        if (Math.abs(f) >= Math.abs(g))
+                        {
+                            c = g / f;
+                            r = Math.sqrt((c * c) + 1.0);
+                            e[i] = f * r;
+                            s = 1.0 / r;
+                            c *= s;
+                        }
+                        else
+                        {
+                            s = f / g;
+                            r = Math.sqrt((s * s) + 1.0);
+                            e[i] = g * r;
+                            c = 1.0 / r;
+                            s *= c;
+                        }
+
+                        g = d[i] - p;
+                        r = ((d[i - 1] - g) * s) + (2.0 * c * b);
+                        p = s * r;
+                        d[i] = g + p;
+                        g = (c * r) - b;
+
+                        for (k = 1; k <= n; k++)
+                        {
+                            f = value[k - 1][i];
+                            value[k - 1][i] = (s * value[k - 1][i - 1]) +
+                                (c * f);
+                            value[k - 1][i - 1] = (c * value[k - 1][i - 1]) -
+                                (s * f);
+                        }
+                    }
+
+                    d[l - 1] = d[l - 1] - p;
+                    e[l - 1] = g;
+                    e[m - 1] = 0.0;
+                }
+            }
+            while (m != l);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void tred2()
+    {
+        int n = rows;
+        int l;
+        int k;
+        int j;
+        int i;
+
+        double scale;
+        double hh;
+        double h;
+        double g;
+        double f;
+
+        this.d = new double[rows];
+        this.e = new double[rows];
+
+        for (i = n - 1; i >= 1; i--)
+        {
+            l = i - 1;
+            h = 0.0;
+            scale = 0.0;
+
+            if (l > 0)
+            {
+                for (k = 0; k < l; k++)
+                {
+                    scale += Math.abs(value[i][k]);
+                }
+
+                if (scale == 0.0)
+                {
+                    e[i] = value[i][l];
+                }
+                else
+                {
+                    for (k = 0; k < l; k++)
+                    {
+                        value[i][k] /= scale;
+                        h += (value[i][k] * value[i][k]);
+                    }
+
+                    f = value[i][l];
+
+                    if (f > 0)
+                    {
+                        g = -1.0 * Math.sqrt(h);
+                    }
+                    else
+                    {
+                        g = Math.sqrt(h);
+                    }
+
+                    e[i] = scale * g;
+                    h -= (f * g);
+                    value[i][l] = f - g;
+                    f = 0.0;
+
+                    for (j = 0; j < l; j++)
+                    {
+                        value[j][i] = value[i][j] / h;
+                        g = 0.0;
+
+                        for (k = 0; k < j; k++)
+                        {
+                            g += (value[j][k] * value[i][k]);
+                        }
+
+                        for (k = j; k < l; k++)
+                        {
+                            g += (value[k][j] * value[i][k]);
+                        }
+
+                        e[j] = g / h;
+                        f += (e[j] * value[i][j]);
+                    }
+
+                    hh = f / (h + h);
+
+                    for (j = 0; j < l; j++)
+                    {
+                        f = value[i][j];
+                        g = e[j] - (hh * f);
+                        e[j] = g;
+
+                        for (k = 0; k < j; k++)
+                        {
+                            value[j][k] -= ((f * e[k]) + (g * value[i][k]));
+                        }
+                    }
+                }
+            }
+            else
+            {
+                e[i] = value[i][l];
+            }
+
+            d[i] = h;
+        }
+
+        d[0] = 0.0;
+        e[0] = 0.0;
+
+        for (i = 0; i < n; i++)
+        {
+            l = i - 1;
+
+            if (d[i] != 0.0)
+            {
+                for (j = 0; j < l; j++)
+                {
+                    g = 0.0;
+
+                    for (k = 0; k < l; k++)
+                    {
+                        g += (value[i][k] * value[k][j]);
+                    }
+
+                    for (k = 0; k < l; k++)
+                    {
+                        value[k][j] -= (g * value[k][i]);
+                    }
+                }
+            }
+
+            d[i] = value[i][i];
+            value[i][i] = 1.0;
+
+            for (j = 0; j < l; j++)
+            {
+                value[j][i] = 0.0;
+                value[i][j] = 0.0;
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void tqli2()
+    {
+        int n = rows;
+
+        int m;
+        int l;
+        int iter;
+        int i;
+        int k;
+        double s;
+        double r;
+        double p;
+        ;
+
+        double g;
+        double f;
+        double dd;
+        double c;
+        double b;
+
+        for (i = 2; i <= n; i++)
+        {
+            e[i - 2] = e[i - 1];
+        }
+
+        e[n - 1] = 0.0;
+
+        for (l = 1; l <= n; l++)
+        {
+            iter = 0;
+
+            do
+            {
+                for (m = l; m <= (n - 1); m++)
+                {
+                    dd = Math.abs(d[m - 1]) + Math.abs(d[m]);
+
+                    if ((Math.abs(e[m - 1]) + dd) == dd)
+                    {
+                        break;
+                    }
+                }
+
+                if (m != l)
+                {
+                    iter++;
+
+                    if (iter == 30)
+                    {
+                        System.err.print("Too many iterations in tqli");
+                        System.exit(0); // JBPNote - same as above - not a graceful exit!
+                    }
+                    else
+                    {
+                        //         System.out.println("Iteration " + iter);
+                    }
+
+                    g = (d[l] - d[l - 1]) / (2.0 * e[l - 1]);
+                    r = Math.sqrt((g * g) + 1.0);
+                    g = d[m - 1] - d[l - 1] + (e[l - 1] / (g + sign(r, g)));
+                    c = 1.0;
+                    s = c;
+                    p = 0.0;
+
+                    for (i = m - 1; i >= l; i--)
+                    {
+                        f = s * e[i - 1];
+                        b = c * e[i - 1];
+
+                        if (Math.abs(f) >= Math.abs(g))
+                        {
+                            c = g / f;
+                            r = Math.sqrt((c * c) + 1.0);
+                            e[i] = f * r;
+                            s = 1.0 / r;
+                            c *= s;
+                        }
+                        else
+                        {
+                            s = f / g;
+                            r = Math.sqrt((s * s) + 1.0);
+                            e[i] = g * r;
+                            c = 1.0 / r;
+                            s *= c;
+                        }
+
+                        g = d[i] - p;
+                        r = ((d[i - 1] - g) * s) + (2.0 * c * b);
+                        p = s * r;
+                        d[i] = g + p;
+                        g = (c * r) - b;
+
+                        for (k = 1; k <= n; k++)
+                        {
+                            f = value[k - 1][i];
+                            value[k - 1][i] = (s * value[k - 1][i - 1]) +
+                                (c * f);
+                            value[k - 1][i - 1] = (c * value[k - 1][i - 1]) -
+                                (s * f);
+                        }
+                    }
+
+                    d[l - 1] = d[l - 1] - p;
+                    e[l - 1] = g;
+                    e[m - 1] = 0.0;
+                }
+            }
+            while (m != l);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param a DOCUMENT ME!
+     * @param b DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public double sign(double a, double b)
+    {
+        if (b < 0)
+        {
+            return -Math.abs(a);
+        }
+        else
+        {
+            return Math.abs(a);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public double[] getColumn(int n)
+    {
+        double[] out = new double[rows];
+
+        for (int i = 0; i < rows; i++)
+        {
+            out[i] = value[i][n];
+        }
+
+        return out;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ps DOCUMENT ME!
+     */
+    public void printD(PrintStream ps)
+    {
+        for (int j = 0; j < rows; j++)
+        {
+            Format.print(ps, "%15.4e", d[j]);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ps DOCUMENT ME!
+     */
+    public void printE(PrintStream ps)
+    {
+        for (int j = 0; j < rows; j++)
+        {
+            Format.print(ps, "%15.4e", e[j]);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param args DOCUMENT ME!
+     */
+    public static void main(String[] args)
+    {
+        int n = Integer.parseInt(args[0]);
+        double[][] in = new double[n][n];
+
+        for (int i = 0; i < n; i++)
+        {
+            for (int j = 0; j < n; j++)
+            {
+                in[i][j] = (double) Math.random();
+            }
+        }
+
+        Matrix origmat = new Matrix(in, n, n);
+
+        //    System.out.println(" --- Original matrix ---- ");
+        ///    origmat.print(System.out);
+        //System.out.println();
+        //System.out.println(" --- transpose matrix ---- ");
+        Matrix trans = origmat.transpose();
+
+        //trans.print(System.out);
+        //System.out.println();
+        //System.out.println(" --- OrigT * Orig ---- ");
+        Matrix symm = trans.postMultiply(origmat);
+
+        //symm.print(System.out);
+        //System.out.println();
+        // Copy the symmetric matrix for later
+        //Matrix origsymm = symm.copy();
+
+        // This produces the tridiagonal transformation matrix
+        //long tstart = System.currentTimeMillis();
+        symm.tred();
+
+        //long tend = System.currentTimeMillis();
+
+        //System.out.println("Time take for tred = " + (tend-tstart) + "ms");
+        //System.out.println(" ---Tridiag transform matrix ---");
+        //symm.print(System.out);
+        //System.out.println();
+        //System.out.println(" --- D vector ---");
+        //symm.printD(System.out);
+        //System.out.println();
+        //System.out.println(" --- E vector ---");
+        //symm.printE(System.out);
+        //System.out.println();
+        // Now produce the diagonalization matrix
+        //tstart = System.currentTimeMillis();
+        symm.tqli();
+        //tend = System.currentTimeMillis();
+
+        //System.out.println("Time take for tqli = " + (tend-tstart) + " ms");
+        //System.out.println(" --- New diagonalization matrix ---");
+        //symm.print(System.out);
+        //System.out.println();
+        //System.out.println(" --- D vector ---");
+        //symm.printD(System.out);
+        //System.out.println();
+        //System.out.println(" --- E vector ---");
+        //symm.printE(System.out);
+        //System.out.println();
+        //System.out.println(" --- First eigenvector --- ");
+        //double[] eigenv = symm.getColumn(0);
+        //for (int i=0; i < eigenv.length;i++) {
+        //  Format.print(System.out,"%15.4f",eigenv[i]);
+        // }
+        //System.out.println();
+        //double[] neigenv = origsymm.vectorPostMultiply(eigenv);
+        //for (int i=0; i < neigenv.length;i++) {
+        //  Format.print(System.out,"%15.4f",neigenv[i]/symm.d[0]);
+        //}
+        //System.out.println();
+    }
+}
index 2385288..86e1a2c 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.math;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class RotatableMatrix\r
-{\r
-    float[][] matrix;\r
-    float[] temp;\r
-    float[][] rot;\r
-\r
-    /**\r
-     * Creates a new RotatableMatrix object.\r
-     *\r
-     * @param rows DOCUMENT ME!\r
-     * @param cols DOCUMENT ME!\r
-     */\r
-    public RotatableMatrix(int rows, int cols)\r
-    {\r
-        matrix = new float[rows][cols];\r
-\r
-        temp = new float[3];\r
-\r
-        rot = new float[3][3];\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param i DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     * @param value DOCUMENT ME!\r
-     */\r
-    public void addElement(int i, int j, float value)\r
-    {\r
-        matrix[i][j] = value;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void print()\r
-    {\r
-        System.out.println(matrix[0][0] + " " + matrix[0][1] + " " +\r
-            matrix[0][2]);\r
-\r
-        System.out.println(matrix[1][0] + " " + matrix[1][1] + " " +\r
-            matrix[1][2]);\r
-\r
-        System.out.println(matrix[2][0] + " " + matrix[2][1] + " " +\r
-            matrix[2][2]);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param degrees DOCUMENT ME!\r
-     * @param axis DOCUMENT ME!\r
-     */\r
-    public void rotate(float degrees, char axis)\r
-    {\r
-        float costheta = (float) Math.cos((degrees * Math.PI) / (float) 180.0);\r
-\r
-        float sintheta = (float) Math.sin((degrees * Math.PI) / (float) 180.0);\r
-\r
-        if (axis == 'z')\r
-        {\r
-            rot[0][0] = (float) costheta;\r
-\r
-            rot[0][1] = (float) -sintheta;\r
-\r
-            rot[0][2] = (float) 0.0;\r
-\r
-            rot[1][0] = (float) sintheta;\r
-\r
-            rot[1][1] = (float) costheta;\r
-\r
-            rot[1][2] = (float) 0.0;\r
-\r
-            rot[2][0] = (float) 0.0;\r
-\r
-            rot[2][1] = (float) 0.0;\r
-\r
-            rot[2][2] = (float) 1.0;\r
-\r
-            preMultiply(rot);\r
-        }\r
-\r
-        if (axis == 'x')\r
-        {\r
-            rot[0][0] = (float) 1.0;\r
-\r
-            rot[0][1] = (float) 0.0;\r
-\r
-            rot[0][2] = (float) 0.0;\r
-\r
-            rot[1][0] = (float) 0.0;\r
-\r
-            rot[1][1] = (float) costheta;\r
-\r
-            rot[1][2] = (float) sintheta;\r
-\r
-            rot[2][0] = (float) 0.0;\r
-\r
-            rot[2][1] = (float) -sintheta;\r
-\r
-            rot[2][2] = (float) costheta;\r
-\r
-            preMultiply(rot);\r
-        }\r
-\r
-        if (axis == 'y')\r
-        {\r
-            rot[0][0] = (float) costheta;\r
-\r
-            rot[0][1] = (float) 0.0;\r
-\r
-            rot[0][2] = (float) -sintheta;\r
-\r
-            rot[1][0] = (float) 0.0;\r
-\r
-            rot[1][1] = (float) 1.0;\r
-\r
-            rot[1][2] = (float) 0.0;\r
-\r
-            rot[2][0] = (float) sintheta;\r
-\r
-            rot[2][1] = (float) 0.0;\r
-\r
-            rot[2][2] = (float) costheta;\r
-\r
-            preMultiply(rot);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param vect DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public float[] vectorMultiply(float[] vect)\r
-    {\r
-        temp[0] = vect[0];\r
-\r
-        temp[1] = vect[1];\r
-\r
-        temp[2] = vect[2];\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            temp[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1]) +\r
-                (matrix[i][2] * vect[2]);\r
-        }\r
-\r
-        vect[0] = temp[0];\r
-\r
-        vect[1] = temp[1];\r
-\r
-        vect[2] = temp[2];\r
-\r
-        return vect;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param mat DOCUMENT ME!\r
-     */\r
-    public void preMultiply(float[][] mat)\r
-    {\r
-        float[][] tmp = new float[3][3];\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                tmp[i][j] = (mat[i][0] * matrix[0][j]) +\r
-                    (mat[i][1] * matrix[1][j]) + (mat[i][2] * matrix[2][j]);\r
-            }\r
-        }\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                matrix[i][j] = tmp[i][j];\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param mat DOCUMENT ME!\r
-     */\r
-    public void postMultiply(float[][] mat)\r
-    {\r
-        float[][] tmp = new float[3][3];\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                tmp[i][j] = (matrix[i][0] * mat[0][j]) +\r
-                    (matrix[i][1] * mat[1][j]) + (matrix[i][2] * mat[2][j]);\r
-            }\r
-        }\r
-\r
-        for (int i = 0; i < 3; i++)\r
-        {\r
-            for (int j = 0; j < 3; j++)\r
-            {\r
-                matrix[i][j] = tmp[i][j];\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param args DOCUMENT ME!\r
-     */\r
-    public static void main(String[] args)\r
-    {\r
-        RotatableMatrix m = new RotatableMatrix(3, 3);\r
-\r
-        m.addElement(0, 0, 1);\r
-\r
-        m.addElement(0, 1, 0);\r
-\r
-        m.addElement(0, 2, 0);\r
-\r
-        m.addElement(1, 0, 0);\r
-\r
-        m.addElement(1, 1, 2);\r
-\r
-        m.addElement(1, 2, 0);\r
-\r
-        m.addElement(2, 0, 0);\r
-\r
-        m.addElement(2, 1, 0);\r
-\r
-        m.addElement(2, 2, 1);\r
-\r
-        m.print();\r
-\r
-        RotatableMatrix n = new RotatableMatrix(3, 3);\r
-\r
-        n.addElement(0, 0, 2);\r
-\r
-        n.addElement(0, 1, 1);\r
-\r
-        n.addElement(0, 2, 1);\r
-\r
-        n.addElement(1, 0, 2);\r
-\r
-        n.addElement(1, 1, 1);\r
-\r
-        n.addElement(1, 2, 1);\r
-\r
-        n.addElement(2, 0, 2);\r
-\r
-        n.addElement(2, 1, 1);\r
-\r
-        n.addElement(2, 2, 1);\r
-\r
-        n.print();\r
-\r
-        //m.postMultiply(n.matrix);\r
-        //m.print();\r
-        //     m.rotate(45,'z',new RotatableMatrix(3,3));\r
-        float[] vect = new float[3];\r
-\r
-        vect[0] = 2;\r
-\r
-        vect[1] = 4;\r
-\r
-        vect[2] = 6;\r
-\r
-        vect = m.vectorMultiply(vect);\r
-\r
-        System.out.println(vect[0] + " " + vect[1] + " " + vect[2]);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     */\r
-    public void setIdentity()\r
-    {\r
-        matrix[0][0] = (float) 1.0;\r
-\r
-        matrix[1][1] = (float) 1.0;\r
-\r
-        matrix[2][2] = (float) 1.0;\r
-\r
-        matrix[0][1] = (float) 0.0;\r
-\r
-        matrix[0][2] = (float) 0.0;\r
-\r
-        matrix[1][0] = (float) 0.0;\r
-\r
-        matrix[1][2] = (float) 0.0;\r
-\r
-        matrix[2][0] = (float) 0.0;\r
-\r
-        matrix[2][1] = (float) 0.0;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.math;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class RotatableMatrix
+{
+    float[][] matrix;
+    float[] temp;
+    float[][] rot;
+
+    /**
+     * Creates a new RotatableMatrix object.
+     *
+     * @param rows DOCUMENT ME!
+     * @param cols DOCUMENT ME!
+     */
+    public RotatableMatrix(int rows, int cols)
+    {
+        matrix = new float[rows][cols];
+
+        temp = new float[3];
+
+        rot = new float[3][3];
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     * @param value DOCUMENT ME!
+     */
+    public void addElement(int i, int j, float value)
+    {
+        matrix[i][j] = value;
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void print()
+    {
+        System.out.println(matrix[0][0] + " " + matrix[0][1] + " " +
+            matrix[0][2]);
+
+        System.out.println(matrix[1][0] + " " + matrix[1][1] + " " +
+            matrix[1][2]);
+
+        System.out.println(matrix[2][0] + " " + matrix[2][1] + " " +
+            matrix[2][2]);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param degrees DOCUMENT ME!
+     * @param axis DOCUMENT ME!
+     */
+    public void rotate(float degrees, char axis)
+    {
+        float costheta = (float) Math.cos((degrees * Math.PI) / (float) 180.0);
+
+        float sintheta = (float) Math.sin((degrees * Math.PI) / (float) 180.0);
+
+        if (axis == 'z')
+        {
+            rot[0][0] = (float) costheta;
+
+            rot[0][1] = (float) -sintheta;
+
+            rot[0][2] = (float) 0.0;
+
+            rot[1][0] = (float) sintheta;
+
+            rot[1][1] = (float) costheta;
+
+            rot[1][2] = (float) 0.0;
+
+            rot[2][0] = (float) 0.0;
+
+            rot[2][1] = (float) 0.0;
+
+            rot[2][2] = (float) 1.0;
+
+            preMultiply(rot);
+        }
+
+        if (axis == 'x')
+        {
+            rot[0][0] = (float) 1.0;
+
+            rot[0][1] = (float) 0.0;
+
+            rot[0][2] = (float) 0.0;
+
+            rot[1][0] = (float) 0.0;
+
+            rot[1][1] = (float) costheta;
+
+            rot[1][2] = (float) sintheta;
+
+            rot[2][0] = (float) 0.0;
+
+            rot[2][1] = (float) -sintheta;
+
+            rot[2][2] = (float) costheta;
+
+            preMultiply(rot);
+        }
+
+        if (axis == 'y')
+        {
+            rot[0][0] = (float) costheta;
+
+            rot[0][1] = (float) 0.0;
+
+            rot[0][2] = (float) -sintheta;
+
+            rot[1][0] = (float) 0.0;
+
+            rot[1][1] = (float) 1.0;
+
+            rot[1][2] = (float) 0.0;
+
+            rot[2][0] = (float) sintheta;
+
+            rot[2][1] = (float) 0.0;
+
+            rot[2][2] = (float) costheta;
+
+            preMultiply(rot);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param vect DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float[] vectorMultiply(float[] vect)
+    {
+        temp[0] = vect[0];
+
+        temp[1] = vect[1];
+
+        temp[2] = vect[2];
+
+        for (int i = 0; i < 3; i++)
+        {
+            temp[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1]) +
+                (matrix[i][2] * vect[2]);
+        }
+
+        vect[0] = temp[0];
+
+        vect[1] = temp[1];
+
+        vect[2] = temp[2];
+
+        return vect;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param mat DOCUMENT ME!
+     */
+    public void preMultiply(float[][] mat)
+    {
+        float[][] tmp = new float[3][3];
+
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {
+                tmp[i][j] = (mat[i][0] * matrix[0][j]) +
+                    (mat[i][1] * matrix[1][j]) + (mat[i][2] * matrix[2][j]);
+            }
+        }
+
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {
+                matrix[i][j] = tmp[i][j];
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param mat DOCUMENT ME!
+     */
+    public void postMultiply(float[][] mat)
+    {
+        float[][] tmp = new float[3][3];
+
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {
+                tmp[i][j] = (matrix[i][0] * mat[0][j]) +
+                    (matrix[i][1] * mat[1][j]) + (matrix[i][2] * mat[2][j]);
+            }
+        }
+
+        for (int i = 0; i < 3; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {
+                matrix[i][j] = tmp[i][j];
+            }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param args DOCUMENT ME!
+     */
+    public static void main(String[] args)
+    {
+        RotatableMatrix m = new RotatableMatrix(3, 3);
+
+        m.addElement(0, 0, 1);
+
+        m.addElement(0, 1, 0);
+
+        m.addElement(0, 2, 0);
+
+        m.addElement(1, 0, 0);
+
+        m.addElement(1, 1, 2);
+
+        m.addElement(1, 2, 0);
+
+        m.addElement(2, 0, 0);
+
+        m.addElement(2, 1, 0);
+
+        m.addElement(2, 2, 1);
+
+        m.print();
+
+        RotatableMatrix n = new RotatableMatrix(3, 3);
+
+        n.addElement(0, 0, 2);
+
+        n.addElement(0, 1, 1);
+
+        n.addElement(0, 2, 1);
+
+        n.addElement(1, 0, 2);
+
+        n.addElement(1, 1, 1);
+
+        n.addElement(1, 2, 1);
+
+        n.addElement(2, 0, 2);
+
+        n.addElement(2, 1, 1);
+
+        n.addElement(2, 2, 1);
+
+        n.print();
+
+        //m.postMultiply(n.matrix);
+        //m.print();
+        //     m.rotate(45,'z',new RotatableMatrix(3,3));
+        float[] vect = new float[3];
+
+        vect[0] = 2;
+
+        vect[1] = 4;
+
+        vect[2] = 6;
+
+        vect = m.vectorMultiply(vect);
+
+        System.out.println(vect[0] + " " + vect[1] + " " + vect[2]);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void setIdentity()
+    {
+        matrix[0][0] = (float) 1.0;
+
+        matrix[1][1] = (float) 1.0;
+
+        matrix[2][2] = (float) 1.0;
+
+        matrix[0][1] = (float) 0.0;
+
+        matrix[0][2] = (float) 0.0;
+
+        matrix[1][0] = (float) 0.0;
+
+        matrix[1][2] = (float) 0.0;
+
+        matrix[2][0] = (float) 0.0;
+
+        matrix[2][1] = (float) 0.0;
+    }
+}
index 789667e..66b3a13 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class AnnotationColourGradient extends ResidueColourScheme\r
-{\r
-    public static int NO_THRESHOLD = -1;\r
-    public static int BELOW_THRESHOLD = 0;\r
-    public static int ABOVE_THRESHOLD = 1;\r
-\r
-    AlignmentAnnotation annotation;\r
-    int aboveAnnotationThreshold = -1;\r
-\r
-    GraphLine annotationThreshold;\r
-\r
-    float r1, g1, b1, rr, gg, bb, dr, dg, db;\r
-    float range = 0;\r
-\r
-    ColourSchemeI colourScheme;\r
-\r
-    /**\r
-     * Creates a new AnnotationColourGradient object.\r
-     */\r
-    public AnnotationColourGradient(AlignmentAnnotation annotation,\r
-                                    ColourSchemeI originalColour,\r
-                                    int aboveThreshold)\r
-    {\r
-      if(originalColour instanceof AnnotationColourGradient)\r
-      {\r
-        colourScheme = ((AnnotationColourGradient)originalColour).colourScheme;\r
-      }\r
-      else\r
-        colourScheme = originalColour;\r
-\r
-      this.annotation = annotation;\r
-\r
-      aboveAnnotationThreshold = aboveThreshold;\r
-\r
-      if(aboveThreshold!=NO_THRESHOLD && annotation.threshold!=null)\r
-        annotationThreshold = annotation.threshold;\r
-    }\r
-\r
-    /**\r
-     * Creates a new AnnotationColourGradient object.\r
-     */\r
-    public AnnotationColourGradient(AlignmentAnnotation annotation,\r
-        Color minColour, Color maxColour, int aboveThreshold)\r
-    {\r
-      this.annotation = annotation;\r
-\r
-      aboveAnnotationThreshold = aboveThreshold;\r
-\r
-      if(aboveThreshold!=NO_THRESHOLD && annotation.threshold!=null)\r
-        annotationThreshold = annotation.threshold;\r
-\r
-      r1 = minColour.getRed();\r
-      g1 = minColour.getGreen();\r
-      b1 = minColour.getBlue();\r
-\r
-      rr = maxColour.getRed() - r1;\r
-      gg = maxColour.getGreen() - g1;\r
-      bb = maxColour.getBlue() - b1;\r
-\r
-      range = annotation.graphMax - annotation.graphMin;\r
-\r
-    }\r
-\r
-    public Color getMinColour()\r
-    {\r
-      return new Color( (int) r1, (int) g1, (int) b1);\r
-    }\r
-\r
-    public Color getMaxColour()\r
-    {\r
-      return new Color( (int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color findColour(String n)\r
-    {\r
-        return Color.red;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color findColour(String n, int j)\r
-    {\r
-        currentColour = Color.white;\r
-\r
-        if ((threshold == 0) || aboveThreshold(n, j))\r
-        {\r
-          if( j<annotation.annotations.length\r
-              && annotation.annotations[j]!=null\r
-              && !jalview.util.Comparison.isGap(n.charAt(0)))\r
-          {\r
-            if(  aboveAnnotationThreshold==NO_THRESHOLD\r
-               || (annotationThreshold!=null && aboveAnnotationThreshold==ABOVE_THRESHOLD && annotation.annotations[j].value>=annotationThreshold.value)\r
-               || (annotationThreshold!=null && aboveAnnotationThreshold==BELOW_THRESHOLD && annotation.annotations[j].value<=annotationThreshold.value))\r
-            {\r
-              if(colourScheme!=null)\r
-              {\r
-                currentColour = colourScheme.findColour(n, j);\r
-              }\r
-              else if(range!=0)\r
-              {\r
-                dr = rr *\r
-                    ( (annotation.annotations[j].value - annotation.graphMin) /\r
-                     range)\r
-                    + r1;\r
-                dg = gg *\r
-                    ( (annotation.annotations[j].value - annotation.graphMin) /\r
-                     range)\r
-                    + g1;\r
-                db = bb *\r
-                    ( (annotation.annotations[j].value - annotation.graphMin) /\r
-                     range)\r
-                    + b1;\r
-\r
-                currentColour = new Color( (int) dr, (int) dg, (int) db);\r
-              }\r
-            }\r
-          }\r
-        }\r
-\r
-        if(conservationColouring)\r
-         applyConservation(j);\r
-\r
-       return currentColour;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+
+public class AnnotationColourGradient extends ResidueColourScheme
+{
+    public static int NO_THRESHOLD = -1;
+    public static int BELOW_THRESHOLD = 0;
+    public static int ABOVE_THRESHOLD = 1;
+
+    AlignmentAnnotation annotation;
+    int aboveAnnotationThreshold = -1;
+
+    GraphLine annotationThreshold;
+
+    float r1, g1, b1, rr, gg, bb, dr, dg, db;
+    float range = 0;
+
+    ColourSchemeI colourScheme;
+
+    /**
+     * Creates a new AnnotationColourGradient object.
+     */
+    public AnnotationColourGradient(AlignmentAnnotation annotation,
+                                    ColourSchemeI originalColour,
+                                    int aboveThreshold)
+    {
+      if(originalColour instanceof AnnotationColourGradient)
+      {
+        colourScheme = ((AnnotationColourGradient)originalColour).colourScheme;
+      }
+      else
+        colourScheme = originalColour;
+
+      this.annotation = annotation;
+
+      aboveAnnotationThreshold = aboveThreshold;
+
+      if(aboveThreshold!=NO_THRESHOLD && annotation.threshold!=null)
+        annotationThreshold = annotation.threshold;
+    }
+
+    /**
+     * Creates a new AnnotationColourGradient object.
+     */
+    public AnnotationColourGradient(AlignmentAnnotation annotation,
+        Color minColour, Color maxColour, int aboveThreshold)
+    {
+      this.annotation = annotation;
+
+      aboveAnnotationThreshold = aboveThreshold;
+
+      if(aboveThreshold!=NO_THRESHOLD && annotation.threshold!=null)
+        annotationThreshold = annotation.threshold;
+
+      r1 = minColour.getRed();
+      g1 = minColour.getGreen();
+      b1 = minColour.getBlue();
+
+      rr = maxColour.getRed() - r1;
+      gg = maxColour.getGreen() - g1;
+      bb = maxColour.getBlue() - b1;
+
+      range = annotation.graphMax - annotation.graphMin;
+
+    }
+
+
+    public String getAnnotation()
+    {
+      return annotation.label;
+    }
+
+    public int getAboveThreshold()
+    {
+      return aboveAnnotationThreshold;
+    }
+
+    public float getAnnotationThreshold()
+    {
+      if(annotationThreshold==null)
+        return 0;
+      else
+        return annotationThreshold.value;
+    }
+
+    public ColourSchemeI getBaseColour()
+    {
+      return colourScheme;
+    }
+
+    public Color getMinColour()
+    {
+      return new Color( (int) r1, (int) g1, (int) b1);
+    }
+
+    public Color getMaxColour()
+    {
+      return new Color( (int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color findColour(String n)
+    {
+        return Color.red;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color findColour(String n, int j)
+    {
+        currentColour = Color.white;
+
+        if ((threshold == 0) || aboveThreshold(n, j))
+        {
+          if( j<annotation.annotations.length
+              && annotation.annotations[j]!=null
+              && !jalview.util.Comparison.isGap(n.charAt(0)))
+          {
+            if(  aboveAnnotationThreshold==NO_THRESHOLD
+               || (annotationThreshold!=null && aboveAnnotationThreshold==ABOVE_THRESHOLD && annotation.annotations[j].value>=annotationThreshold.value)
+               || (annotationThreshold!=null && aboveAnnotationThreshold==BELOW_THRESHOLD && annotation.annotations[j].value<=annotationThreshold.value))
+            {
+              if(colourScheme!=null)
+              {
+                currentColour = colourScheme.findColour(n, j);
+              }
+              else if(range!=0)
+              {
+                dr = rr *
+                    ( (annotation.annotations[j].value - annotation.graphMin) /
+                     range)
+                    + r1;
+                dg = gg *
+                    ( (annotation.annotations[j].value - annotation.graphMin) /
+                     range)
+                    + g1;
+                db = bb *
+                    ( (annotation.annotations[j].value - annotation.graphMin) /
+                     range)
+                    + b1;
+
+                currentColour = new Color( (int) dr, (int) dg, (int) db);
+              }
+            }
+          }
+        }
+
+        if(conservationColouring)
+         applyConservation(j);
+
+       return currentColour;
+    }
+}
index 6e91e0b..c9bff7d 100755 (executable)
@@ -1,88 +1,88 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-\r
-import java.awt.*;\r
-\r
-public class Blosum62ColourScheme\r
-    extends ResidueColourScheme\r
-{\r
-  public Blosum62ColourScheme()\r
-  {\r
-    super();\r
-  }\r
-\r
-  public Color findColour(String s, int j)\r
-  {\r
-    char res = s.charAt(0);\r
-    if ('a' <= res && res <= 'z' )\r
-    {\r
-       // TO UPPERCASE !!!\r
-       s = String.valueOf( res -= ('a' - 'A') );\r
-    }\r
-\r
-\r
-    if ( (threshold != 0) && !aboveThreshold(s, j))\r
-    {\r
-      return Color.white;\r
-    }\r
-\r
-    if (!jalview.util.Comparison.isGap( res ))\r
-    {\r
-      String max = (String) consensus[j].get("maxResidue");\r
-\r
-      if (max.indexOf(s) > -1)\r
-      {\r
-        currentColour = new Color(154, 154, 255);\r
-      }\r
-      else\r
-      {\r
-        int c = 0;\r
-        int max_aa = 0;\r
-        int n = max.length();\r
-\r
-        do\r
-        {\r
-          c += ResidueProperties.getBLOSUM62(max.substring(max_aa,\r
-              max_aa + 1), s);\r
-        }\r
-        while (++max_aa < n);\r
-\r
-        if (c > 0)\r
-        {\r
-          currentColour = new Color(204, 204, 255);\r
-        }\r
-        else\r
-        {\r
-          currentColour = Color.white;\r
-        }\r
-      }\r
-\r
-      if(conservationColouring)\r
-         applyConservation(j);\r
-    }\r
-    else\r
-    {\r
-      return Color.white;\r
-    }\r
-\r
-    return currentColour;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+
+import java.awt.*;
+
+public class Blosum62ColourScheme
+    extends ResidueColourScheme
+{
+  public Blosum62ColourScheme()
+  {
+    super();
+  }
+
+  public Color findColour(String s, int j)
+  {
+    char res = s.charAt(0);
+    if ('a' <= res && res <= 'z' )
+    {
+       // TO UPPERCASE !!!
+       s = String.valueOf( res -= ('a' - 'A') );
+    }
+
+
+    if ( j>=consensus.length || (threshold != 0 && !aboveThreshold(s, j) ))
+    {
+      return Color.white;
+    }
+
+    if (!jalview.util.Comparison.isGap( res ))
+    {
+      String max = (String) consensus[j].get("maxResidue");
+
+      if (max.indexOf(s) > -1)
+      {
+        currentColour = new Color(154, 154, 255);
+      }
+      else
+      {
+        int c = 0;
+        int max_aa = 0;
+        int n = max.length();
+
+        do
+        {
+          c += ResidueProperties.getBLOSUM62(max.substring(max_aa,
+              max_aa + 1), s);
+        }
+        while (++max_aa < n);
+
+        if (c > 0)
+        {
+          currentColour = new Color(204, 204, 255);
+        }
+        else
+        {
+          currentColour = Color.white;
+        }
+      }
+
+      if(conservationColouring)
+         applyConservation(j);
+    }
+    else
+    {
+      return Color.white;
+    }
+
+    return currentColour;
+  }
+}
index 691cd02..8ddb420 100755 (executable)
@@ -1,52 +1,52 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class BuriedColourScheme extends ScoreColourScheme\r
-{\r
-    /**\r
-     * Creates a new BuriedColourScheme object.\r
-     */\r
-    public BuriedColourScheme()\r
-    {\r
-        super(ResidueProperties.buried, ResidueProperties.buriedmin,\r
-            ResidueProperties.buriedmax);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color makeColour(float c)\r
-    {\r
-        return new Color(0, (float) (1.0 - c), c);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class BuriedColourScheme extends ScoreColourScheme
+{
+    /**
+     * Creates a new BuriedColourScheme object.
+     */
+    public BuriedColourScheme()
+    {
+        super(ResidueProperties.buried, ResidueProperties.buriedmin,
+            ResidueProperties.buriedmax);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color makeColour(float c)
+    {
+        return new Color(0, (float) (1.0 - c), c);
+    }
+}
index 1e38a6d..e39a7db 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class ClustalxColourScheme\r
-    extends ResidueColourScheme\r
-{\r
-  public static Hashtable colhash = new Hashtable();\r
-  Hashtable[] cons;\r
-  int[][] cons2;\r
-  ConsensusColour[] colours;\r
-  ConsensusColour[] ResidueColour;\r
-  int size;\r
-  Consensus[] conses = new Consensus[32];\r
-  Vector colourTable = new Vector();\r
-\r
-  {\r
-    colhash.put("RED", new Color( (float) 0.9, (float) 0.2, (float) 0.1));\r
-    colhash.put("BLUE", new Color( (float) 0.5, (float) 0.7, (float) 0.9));\r
-    colhash.put("GREEN", new Color( (float) 0.1, (float) 0.8, (float) 0.1));\r
-    colhash.put("ORANGE", new Color( (float) 0.9, (float) 0.6, (float) 0.3));\r
-    colhash.put("CYAN", new Color( (float) 0.1, (float) 0.7, (float) 0.7));\r
-    colhash.put("PINK", new Color( (float) 0.9, (float) 0.5, (float) 0.5));\r
-    colhash.put("MAGENTA", new Color( (float) 0.8, (float) 0.3, (float) 0.8));\r
-    colhash.put("YELLOW", new Color( (float) 0.8, (float) 0.8, (float) 0.0));\r
-  }\r
-\r
-  public ClustalxColourScheme(Vector seqs, int maxWidth)\r
-  {\r
-    resetClustalX(seqs, maxWidth);\r
-  }\r
-\r
-  public void resetClustalX(Vector seqs, int maxWidth)\r
-  {\r
-    cons2 = new int[maxWidth][24];\r
-\r
-    int start = 0;\r
-\r
-    // Initialize the array\r
-    for (int j = 0; j < 24; j++)\r
-    {\r
-      for (int i = 0; i < maxWidth; i++)\r
-      {\r
-        cons2[i][j] = 0;\r
-      }\r
-    }\r
-\r
-    int res;\r
-    int i;\r
-    int j = 0;\r
-    String seq;\r
-\r
-    while (j < seqs.size())\r
-    {\r
-      seq = ( (SequenceI) seqs.elementAt(j)).getSequence();\r
-\r
-      int end_j = seq.length() - 1;\r
-\r
-      for (i = start; i <= end_j; i++)\r
-      {\r
-        if ( (seq.length() - 1) < i)\r
-        {\r
-          res = 23;\r
-        }\r
-        else\r
-        {\r
-          res = ( (Integer) ResidueProperties.aaHash.get(seq.charAt(i) +\r
-              "")).intValue();\r
-        }\r
-\r
-        cons2[i][res]++;\r
-      }\r
-\r
-      j++;\r
-    }\r
-\r
-    this.size = seqs.size();\r
-    makeColours();\r
-  }\r
-\r
-  public void makeColours()\r
-  {\r
-    conses[0] = new Consensus("WLVIMAFCYHP", 60);\r
-    conses[1] = new Consensus("WLVIMAFCYHP", 80);\r
-    conses[2] = new Consensus("ED", 50);\r
-    conses[3] = new Consensus("KR", 60);\r
-    conses[4] = new Consensus("G", 50);\r
-    conses[5] = new Consensus("N", 50);\r
-    conses[6] = new Consensus("QE", 50);\r
-    conses[7] = new Consensus("P", 50);\r
-    conses[8] = new Consensus("TS", 50);\r
-\r
-    conses[26] = new Consensus("A", 85);\r
-    conses[27] = new Consensus("C", 85);\r
-    conses[10] = new Consensus("E", 85);\r
-    conses[11] = new Consensus("F", 85);\r
-    conses[12] = new Consensus("G", 85);\r
-    conses[13] = new Consensus("H", 85);\r
-    conses[14] = new Consensus("I", 85);\r
-    conses[15] = new Consensus("L", 85);\r
-    conses[16] = new Consensus("M", 85);\r
-    conses[17] = new Consensus("N", 85);\r
-    conses[18] = new Consensus("P", 85);\r
-    conses[19] = new Consensus("Q", 85);\r
-    conses[20] = new Consensus("R", 85);\r
-    conses[21] = new Consensus("S", 85);\r
-    conses[22] = new Consensus("T", 85);\r
-    conses[23] = new Consensus("V", 85);\r
-    conses[24] = new Consensus("W", 85);\r
-    conses[25] = new Consensus("Y", 85);\r
-    conses[28] = new Consensus("K", 85);\r
-    conses[29] = new Consensus("D", 85);\r
-\r
-    conses[30] = new Consensus("G", 0);\r
-    conses[31] = new Consensus("P", 0);\r
-\r
-    // We now construct the colours\r
-    colours = new ConsensusColour[11];\r
-\r
-    Consensus[] tmp8 = new Consensus[1];\r
-    tmp8[0] = conses[30]; //G\r
-    colours[7] = new ConsensusColour( (Color) colhash.get("ORANGE"), tmp8);\r
-\r
-    Consensus[] tmp9 = new Consensus[1];\r
-    tmp9[0] = conses[31]; //P\r
-    colours[8] = new ConsensusColour( (Color) colhash.get("YELLOW"), tmp9);\r
-\r
-    Consensus[] tmp10 = new Consensus[1];\r
-    tmp10[0] = conses[27]; //C\r
-    colours[9] = new ConsensusColour( (Color) colhash.get("PINK"), tmp8);\r
-\r
-    Consensus[] tmp1 = new Consensus[14];\r
-    tmp1[0] = conses[0]; //%\r
-    tmp1[1] = conses[1]; //#\r
-    tmp1[2] = conses[26]; //A\r
-    tmp1[3] = conses[27]; //C\r
-    tmp1[4] = conses[11]; //F\r
-    tmp1[5] = conses[13]; //H\r
-    tmp1[6] = conses[14]; //I\r
-    tmp1[7] = conses[15]; //L\r
-    tmp1[8] = conses[16]; //M\r
-    tmp1[9] = conses[23]; //V\r
-    tmp1[10] = conses[24]; //W\r
-    tmp1[11] = conses[25]; //Y\r
-    tmp1[12] = conses[18]; //P\r
-    tmp1[13] = conses[19]; //p\r
-    colours[0] = new ConsensusColour( (Color) colhash.get("BLUE"), tmp1);\r
-\r
-    colours[10] = new ConsensusColour( (Color) colhash.get("CYAN"), tmp1);\r
-\r
-    Consensus[] tmp2 = new Consensus[5];\r
-    tmp2[0] = conses[8]; //t\r
-    tmp2[1] = conses[21]; //S\r
-    tmp2[2] = conses[22]; //T\r
-    tmp2[3] = conses[0]; //%\r
-    tmp2[4] = conses[1]; //#\r
-    colours[1] = new ConsensusColour( (Color) colhash.get("GREEN"), tmp2);\r
-\r
-    Consensus[] tmp3 = new Consensus[3];\r
-\r
-    tmp3[0] = conses[17]; //N\r
-    tmp3[1] = conses[29]; //D\r
-    tmp3[2] = conses[5]; //n\r
-    colours[2] = new ConsensusColour( (Color) colhash.get("GREEN"), tmp3);\r
-\r
-    Consensus[] tmp4 = new Consensus[6];\r
-    tmp4[0] = conses[6]; // q = QE\r
-    tmp4[1] = conses[19]; //Q\r
-    tmp4[2] = conses[22]; //E\r
-    tmp4[3] = conses[3]; //+\r
-    tmp4[4] = conses[28]; //K\r
-    tmp4[5] = conses[20]; //R\r
-    colours[3] = new ConsensusColour( (Color) colhash.get("GREEN"), tmp4);\r
-\r
-    Consensus[] tmp5 = new Consensus[4];\r
-    tmp5[0] = conses[3]; //+\r
-    tmp5[1] = conses[28]; //K\r
-    tmp5[2] = conses[20]; //R\r
-    tmp5[3] = conses[19]; //Q\r
-    colours[4] = new ConsensusColour( (Color) colhash.get("RED"), tmp5);\r
-\r
-    Consensus[] tmp6 = new Consensus[5];\r
-    tmp6[0] = conses[3]; //-\r
-    tmp6[1] = conses[29]; //D\r
-    tmp6[2] = conses[10]; //E\r
-    tmp6[3] = conses[6]; //q\r
-    tmp6[4] = conses[19]; //Q\r
-    colours[5] = new ConsensusColour( (Color) colhash.get("MAGENTA"), tmp6);\r
-\r
-    Consensus[] tmp7 = new Consensus[5];\r
-    tmp7[0] = conses[3]; //-\r
-    tmp7[1] = conses[29]; //D\r
-    tmp7[2] = conses[10]; //E\r
-    tmp7[3] = conses[17]; //N\r
-    tmp7[4] = conses[2]; //DE\r
-    colours[6] = new ConsensusColour( (Color) colhash.get("MAGENTA"), tmp7);\r
-\r
-    // Now attach the ConsensusColours to the residue letters\r
-    ResidueColour = new ConsensusColour[20];\r
-    ResidueColour[0] = colours[0]; // A\r
-    ResidueColour[1] = colours[4]; // R\r
-    ResidueColour[2] = colours[2]; // N\r
-    ResidueColour[3] = colours[6]; // D\r
-    ResidueColour[4] = colours[0]; // C\r
-    ResidueColour[5] = colours[3]; // Q\r
-    ResidueColour[6] = colours[5]; // E\r
-    ResidueColour[7] = colours[7]; // G\r
-    ResidueColour[8] = colours[10]; // H\r
-    ResidueColour[9] = colours[0]; // I\r
-    ResidueColour[10] = colours[0]; // L\r
-    ResidueColour[11] = colours[4]; // K\r
-    ResidueColour[12] = colours[0]; // M\r
-    ResidueColour[13] = colours[0]; // F\r
-    ResidueColour[14] = colours[8]; // P\r
-    ResidueColour[15] = colours[1]; // S\r
-    ResidueColour[16] = colours[1]; // T\r
-    ResidueColour[17] = colours[0]; // W\r
-    ResidueColour[18] = colours[10]; // Y\r
-    ResidueColour[19] = colours[0]; // V\r
-  }\r
-\r
-  public Color findColour(String s)\r
-  {\r
-    return Color.pink;\r
-  }\r
-\r
-  public Color findColour(String s, int j)\r
-  {\r
-\r
-    if(cons2.length<=j)\r
-      return currentColour;\r
-\r
-\r
-    if ( (threshold != 0) && !aboveThreshold(s, j))\r
-    {\r
-      return Color.white;\r
-    }\r
-\r
-    int i = ( (Integer) ResidueProperties.aaHash.get(s)).intValue();\r
-\r
-    currentColour = Color.white;\r
-\r
-    if (i > 19)\r
-    {\r
-      return currentColour;\r
-    }\r
-\r
-  for (int k = 0; k < ResidueColour[i].conses.length; k++)\r
-  {\r
-    if (ResidueColour[i].conses[k].isConserved(cons2, j, size))\r
-    {\r
-      currentColour = ResidueColour[i].c;\r
-    }\r
-  }\r
-\r
-    if (i == 4)\r
-    {\r
-      if (conses[27].isConserved(cons2, j, size))\r
-      {\r
-        currentColour = (Color) colhash.get("PINK");\r
-      }\r
-    }\r
-\r
-    if(conservationColouring)\r
-         applyConservation(j);\r
-\r
-    return currentColour;\r
-  }\r
-}\r
-\r
-class ConsensusColour\r
-{\r
-  Consensus[] conses;\r
-  Color c;\r
-\r
-  public ConsensusColour(Color c, Consensus[] conses)\r
-  {\r
-    this.conses = conses;\r
-\r
-    //    this.list = list;\r
-    this.c = c;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+import java.util.*;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+
+public class ClustalxColourScheme
+    extends ResidueColourScheme
+{
+  public static Hashtable colhash = new Hashtable();
+  Hashtable[] cons;
+  int[][] cons2;
+  ConsensusColour[] colours;
+  ConsensusColour[] ResidueColour;
+  int size;
+  Consensus[] conses = new Consensus[32];
+  Vector colourTable = new Vector();
+
+  {
+    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));
+  }
+
+  public ClustalxColourScheme(Vector seqs, int maxWidth)
+  {
+    resetClustalX(seqs, maxWidth);
+  }
+
+  public void resetClustalX(Vector seqs, int maxWidth)
+  {
+    cons2 = new int[maxWidth][24];
+
+    int start = 0;
+
+    // Initialize the array
+    for (int j = 0; j < 24; j++)
+    {
+      for (int i = 0; i < maxWidth; i++)
+      {
+        cons2[i][j] = 0;
+      }
+    }
+
+    int res;
+    int i;
+    int j = 0;
+    String seq;
+
+    while (j < seqs.size())
+    {
+      seq = ( (SequenceI) seqs.elementAt(j)).getSequence();
+
+      int end_j = seq.length() - 1;
+
+      for (i = start; i <= end_j; i++)
+      {
+        if ( (seq.length() - 1) < i)
+        {
+          res = 23;
+        }
+        else
+        {
+          res = ( (Integer) ResidueProperties.aaHash.get(seq.charAt(i) +
+              "")).intValue();
+        }
+
+        cons2[i][res]++;
+      }
+
+      j++;
+    }
+
+    this.size = seqs.size();
+    makeColours();
+  }
+
+  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[30] = new Consensus("G", 0);
+    conses[31] = new Consensus("P", 0);
+
+    // We now construct the colours
+    colours = new ConsensusColour[11];
+
+    Consensus[] tmp8 = new Consensus[1];
+    tmp8[0] = conses[30]; //G
+    colours[7] = new ConsensusColour( (Color) colhash.get("ORANGE"), tmp8);
+
+    Consensus[] tmp9 = new Consensus[1];
+    tmp9[0] = conses[31]; //P
+    colours[8] = new ConsensusColour( (Color) colhash.get("YELLOW"), tmp9);
+
+    Consensus[] tmp10 = new Consensus[1];
+    tmp10[0] = conses[27]; //C
+    colours[9] = new ConsensusColour( (Color) colhash.get("PINK"), tmp8);
+
+    Consensus[] tmp1 = new Consensus[14];
+    tmp1[0] = conses[0]; //%
+    tmp1[1] = conses[1]; //#
+    tmp1[2] = conses[26]; //A
+    tmp1[3] = conses[27]; //C
+    tmp1[4] = conses[11]; //F
+    tmp1[5] = conses[13]; //H
+    tmp1[6] = conses[14]; //I
+    tmp1[7] = conses[15]; //L
+    tmp1[8] = conses[16]; //M
+    tmp1[9] = conses[23]; //V
+    tmp1[10] = conses[24]; //W
+    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[10] = new ConsensusColour( (Color) colhash.get("CYAN"), tmp1);
+
+    Consensus[] tmp2 = new Consensus[5];
+    tmp2[0] = conses[8]; //t
+    tmp2[1] = conses[21]; //S
+    tmp2[2] = conses[22]; //T
+    tmp2[3] = conses[0]; //%
+    tmp2[4] = conses[1]; //#
+    colours[1] = new ConsensusColour( (Color) colhash.get("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);
+
+    Consensus[] tmp4 = new Consensus[6];
+    tmp4[0] = conses[6]; // q = QE
+    tmp4[1] = conses[19]; //Q
+    tmp4[2] = conses[22]; //E
+    tmp4[3] = conses[3]; //+
+    tmp4[4] = conses[28]; //K
+    tmp4[5] = conses[20]; //R
+    colours[3] = new ConsensusColour( (Color) colhash.get("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);
+
+    Consensus[] tmp6 = new Consensus[5];
+    tmp6[0] = conses[3]; //-
+    tmp6[1] = conses[29]; //D
+    tmp6[2] = conses[10]; //E
+    tmp6[3] = conses[6]; //q
+    tmp6[4] = conses[19]; //Q
+    colours[5] = new ConsensusColour( (Color) colhash.get("MAGENTA"), tmp6);
+
+    Consensus[] tmp7 = new Consensus[5];
+    tmp7[0] = conses[3]; //-
+    tmp7[1] = conses[29]; //D
+    tmp7[2] = conses[10]; //E
+    tmp7[3] = conses[17]; //N
+    tmp7[4] = conses[2]; //DE
+    colours[6] = new ConsensusColour( (Color) colhash.get("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
+  }
+
+  public Color findColour(String s)
+  {
+    return Color.pink;
+  }
+
+  public Color findColour(String s, int j)
+  {
+
+    if(cons2.length<=j)
+      return currentColour;
+
+
+    if ( (threshold != 0) && !aboveThreshold(s, j))
+    {
+      return Color.white;
+    }
+
+    int i = ( (Integer) ResidueProperties.aaHash.get(s)).intValue();
+
+    currentColour = Color.white;
+
+    if (i > 19)
+    {
+      return currentColour;
+    }
+
+  for (int k = 0; k < ResidueColour[i].conses.length; k++)
+  {
+    if (ResidueColour[i].conses[k].isConserved(cons2, j, size))
+    {
+      currentColour = ResidueColour[i].c;
+    }
+  }
+
+    if (i == 4)
+    {
+      if (conses[27].isConserved(cons2, j, size))
+      {
+        currentColour = (Color) colhash.get("PINK");
+      }
+    }
+
+    if(conservationColouring)
+         applyConservation(j);
+
+    return currentColour;
+  }
+}
+
+class ConsensusColour
+{
+  Consensus[] conses;
+  Color c;
+
+  public ConsensusColour(Color c, Consensus[] conses)
+  {
+    this.conses = conses;
+
+    //    this.list = list;
+    this.c = c;
+  }
+}
index 8f0f3c5..db4ab8b 100755 (executable)
@@ -1,44 +1,44 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-public interface ColourSchemeI\r
-{\r
-  public Color findColour(String aa);\r
-\r
-  public Color findColour(String s, int j);\r
-\r
-  public void setConsensus(java.util.Vector v);\r
-\r
-  public void setConservation(jalview.analysis.Conservation c);\r
-\r
-  public boolean conservationApplied();\r
-\r
-  public void setConservationInc(int i);\r
-\r
-  public int getConservationInc();\r
-\r
-  public int getThreshold();\r
-\r
-  public void setThreshold(int ct, boolean ignoreGaps);\r
-\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+import java.awt.*;
+
+public interface ColourSchemeI
+{
+  public Color findColour(String aa);
+
+  public Color findColour(String s, int j);
+
+  public void setConsensus(java.util.Vector v);
+
+  public void setConservation(jalview.analysis.Conservation c);
+
+  public boolean conservationApplied();
+
+  public void setConservationInc(int i);
+
+  public int getConservationInc();
+
+  public int getThreshold();
+
+  public void setThreshold(int ct, boolean ignoreGaps);
+
+
+}
index b586a0a..355d717 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class ColourSchemeProperty\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public static final int CLUSTAL = 0;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int BLOSUM = 1;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int PID = 2;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int ZAPPO = 3;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int TAYLOR = 4;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int HYDROPHOBIC = 5;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int HELIX = 6;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int STRAND = 7;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int TURN = 8;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int BURIED = 9;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int NUCLEOTIDE = 10;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int USER_DEFINED = 11;\r
-\r
-\r
-    /** DOCUMENT ME!! */\r
-    public static final int NONE = 12;\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param name DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static int getColourIndexFromName(String name)\r
-    {\r
-        int ret = 12;\r
-\r
-        if (name.equalsIgnoreCase("Clustal"))\r
-        {\r
-            ret = CLUSTAL;\r
-        }\r
-        else if (name.equalsIgnoreCase("Blosum62"))\r
-        {\r
-            ret = BLOSUM;\r
-        }\r
-        else if (name.equalsIgnoreCase("% Identity"))\r
-        {\r
-            ret = PID;\r
-        }\r
-        else if (name.equalsIgnoreCase("Zappo"))\r
-        {\r
-            ret = ZAPPO;\r
-        }\r
-        else if (name.equalsIgnoreCase("Taylor"))\r
-        {\r
-          ret = TAYLOR;\r
-        }\r
-        else if (name.equalsIgnoreCase("Hydrophobic"))\r
-        {\r
-            ret = HYDROPHOBIC;\r
-        }\r
-        else if (name.equalsIgnoreCase("Helix Propensity"))\r
-        {\r
-            ret = HELIX;\r
-        }\r
-        else if (name.equalsIgnoreCase("Strand Propensity"))\r
-        {\r
-            ret = STRAND;\r
-        }\r
-        else if (name.equalsIgnoreCase("Turn Propensity"))\r
-        {\r
-            ret = TURN;\r
-        }\r
-        else if (name.equalsIgnoreCase("Buried Index"))\r
-        {\r
-            ret = BURIED;\r
-        }\r
-        else if (name.equalsIgnoreCase("Nucleotide"))\r
-        {\r
-            ret = NUCLEOTIDE;\r
-        }\r
-        else if (name.equalsIgnoreCase("User Defined"))\r
-        {\r
-            ret = USER_DEFINED;\r
-        }\r
-\r
-        return ret;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param cs DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static String getColourName(ColourSchemeI cs)\r
-    {\r
-\r
-        int index = 12;\r
-\r
-        if (cs instanceof ClustalxColourScheme)\r
-        {\r
-            index = CLUSTAL;\r
-        }\r
-        else if (cs instanceof Blosum62ColourScheme)\r
-        {\r
-            index = BLOSUM;\r
-        }\r
-        else if (cs instanceof PIDColourScheme)\r
-        {\r
-            index = PID;\r
-        }\r
-        else if (cs instanceof ZappoColourScheme)\r
-        {\r
-            index = ZAPPO;\r
-        }\r
-        else if (cs instanceof TaylorColourScheme)\r
-        {\r
-            index = TAYLOR;\r
-        }\r
-        else if (cs instanceof HydrophobicColourScheme)\r
-        {\r
-            index = HYDROPHOBIC;\r
-        }\r
-        else if (cs instanceof HelixColourScheme)\r
-        {\r
-            index = HELIX;\r
-        }\r
-        else if (cs instanceof StrandColourScheme)\r
-        {\r
-            index = STRAND;\r
-        }\r
-        else if (cs instanceof TurnColourScheme)\r
-        {\r
-            index = TURN;\r
-        }\r
-        else if (cs instanceof BuriedColourScheme)\r
-        {\r
-            index = BURIED;\r
-        }\r
-        else if (cs instanceof NucleotideColourScheme)\r
-        {\r
-            index = NUCLEOTIDE;\r
-        }\r
-        else if (cs instanceof UserColourScheme)\r
-        {\r
-            index = USER_DEFINED;\r
-        }\r
-\r
-        return getColourName(index);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param index DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static String getColourName(int index)\r
-    {\r
-        String ret = null;\r
-\r
-        switch (index)\r
-        {\r
-        case CLUSTAL:\r
-            ret = "Clustal";\r
-\r
-            break;\r
-\r
-        case BLOSUM:\r
-            ret = "Blosum62";\r
-\r
-            break;\r
-\r
-        case PID:\r
-            ret = "% Identity";\r
-\r
-            break;\r
-\r
-        case ZAPPO:\r
-            ret = "Zappo";\r
-\r
-            break;\r
-\r
-        case TAYLOR:\r
-            ret = "Taylor";\r
-            break;\r
-\r
-        case HYDROPHOBIC:\r
-            ret = "Hydrophobic";\r
-\r
-            break;\r
-\r
-        case HELIX:\r
-            ret = "Helix Propensity";\r
-\r
-            break;\r
-\r
-        case STRAND:\r
-            ret = "Strand Propensity";\r
-\r
-            break;\r
-\r
-        case TURN:\r
-            ret = "Turn Propensity";\r
-\r
-            break;\r
-\r
-        case BURIED:\r
-            ret = "Buried Index";\r
-\r
-            break;\r
-\r
-        case NUCLEOTIDE:\r
-            ret = "Nucleotide";\r
-\r
-            break;\r
-\r
-        case USER_DEFINED:\r
-            ret = "User Defined";\r
-\r
-            break;\r
-\r
-        default:\r
-            ret = "None";\r
-\r
-            break;\r
-        }\r
-\r
-        return ret;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param al DOCUMENT ME!\r
-     * @param name DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static ColourSchemeI getColour(jalview.datamodel.AlignmentI al,\r
-        String name)\r
-    {\r
-        return getColour(al.getSequences(), al.getWidth(), name);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seqs DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param name DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static ColourSchemeI getColour(java.util.Vector seqs, int width,\r
-        String name)\r
-    {\r
-        return getColour(seqs, width, getColourIndexFromName(name));\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param seqs DOCUMENT ME!\r
-     * @param width DOCUMENT ME!\r
-     * @param index DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public static ColourSchemeI getColour(java.util.Vector seqs, int width,\r
-        int index)\r
-    {\r
-        ColourSchemeI cs = null;\r
-\r
-        switch (index)\r
-        {\r
-        case CLUSTAL:\r
-            cs = new ClustalxColourScheme(seqs, width);\r
-\r
-            break;\r
-\r
-        case BLOSUM:\r
-            cs = new Blosum62ColourScheme();\r
-\r
-            break;\r
-\r
-        case PID:\r
-            cs = new PIDColourScheme();\r
-\r
-            break;\r
-\r
-        case ZAPPO:\r
-            cs = new ZappoColourScheme();\r
-\r
-            break;\r
-\r
-        case TAYLOR:\r
-            cs = new TaylorColourScheme();\r
-            break;\r
-\r
-        case HYDROPHOBIC:\r
-            cs = new HydrophobicColourScheme();\r
-\r
-            break;\r
-\r
-        case HELIX:\r
-            cs = new HelixColourScheme();\r
-\r
-            break;\r
-\r
-        case STRAND:\r
-            cs = new StrandColourScheme();\r
-\r
-            break;\r
-\r
-        case TURN:\r
-            cs = new TurnColourScheme();\r
-\r
-            break;\r
-\r
-        case BURIED:\r
-            cs = new BuriedColourScheme();\r
-\r
-            break;\r
-\r
-        case NUCLEOTIDE:\r
-            cs = new NucleotideColourScheme();\r
-\r
-            break;\r
-\r
-        case USER_DEFINED:\r
-          Color[] col = new Color[24];\r
-          for (int i = 0; i < 24; i++)\r
-            col[i] = Color.white;\r
-          cs = new UserColourScheme(col);\r
-            break;\r
-\r
-        default:\r
-            break;\r
-        }\r
-\r
-        return cs;\r
-    }\r
-\r
-    public static Color getAWTColorFromName(String name)\r
-    {\r
-      Color col = null;\r
-      name = name.toLowerCase();\r
-      if(name.equals("black"))\r
-        col = Color.black;\r
-      else if(name.equals("blue"))\r
-        col = Color.blue;\r
-      else if(name.equals("cyan"))\r
-        col = Color.cyan;\r
-      else if(name.equals("darkGray"))\r
-        col = Color.darkGray;\r
-      else if(name.equals("gray"))\r
-        col = Color.gray;\r
-      else if(name.equals("green"))\r
-        col = Color.green;\r
-      else if(name.equals("lightGray"))\r
-        col = Color.lightGray;\r
-      else if(name.equals("magenta"))\r
-        col = Color.magenta;\r
-      else if(name.equals("orange"))\r
-        col = Color.orange;\r
-      else if(name.equals("pink"))\r
-        col = Color.pink;\r
-      else if(name.equals("red"))\r
-        col = Color.red;\r
-      else if(name.equals("white"))\r
-        col = Color.white;\r
-      else if(name.equals("yellow"))\r
-        col = Color.yellow;\r
-\r
-      return col;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ColourSchemeProperty
+{
+    /** DOCUMENT ME!! */
+    public static final int CLUSTAL = 0;
+
+    /** DOCUMENT ME!! */
+    public static final int BLOSUM = 1;
+
+    /** DOCUMENT ME!! */
+    public static final int PID = 2;
+
+    /** DOCUMENT ME!! */
+    public static final int ZAPPO = 3;
+
+    /** DOCUMENT ME!! */
+    public static final int TAYLOR = 4;
+
+    /** DOCUMENT ME!! */
+    public static final int HYDROPHOBIC = 5;
+
+    /** DOCUMENT ME!! */
+    public static final int HELIX = 6;
+
+    /** DOCUMENT ME!! */
+    public static final int STRAND = 7;
+
+    /** DOCUMENT ME!! */
+    public static final int TURN = 8;
+
+    /** DOCUMENT ME!! */
+    public static final int BURIED = 9;
+
+    /** DOCUMENT ME!! */
+    public static final int NUCLEOTIDE = 10;
+
+    /** DOCUMENT ME!! */
+    public static final int USER_DEFINED = 11;
+
+
+    /** DOCUMENT ME!! */
+    public static final int NONE = 12;
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static int getColourIndexFromName(String name)
+    {
+        int ret = 12;
+
+        if (name.equalsIgnoreCase("Clustal"))
+        {
+            ret = CLUSTAL;
+        }
+        else if (name.equalsIgnoreCase("Blosum62"))
+        {
+            ret = BLOSUM;
+        }
+        else if (name.equalsIgnoreCase("% Identity"))
+        {
+            ret = PID;
+        }
+        else if (name.equalsIgnoreCase("Zappo"))
+        {
+            ret = ZAPPO;
+        }
+        else if (name.equalsIgnoreCase("Taylor"))
+        {
+          ret = TAYLOR;
+        }
+        else if (name.equalsIgnoreCase("Hydrophobic"))
+        {
+            ret = HYDROPHOBIC;
+        }
+        else if (name.equalsIgnoreCase("Helix Propensity"))
+        {
+            ret = HELIX;
+        }
+        else if (name.equalsIgnoreCase("Strand Propensity"))
+        {
+            ret = STRAND;
+        }
+        else if (name.equalsIgnoreCase("Turn Propensity"))
+        {
+            ret = TURN;
+        }
+        else if (name.equalsIgnoreCase("Buried Index"))
+        {
+            ret = BURIED;
+        }
+        else if (name.equalsIgnoreCase("Nucleotide"))
+        {
+            ret = NUCLEOTIDE;
+        }
+        else if (name.equalsIgnoreCase("User Defined"))
+        {
+            ret = USER_DEFINED;
+        }
+
+        return ret;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param cs DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static String getColourName(ColourSchemeI cs)
+    {
+
+        int index = 12;
+
+        if (cs instanceof ClustalxColourScheme)
+        {
+            index = CLUSTAL;
+        }
+        else if (cs instanceof Blosum62ColourScheme)
+        {
+            index = BLOSUM;
+        }
+        else if (cs instanceof PIDColourScheme)
+        {
+            index = PID;
+        }
+        else if (cs instanceof ZappoColourScheme)
+        {
+            index = ZAPPO;
+        }
+        else if (cs instanceof TaylorColourScheme)
+        {
+            index = TAYLOR;
+        }
+        else if (cs instanceof HydrophobicColourScheme)
+        {
+            index = HYDROPHOBIC;
+        }
+        else if (cs instanceof HelixColourScheme)
+        {
+            index = HELIX;
+        }
+        else if (cs instanceof StrandColourScheme)
+        {
+            index = STRAND;
+        }
+        else if (cs instanceof TurnColourScheme)
+        {
+            index = TURN;
+        }
+        else if (cs instanceof BuriedColourScheme)
+        {
+            index = BURIED;
+        }
+        else if (cs instanceof NucleotideColourScheme)
+        {
+            index = NUCLEOTIDE;
+        }
+        else if (cs instanceof UserColourScheme)
+        {
+            index = USER_DEFINED;
+        }
+
+        return getColourName(index);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param index DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static String getColourName(int index)
+    {
+        String ret = null;
+
+        switch (index)
+        {
+        case CLUSTAL:
+            ret = "Clustal";
+
+            break;
+
+        case BLOSUM:
+            ret = "Blosum62";
+
+            break;
+
+        case PID:
+            ret = "% Identity";
+
+            break;
+
+        case ZAPPO:
+            ret = "Zappo";
+
+            break;
+
+        case TAYLOR:
+            ret = "Taylor";
+            break;
+
+        case HYDROPHOBIC:
+            ret = "Hydrophobic";
+
+            break;
+
+        case HELIX:
+            ret = "Helix Propensity";
+
+            break;
+
+        case STRAND:
+            ret = "Strand Propensity";
+
+            break;
+
+        case TURN:
+            ret = "Turn Propensity";
+
+            break;
+
+        case BURIED:
+            ret = "Buried Index";
+
+            break;
+
+        case NUCLEOTIDE:
+            ret = "Nucleotide";
+
+            break;
+
+        case USER_DEFINED:
+            ret = "User Defined";
+
+            break;
+
+        default:
+            ret = "None";
+
+            break;
+        }
+
+        return ret;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param al DOCUMENT ME!
+     * @param name DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static ColourSchemeI getColour(jalview.datamodel.AlignmentI al,
+        String name)
+    {
+        return getColour(al.getSequences(), al.getWidth(), name);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seqs DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param name DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static ColourSchemeI getColour(java.util.Vector seqs, int width,
+        String name)
+    {
+        return getColour(seqs, width, getColourIndexFromName(name));
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param seqs DOCUMENT ME!
+     * @param width DOCUMENT ME!
+     * @param index DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public static ColourSchemeI getColour(java.util.Vector seqs, int width,
+        int index)
+    {
+        ColourSchemeI cs = null;
+
+        switch (index)
+        {
+        case CLUSTAL:
+            cs = new ClustalxColourScheme(seqs, width);
+
+            break;
+
+        case BLOSUM:
+            cs = new Blosum62ColourScheme();
+
+            break;
+
+        case PID:
+            cs = new PIDColourScheme();
+
+            break;
+
+        case ZAPPO:
+            cs = new ZappoColourScheme();
+
+            break;
+
+        case TAYLOR:
+            cs = new TaylorColourScheme();
+            break;
+
+        case HYDROPHOBIC:
+            cs = new HydrophobicColourScheme();
+
+            break;
+
+        case HELIX:
+            cs = new HelixColourScheme();
+
+            break;
+
+        case STRAND:
+            cs = new StrandColourScheme();
+
+            break;
+
+        case TURN:
+            cs = new TurnColourScheme();
+
+            break;
+
+        case BURIED:
+            cs = new BuriedColourScheme();
+
+            break;
+
+        case NUCLEOTIDE:
+            cs = new NucleotideColourScheme();
+
+            break;
+
+        case USER_DEFINED:
+          Color[] col = new Color[24];
+          for (int i = 0; i < 24; i++)
+            col[i] = Color.white;
+          cs = new UserColourScheme(col);
+            break;
+
+        default:
+            break;
+        }
+
+        return cs;
+    }
+
+    public static Color getAWTColorFromName(String name)
+    {
+      Color col = null;
+      name = name.toLowerCase();
+      if(name.equals("black"))
+        col = Color.black;
+      else if(name.equals("blue"))
+        col = Color.blue;
+      else if(name.equals("cyan"))
+        col = Color.cyan;
+      else if(name.equals("darkGray"))
+        col = Color.darkGray;
+      else if(name.equals("gray"))
+        col = Color.gray;
+      else if(name.equals("green"))
+        col = Color.green;
+      else if(name.equals("lightGray"))
+        col = Color.lightGray;
+      else if(name.equals("magenta"))
+        col = Color.magenta;
+      else if(name.equals("orange"))
+        col = Color.orange;
+      else if(name.equals("pink"))
+        col = Color.pink;
+      else if(name.equals("red"))
+        col = Color.red;
+      else if(name.equals("white"))
+        col = Color.white;
+      else if(name.equals("yellow"))
+        col = Color.yellow;
+
+      return col;
+    }
+}
index ac895bb..93ae548 100755 (executable)
@@ -1,80 +1,80 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-////////////////////////////////////////////\r
-// This does nothing at all at the moment!!!!!!!!!!\r
-// AW 15th Dec 2004\r
-/////////////////////////////////////////\r
-public class Consensus\r
-{\r
-  int[] mask;\r
-  double threshold;\r
-  String maskstr;\r
-\r
-  public Consensus(String mask, double threshold)\r
-  {\r
-    // this.id = id;\r
-    //    this.mask = mask;\r
-    this.maskstr = mask;\r
-    setMask(mask);\r
-    this.threshold = threshold;\r
-  }\r
-\r
-  public void setMask(String s)\r
-  {\r
-    this.mask = setNums(s);\r
-\r
-    //   for (int i=0; i < mask.length; i++) {\r
-    //  System.out.println(mask[i] + " " + ResidueProperties.aa[mask[i]]);\r
-    // }\r
-  }\r
-\r
-  public boolean isConserved(int[][] cons2, int col, int size)\r
-  {\r
-    int tot = 0;\r
-\r
-    for (int i = 0; i < mask.length; i++)\r
-    {\r
-      tot += cons2[col][mask[i]];\r
-    }\r
-\r
-    if ( (double) tot > ( (threshold * size) / 100))\r
-    {\r
-      return true;\r
-    }\r
-\r
-    return false;\r
-  }\r
-\r
-  int[] setNums(String s)\r
-  {\r
-    int[] out = new int[s.length()];\r
-    int i = 0;\r
-\r
-    while (i < s.length())\r
-    {\r
-      out[i] = ( (Integer) ResidueProperties.aaHash.get(s.substring(i,\r
-          i + 1))).intValue();\r
-      i++;\r
-    }\r
-\r
-    return out;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+////////////////////////////////////////////
+// This does nothing at all at the moment!!!!!!!!!!
+// AW 15th Dec 2004
+/////////////////////////////////////////
+public class Consensus
+{
+  int[] mask;
+  double threshold;
+  String maskstr;
+
+  public Consensus(String mask, double threshold)
+  {
+    // this.id = id;
+    //    this.mask = mask;
+    this.maskstr = mask;
+    setMask(mask);
+    this.threshold = threshold;
+  }
+
+  public void setMask(String s)
+  {
+    this.mask = setNums(s);
+
+    //   for (int i=0; i < mask.length; i++) {
+    //  System.out.println(mask[i] + " " + ResidueProperties.aa[mask[i]]);
+    // }
+  }
+
+  public boolean isConserved(int[][] cons2, int col, int size)
+  {
+    int tot = 0;
+
+    for (int i = 0; i < mask.length; i++)
+    {
+      tot += cons2[col][mask[i]];
+    }
+
+    if ( (double) tot > ( (threshold * size) / 100))
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+  int[] setNums(String s)
+  {
+    int[] out = new int[s.length()];
+    int i = 0;
+
+    while (i < s.length())
+    {
+      out[i] = ( (Integer) ResidueProperties.aaHash.get(s.substring(i,
+          i + 1))).intValue();
+      i++;
+    }
+
+    return out;
+  }
+}
index 43ddcdc..7e00f07 100755 (executable)
@@ -1,36 +1,36 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-public class HelixColourScheme\r
-    extends ScoreColourScheme\r
-{\r
-  public HelixColourScheme()\r
-  {\r
-    super(ResidueProperties.helix, ResidueProperties.helixmin,\r
-          ResidueProperties.helixmax);\r
-  }\r
-\r
-  public Color makeColour(float c)\r
-  {\r
-    return new Color(c, (float) 1.0 - c, c);\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+import java.awt.*;
+
+public class HelixColourScheme
+    extends ScoreColourScheme
+{
+  public HelixColourScheme()
+  {
+    super(ResidueProperties.helix, ResidueProperties.helixmin,
+          ResidueProperties.helixmax);
+  }
+
+  public Color makeColour(float c)
+  {
+    return new Color(c, (float) 1.0 - c, c);
+  }
+}
index aa04a6c..e347423 100755 (executable)
@@ -1,52 +1,52 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class HydrophobicColourScheme extends ScoreColourScheme\r
-{\r
-    /**\r
-     * Creates a new HydrophobicColourScheme object.\r
-     */\r
-    public HydrophobicColourScheme()\r
-    {\r
-        super(ResidueProperties.hyd, ResidueProperties.hydmin,\r
-            ResidueProperties.hydmax);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color makeColour(float c)\r
-    {\r
-        return new Color(c, (float) 0.0, (float) 1.0 - c);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class HydrophobicColourScheme extends ScoreColourScheme
+{
+    /**
+     * Creates a new HydrophobicColourScheme object.
+     */
+    public HydrophobicColourScheme()
+    {
+        super(ResidueProperties.hyd, ResidueProperties.hydmin,
+            ResidueProperties.hydmax);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color makeColour(float c)
+    {
+        return new Color(c, (float) 0.0, (float) 1.0 - c);
+    }
+}
index 942e55b..e8382d5 100755 (executable)
@@ -1,84 +1,84 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class NucleotideColourScheme extends ResidueColourScheme\r
-{\r
-    /**\r
-     * Creates a new NucleotideColourScheme object.\r
-     */\r
-    public NucleotideColourScheme()\r
-    {\r
-        super(ResidueProperties.nucleotide, 0);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color findColour(String n)\r
-    {\r
-        // System.out.println("called"); log.debug\r
-        return colors[((Integer) (ResidueProperties.nucleotideHash.get(n))).intValue()];\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param n DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color findColour(String n, int j)\r
-    {\r
-        if ((threshold == 0) || aboveThreshold(n, j))\r
-        {\r
-            try\r
-            {\r
-                currentColour = colors[((Integer) (ResidueProperties.nucleotideHash.get(n))).intValue()];\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                return Color.white;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            return Color.white;\r
-        }\r
-\r
-        if(conservationColouring)\r
-         applyConservation(j);\r
-\r
-       return currentColour;\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class NucleotideColourScheme extends ResidueColourScheme
+{
+    /**
+     * Creates a new NucleotideColourScheme object.
+     */
+    public NucleotideColourScheme()
+    {
+        super(ResidueProperties.nucleotide, 0);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color findColour(String n)
+    {
+        // System.out.println("called"); log.debug
+        return colors[((Integer) (ResidueProperties.nucleotideHash.get(n))).intValue()];
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color findColour(String n, int j)
+    {
+        if ((threshold == 0) || aboveThreshold(n, j))
+        {
+            try
+            {
+                currentColour = colors[((Integer) (ResidueProperties.nucleotideHash.get(n))).intValue()];
+            }
+            catch (Exception ex)
+            {
+                return Color.white;
+            }
+        }
+        else
+        {
+            return Color.white;
+        }
+
+        if(conservationColouring)
+         applyConservation(j);
+
+       return currentColour;
+    }
+}
index 1575a6a..d9fd7bd 100755 (executable)
@@ -1,83 +1,83 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-import jalview.datamodel.*;\r
-\r
-public class PIDColourScheme\r
-    extends ResidueColourScheme\r
-{\r
-  public Color[] pidColours;\r
-  public float[] thresholds;\r
-  SequenceGroup group;\r
-\r
-  public PIDColourScheme()\r
-  {\r
-    this.pidColours = ResidueProperties.pidColours;\r
-    this.thresholds = ResidueProperties.pidThresholds;\r
-  }\r
-\r
-  public Color findColour(String s, int j)\r
-  {\r
-    char res = s.charAt(0);\r
-    if ('a' <= res && res <= 'z')\r
-    {\r
-      s = String.valueOf(res -= ('a' - 'A'));\r
-    }\r
-\r
-\r
-    if ( (threshold != 0) && !aboveThreshold(s, j))\r
-    {\r
-      return Color.white;\r
-    }\r
-\r
-    currentColour = Color.white;\r
-\r
-    double sc = 0;\r
-\r
-    if(consensus.length<=j)\r
-      return Color.white;\r
-\r
-      if ( (Integer.parseInt(consensus[j].get("maxCount").toString()) != -1) &&\r
-          consensus[j].contains(s))\r
-      {\r
-        sc = ( (Float) consensus[j].get(ignoreGaps)).floatValue();\r
-\r
-        if (!jalview.util.Comparison.isGap(res))\r
-        {\r
-          for (int i = 0; i < thresholds.length; i++)\r
-          {\r
-            if (sc > thresholds[i])\r
-            {\r
-              currentColour = pidColours[i];\r
-\r
-              break;\r
-            }\r
-          }\r
-        }\r
-      }\r
-\r
-    if(conservationColouring)\r
-         applyConservation(j);\r
-\r
-    return currentColour;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+import java.awt.*;
+
+import jalview.datamodel.*;
+
+public class PIDColourScheme
+    extends ResidueColourScheme
+{
+  public Color[] pidColours;
+  public float[] thresholds;
+  SequenceGroup group;
+
+  public PIDColourScheme()
+  {
+    this.pidColours = ResidueProperties.pidColours;
+    this.thresholds = ResidueProperties.pidThresholds;
+  }
+
+  public Color findColour(String s, int j)
+  {
+    char res = s.charAt(0);
+    if ('a' <= res && res <= 'z')
+    {
+      s = String.valueOf(res -= ('a' - 'A'));
+    }
+
+
+    if ( (threshold != 0) && !aboveThreshold(s, j))
+    {
+      return Color.white;
+    }
+
+    currentColour = Color.white;
+
+    double sc = 0;
+
+    if(consensus.length<=j)
+      return Color.white;
+
+      if ( (Integer.parseInt(consensus[j].get("maxCount").toString()) != -1) &&
+          consensus[j].contains(s))
+      {
+        sc = ( (Float) consensus[j].get(ignoreGaps)).floatValue();
+
+        if (!jalview.util.Comparison.isGap(res))
+        {
+          for (int i = 0; i < thresholds.length; i++)
+          {
+            if (sc > thresholds[i])
+            {
+              currentColour = pidColours[i];
+
+              break;
+            }
+          }
+        }
+      }
+
+    if(conservationColouring)
+         applyConservation(j);
+
+    return currentColour;
+  }
+}
index b83244d..add76a0 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import jalview.analysis.*;\r
-\r
-import java.awt.*;\r
-\r
-import java.util.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class ResidueColourScheme implements ColourSchemeI\r
-{\r
-\r
-    boolean conservationColouring = false;\r
-    boolean consensusColouring = false;\r
-\r
-    Color[] colors;\r
-    int threshold = 0;\r
-\r
-    /* Set when threshold colouring to either pid_gaps or pid_nogaps*/\r
-    protected String ignoreGaps = "pid_gaps";\r
-\r
-    /** Consenus as a hashtable array */\r
-    Hashtable [] consensus;\r
-\r
-    /** Conservation string as a char array */\r
-   char [] conservation;\r
-\r
-   /** DOCUMENT ME!! */\r
-   int inc = 30;\r
-\r
-   /**\r
-    * The colour to be calculated, manipulated and returned\r
-    */\r
-   Color currentColour = null;\r
-\r
-\r
-\r
-    /**\r
-     * Creates a new ResidueColourScheme object.\r
-     *\r
-     * @param colors DOCUMENT ME!\r
-     * @param threshold DOCUMENT ME!\r
-     */\r
-    public ResidueColourScheme(Color[] colours, int threshold)\r
-    {\r
-        this.colors = colours;\r
-        this.threshold = threshold;\r
-    }\r
-\r
-    /**\r
-     * Creates a new ResidueColourScheme object.\r
-     */\r
-    public ResidueColourScheme()\r
-    {\r
-    }\r
-\r
-    /**\r
-    * Find a colour without an index in a sequence\r
-    */\r
-   public Color findColour(String aa)\r
-   {\r
-       return colors[((Integer) (ResidueProperties.aaHash.get(aa))).intValue()];\r
-   }\r
-\r
-\r
-\r
-   public Color findColour(String s, int j)\r
-   {\r
-\r
-       int index = ((Integer) (ResidueProperties.aaHash.get(s))).intValue();\r
-\r
-       if ((threshold == 0) || aboveThreshold(ResidueProperties.aa[index], j))\r
-       {\r
-           currentColour = colors[index];\r
-       }\r
-       else\r
-       {\r
-           currentColour = Color.white;\r
-       }\r
-\r
-       if(conservationColouring)\r
-         applyConservation(j);\r
-\r
-\r
-       return currentColour;\r
-   }\r
-\r
-\r
-    /**\r
-     * Get the percentage threshold for this colour scheme\r
-     *\r
-     * @return Returns the percentage threshold\r
-     */\r
-    public int getThreshold()\r
-    {\r
-        return threshold;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param ct DOCUMENT ME!\r
-     */\r
-    public void setThreshold(int ct, boolean ignoreGaps)\r
-    {\r
-        threshold = ct;\r
-        if(ignoreGaps)\r
-          this.ignoreGaps = "pid_nogaps";\r
-        else\r
-          this.ignoreGaps = "pid_gaps";\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public boolean aboveThreshold(String s, int j)\r
-    {\r
-        if ((((Integer) consensus[j].get("maxCount")).intValue() != -1) &&\r
-                consensus[j].contains(s))\r
-        {\r
-            if (((Float)consensus[j].get(ignoreGaps)).floatValue() >= threshold)\r
-            {\r
-                return true;\r
-            }\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-\r
-    public boolean conservationApplied()\r
-    {\r
-      return conservationColouring;\r
-    }\r
-\r
-    public void setConservationInc(int i)\r
-    {\r
-      inc = i;\r
-    }\r
-\r
-    public int getConservationInc()\r
-    {\r
-      return inc;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param consensus DOCUMENT ME!\r
-     */\r
-    public void setConsensus(Vector vconsensus)\r
-    {\r
-      if(vconsensus==null)\r
-        return;\r
-\r
-       int i, iSize=vconsensus.size();\r
-       consensus = new Hashtable[iSize];\r
-       for(i=0; i<iSize; i++)\r
-        consensus[i] = (Hashtable)vconsensus.elementAt(i);\r
-    }\r
-\r
-\r
-    public void setConservation(Conservation cons)\r
-    {\r
-      if(cons==null)\r
-      {\r
-        conservationColouring = false;\r
-        conservation = null;\r
-      }\r
-      else\r
-      {\r
-        conservationColouring = true;\r
-        int i, iSize = cons.getConsSequence().getLength();\r
-        conservation = new char[iSize];\r
-        for (i = 0; i < iSize; i++)\r
-          conservation[i] = cons.getConsSequence().getCharAt(i);\r
-      }\r
-\r
-    }\r
-\r
-\r
-    /**\r
-    * DOCUMENT ME!\r
-    *\r
-    * @param s DOCUMENT ME!\r
-    * @param i DOCUMENT ME!\r
-    *\r
-    * @return DOCUMENT ME!\r
-    */\r
-\r
-   void applyConservation(int i)\r
-   {\r
-\r
-     if ((conservation[i] != '*') && (conservation[i] != '+'))\r
-     {\r
-       if(jalview.util.Comparison.isGap(conservation[i]))\r
-       {\r
-         currentColour = Color.white;\r
-       }\r
-       else\r
-       {\r
-         float t = 11 - (conservation[i] - '0');\r
-         if(t==0)\r
-         {\r
-           currentColour = Color.white;\r
-           return;\r
-         }\r
-\r
-         int red = currentColour.getRed();\r
-         int green = currentColour.getGreen();\r
-         int blue = currentColour.getBlue();\r
-\r
-         int dr = 255 - red;\r
-         int dg = 255 - green;\r
-         int db = 255 - blue;\r
-\r
-         dr *= t / 10f;\r
-         dg *= t / 10f;\r
-         db *= t / 10f;\r
-\r
-         red += (inc / 20f) * dr;\r
-         green += (inc / 20f) * dg;\r
-         blue += (inc / 20f) * db;\r
-\r
-         if (red > 255 || green > 255 || blue > 255)\r
-           currentColour = Color.white;\r
-         else\r
-           currentColour = new Color(red, green, blue);\r
-       }\r
-       }\r
-   }\r
-\r
-\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import jalview.analysis.*;
+
+import java.awt.*;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ResidueColourScheme implements ColourSchemeI
+{
+
+    boolean conservationColouring = false;
+    boolean consensusColouring = false;
+
+    Color[] colors;
+    int threshold = 0;
+
+    /* Set when threshold colouring to either pid_gaps or pid_nogaps*/
+    protected String ignoreGaps = "pid_gaps";
+
+    /** Consenus as a hashtable array */
+    Hashtable [] consensus;
+
+    /** Conservation string as a char array */
+   char [] conservation;
+
+   /** DOCUMENT ME!! */
+   int inc = 30;
+
+   /**
+    * The colour to be calculated, manipulated and returned
+    */
+   Color currentColour = null;
+
+
+
+    /**
+     * Creates a new ResidueColourScheme object.
+     *
+     * @param colors DOCUMENT ME!
+     * @param threshold DOCUMENT ME!
+     */
+    public ResidueColourScheme(Color[] colours, int threshold)
+    {
+        this.colors = colours;
+        this.threshold = threshold;
+    }
+
+    /**
+     * Creates a new ResidueColourScheme object.
+     */
+    public ResidueColourScheme()
+    {
+    }
+
+    /**
+    * Find a colour without an index in a sequence
+    */
+   public Color findColour(String aa)
+   {
+       return colors[((Integer) (ResidueProperties.aaHash.get(aa))).intValue()];
+   }
+
+
+
+   public Color findColour(String s, int j)
+   {
+
+       int index = ((Integer) (ResidueProperties.aaHash.get(s))).intValue();
+
+       if ((threshold == 0) || aboveThreshold(ResidueProperties.aa[index], j))
+       {
+           currentColour = colors[index];
+       }
+       else
+       {
+           currentColour = Color.white;
+       }
+
+       if(conservationColouring)
+         applyConservation(j);
+
+
+       return currentColour;
+   }
+
+
+    /**
+     * Get the percentage threshold for this colour scheme
+     *
+     * @return Returns the percentage threshold
+     */
+    public int getThreshold()
+    {
+        return threshold;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param ct DOCUMENT ME!
+     */
+    public void setThreshold(int ct, boolean ignoreGaps)
+    {
+        threshold = ct;
+        if(ignoreGaps)
+          this.ignoreGaps = "pid_nogaps";
+        else
+          this.ignoreGaps = "pid_gaps";
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean aboveThreshold(String s, int j)
+    {
+        if ((((Integer) consensus[j].get("maxCount")).intValue() != -1) &&
+                consensus[j].contains(s))
+        {
+            if (((Float)consensus[j].get(ignoreGaps)).floatValue() >= threshold)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    public boolean conservationApplied()
+    {
+      return conservationColouring;
+    }
+
+    public void setConservationInc(int i)
+    {
+      inc = i;
+    }
+
+    public int getConservationInc()
+    {
+      return inc;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param consensus DOCUMENT ME!
+     */
+    public void setConsensus(Vector vconsensus)
+    {
+      if(vconsensus==null)
+        return;
+
+       int i, iSize=vconsensus.size();
+       consensus = new Hashtable[iSize];
+       for(i=0; i<iSize; i++)
+        consensus[i] = (Hashtable)vconsensus.elementAt(i);
+    }
+
+
+    public void setConservation(Conservation cons)
+    {
+      if(cons==null)
+      {
+        conservationColouring = false;
+        conservation = null;
+      }
+      else
+      {
+        conservationColouring = true;
+        int i, iSize = cons.getConsSequence().getLength();
+        conservation = new char[iSize];
+        for (i = 0; i < iSize; i++)
+          conservation[i] = cons.getConsSequence().getCharAt(i);
+      }
+
+    }
+
+
+    /**
+    * DOCUMENT ME!
+    *
+    * @param s DOCUMENT ME!
+    * @param i DOCUMENT ME!
+    *
+    * @return DOCUMENT ME!
+    */
+
+   void applyConservation(int i)
+   {
+
+     if ((conservation[i] != '*') && (conservation[i] != '+'))
+     {
+       if(jalview.util.Comparison.isGap(conservation[i]))
+       {
+         currentColour = Color.white;
+       }
+       else
+       {
+         float t = 11 - (conservation[i] - '0');
+         if(t==0)
+         {
+           currentColour = Color.white;
+           return;
+         }
+
+         int red = currentColour.getRed();
+         int green = currentColour.getGreen();
+         int blue = currentColour.getBlue();
+
+         int dr = 255 - red;
+         int dg = 255 - green;
+         int db = 255 - blue;
+
+         dr *= t / 10f;
+         dg *= t / 10f;
+         db *= t / 10f;
+
+         red += (inc / 20f) * dr;
+         green += (inc / 20f) * dg;
+         blue += (inc / 20f) * db;
+
+         if (red > 255 || green > 255 || blue > 255)
+           currentColour = Color.white;
+         else
+           currentColour = new Color(red, green, blue);
+       }
+       }
+   }
+
+
+}
index 65cc0f1..88f6c79 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-\r
-public class ResidueProperties\r
-{\r
-  //Stores residue codes/names and colours and other things\r
-  public static final Hashtable aaHash = new Hashtable(); // stores the number value of the aa\r
-  public static final Hashtable aa3Hash = new Hashtable();\r
-  public static final Hashtable aa2Triplet = new Hashtable();\r
-  public static final Hashtable nucleotideHash = new Hashtable();\r
-  public static final Hashtable nucleotideName = new Hashtable();\r
-\r
-  static\r
-  {\r
-    aaHash.put("A", new Integer(0));\r
-    aaHash.put("R", new Integer(1));\r
-    aaHash.put("N", new Integer(2));\r
-    aaHash.put("D", new Integer(3));\r
-    aaHash.put("C", new Integer(4));\r
-    aaHash.put("Q", new Integer(5));\r
-    aaHash.put("E", new Integer(6));\r
-    aaHash.put("G", new Integer(7));\r
-    aaHash.put("H", new Integer(8));\r
-    aaHash.put("I", new Integer(9));\r
-    aaHash.put("L", new Integer(10));\r
-    aaHash.put("K", new Integer(11));\r
-    aaHash.put("M", new Integer(12));\r
-    aaHash.put("F", new Integer(13));\r
-    aaHash.put("P", new Integer(14));\r
-    aaHash.put("S", new Integer(15));\r
-    aaHash.put("T", new Integer(16));\r
-    aaHash.put("W", new Integer(17));\r
-    aaHash.put("Y", new Integer(18));\r
-    aaHash.put("V", new Integer(19));\r
-    aaHash.put("B", new Integer(20));\r
-    aaHash.put("Z", new Integer(21));\r
-    aaHash.put("X", new Integer(22));\r
-    aaHash.put("U", new Integer(22));\r
-    aaHash.put("a", new Integer(0));\r
-    aaHash.put("r", new Integer(1));\r
-    aaHash.put("n", new Integer(2));\r
-    aaHash.put("d", new Integer(3));\r
-    aaHash.put("c", new Integer(4));\r
-    aaHash.put("q", new Integer(5));\r
-    aaHash.put("e", new Integer(6));\r
-    aaHash.put("g", new Integer(7));\r
-    aaHash.put("h", new Integer(8));\r
-    aaHash.put("i", new Integer(9));\r
-    aaHash.put("l", new Integer(10));\r
-    aaHash.put("k", new Integer(11));\r
-    aaHash.put("m", new Integer(12));\r
-    aaHash.put("f", new Integer(13));\r
-    aaHash.put("p", new Integer(14));\r
-    aaHash.put("s", new Integer(15));\r
-    aaHash.put("t", new Integer(16));\r
-    aaHash.put("w", new Integer(17));\r
-    aaHash.put("y", new Integer(18));\r
-    aaHash.put("v", new Integer(19));\r
-    aaHash.put("b", new Integer(20));\r
-    aaHash.put("z", new Integer(21));\r
-    aaHash.put("x", new Integer(22));\r
-    aaHash.put("u", new Integer(22));\r
-    aaHash.put("-", new Integer(23));\r
-    aaHash.put("*", new Integer(23));\r
-    aaHash.put(".", new Integer(23));\r
-    aaHash.put(" ", new Integer(23));\r
-  }\r
-\r
-  static\r
-  {\r
-    nucleotideHash.put("A", new Integer(0));\r
-    nucleotideHash.put("a", new Integer(0));\r
-    nucleotideHash.put("C", new Integer(1));\r
-    nucleotideHash.put("c", new Integer(1));\r
-    nucleotideHash.put("G", new Integer(2));\r
-    nucleotideHash.put("g", new Integer(2));\r
-    nucleotideHash.put("T", new Integer(3));\r
-    nucleotideHash.put("t", new Integer(3));\r
-    nucleotideHash.put("U", new Integer(4));\r
-    nucleotideHash.put("u", new Integer(4));\r
-    nucleotideHash.put("I", new Integer(5));\r
-    nucleotideHash.put("i", new Integer(5));\r
-    nucleotideHash.put("X", new Integer(6));\r
-    nucleotideHash.put("x", new Integer(6));\r
-    nucleotideHash.put("R", new Integer(7));\r
-    nucleotideHash.put("r", new Integer(7));\r
-    nucleotideHash.put("Y", new Integer(8));\r
-    nucleotideHash.put("y", new Integer(8));\r
-    nucleotideHash.put("N", new Integer(9));\r
-    nucleotideHash.put("n", new Integer(9));\r
-\r
-\r
-    nucleotideName.put("A", "Adenine");\r
-    nucleotideName.put("a", "Adenine");\r
-    nucleotideName.put("G", "Guanine");\r
-    nucleotideName.put("g", "Guanine");\r
-    nucleotideName.put("C", "Cytosine");\r
-    nucleotideName.put("c", "Cytosine");\r
-    nucleotideName.put("T", "Thymine");\r
-    nucleotideName.put("t", "Thymine");\r
-    nucleotideName.put("U", "Uracil");\r
-    nucleotideName.put("u", "Uracil");\r
-    nucleotideName.put("I", "Inosine");\r
-    nucleotideName.put("i", "Inosine");\r
-    nucleotideName.put("X", "Xanthine");\r
-    nucleotideName.put("x", "Xanthine");\r
-    nucleotideName.put("R", "Unknown Purine");\r
-    nucleotideName.put("r", "Unknown Purine");\r
-    nucleotideName.put("Y", "Unknown Pyrimidine");\r
-    nucleotideName.put("y", "Unknown Pyrimidine");\r
-    nucleotideName.put("N", "Unknown");\r
-    nucleotideName.put("n", "Unknown");\r
-  }\r
-\r
-\r
-  static\r
-  {\r
-    aa3Hash.put("ALA", new Integer(0));\r
-    aa3Hash.put("ARG", new Integer(1));\r
-    aa3Hash.put("ASN", new Integer(2));\r
-    aa3Hash.put("ASP", new Integer(3)); //D\r
-    aa3Hash.put("CYS", new Integer(4));\r
-    aa3Hash.put("GLN", new Integer(5)); //Q\r
-    aa3Hash.put("GLU", new Integer(6)); // E\r
-    aa3Hash.put("GLY", new Integer(7));\r
-    aa3Hash.put("HIS", new Integer(8));\r
-    aa3Hash.put("ILE", new Integer(9));\r
-    aa3Hash.put("LEU", new Integer(10));\r
-    aa3Hash.put("LYS", new Integer(11));\r
-    aa3Hash.put("MET", new Integer(12));\r
-    aa3Hash.put("PHE", new Integer(13));\r
-    aa3Hash.put("PRO", new Integer(14));\r
-    aa3Hash.put("SER", new Integer(15));\r
-    aa3Hash.put("THR", new Integer(16));\r
-    aa3Hash.put("TRP", new Integer(17));\r
-    aa3Hash.put("TYR", new Integer(18));\r
-    aa3Hash.put("VAL", new Integer(19));\r
-    // IUB Nomenclature for ambiguous peptides\r
-    aa3Hash.put("ASX", new Integer(20)); // "B";\r
-    aa3Hash.put("GLX", new Integer(21)); // X\r
-    aa3Hash.put("XAA", new Integer(22));// X unknown\r
-    aa3Hash.put("-", new Integer(23));\r
-    aa3Hash.put("*", new Integer(23));\r
-    aa3Hash.put(".", new Integer(23));\r
-    aa3Hash.put(" ", new Integer(23));\r
-  }\r
-\r
-  static\r
-  {\r
-    aa2Triplet.put("A", "ALA");\r
-    aa2Triplet.put("a", "ALA");\r
-    aa2Triplet.put("R", "ARG");\r
-    aa2Triplet.put("r", "ARG");\r
-    aa2Triplet.put("N", "ASN");\r
-    aa2Triplet.put("n", "ASN");\r
-    aa2Triplet.put("D", "ASP");\r
-    aa2Triplet.put("d", "ASP");\r
-    aa2Triplet.put("C", "CYS");\r
-    aa2Triplet.put("c", "CYS");\r
-    aa2Triplet.put("Q", "GLN");\r
-    aa2Triplet.put("q", "GLN");\r
-    aa2Triplet.put("E", "GLU");\r
-    aa2Triplet.put("e", "GLU");\r
-    aa2Triplet.put("G", "GLY");\r
-    aa2Triplet.put("g", "GLY");\r
-    aa2Triplet.put("H", "HIS");\r
-    aa2Triplet.put("h", "HIS");\r
-    aa2Triplet.put("I", "ILE");\r
-    aa2Triplet.put("i", "ILE");\r
-    aa2Triplet.put("L", "LEU");\r
-    aa2Triplet.put("l", "LEU");\r
-    aa2Triplet.put("K", "LYS");\r
-    aa2Triplet.put("k", "LYS");\r
-    aa2Triplet.put("M", "MET");\r
-    aa2Triplet.put("m", "MET");\r
-    aa2Triplet.put("F", "PHE");\r
-    aa2Triplet.put("f", "PHE");\r
-    aa2Triplet.put("P", "PRO");\r
-    aa2Triplet.put("p", "PRO");\r
-    aa2Triplet.put("S", "SER");\r
-    aa2Triplet.put("s", "SER");\r
-    aa2Triplet.put("T", "THR");\r
-    aa2Triplet.put("t", "THR");\r
-    aa2Triplet.put("W", "TRP");\r
-    aa2Triplet.put("w", "TRP");\r
-    aa2Triplet.put("Y", "TYR");\r
-    aa2Triplet.put("y", "TYR");\r
-    aa2Triplet.put("V", "VAL");\r
-    aa2Triplet.put("v", "VAL");\r
-  }\r
-\r
-  public static final String[] aa =\r
-      {\r
-      "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I", "L", "K", "M", "F",\r
-      "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "_", "*", ".", " "\r
-  };\r
-  public static final Color midBlue = new Color(100, 100, 255);\r
-  public static final Vector scaleColours = new Vector();\r
-\r
-  static\r
-  {\r
-    scaleColours.addElement(new Color(114, 0, 147));\r
-    scaleColours.addElement(new Color(156, 0, 98));\r
-    scaleColours.addElement(new Color(190, 0, 0));\r
-    scaleColours.addElement(Color.red);\r
-    scaleColours.addElement(new Color(255, 125, 0));\r
-    scaleColours.addElement(Color.orange);\r
-    scaleColours.addElement(new Color(255, 194, 85));\r
-    scaleColours.addElement(Color.yellow);\r
-    scaleColours.addElement(new Color(255, 255, 181));\r
-    scaleColours.addElement(Color.white);\r
-  }\r
-\r
-  public static final Color[] taylor =\r
-      {\r
-      new Color(204, 255, 0), // A  Greenish-yellowy-yellow\r
-      new Color(0, 0, 255), // R  Blueish-bluey-blue\r
-      new Color(204, 0, 255), // N  Blueish-reddy-blue\r
-      new Color(255, 0, 0), // D  Reddish-reddy-red\r
-      new Color(255, 255, 0), // C  Yellowish-yellowy-yellow\r
-      new Color(255, 0, 204), // Q  Reddish-bluey-red\r
-      new Color(255, 0, 102), // E  Blueish-reddy-red\r
-      new Color(255, 153, 0), // G  Yellowy-reddy-yellow\r
-      new Color(0, 102, 255), // H  Greenish-bluey-blue\r
-      new Color(102, 255, 0), // I  Greenish-yellowy-green\r
-      new Color(51, 255, 0), // L  Yellowish-greeny-green\r
-      new Color(102, 0, 255), // K  Reddish-bluey-blue\r
-      new Color(0, 255, 0), // M  Greenish-greeny-green\r
-      new Color(0, 255, 102), // F  Blueish-greeny-green\r
-      new Color(255, 204, 0), // P  Reddish-yellowy-yellow\r
-      new Color(255, 51, 0), // S  Yellowish-reddy-red\r
-      new Color(255, 102, 0), // T  Reddish-yellowy-red\r
-      new Color(0, 204, 255), // W  Blueish-greeny-green\r
-      new Color(0, 255, 204), // Y  Greenish-bluey-green\r
-      new Color(153, 255, 0), // V  Yellowish-greeny-yellow\r
-      Color.white, // B\r
-      Color.white, // Z\r
-      Color.white, // X\r
-      Color.white, // -\r
-      Color.white, // *\r
-      Color.white // .\r
-  };\r
-  public static final Color[] nucleotide =\r
-      {\r
-      new Color(100, 247, 63), // A\r
-      new Color(255, 179, 64), // C\r
-      new Color(235, 65, 60), // G\r
-      new Color(60, 136, 238), // T\r
-      new Color(60, 136, 238) // U\r
-  };\r
-  public static final Color[] color =\r
-      {\r
-      Color.pink, // A\r
-      midBlue, // R\r
-      Color.green, // N\r
-      Color.red, // D\r
-      Color.yellow, // C\r
-      Color.green, // Q\r
-      Color.red, // E\r
-      Color.magenta, // G\r
-      Color.red, // H\r
-      Color.pink, // I\r
-      Color.pink, // L\r
-      midBlue, // K\r
-      Color.pink, // M\r
-      Color.orange, // F\r
-      Color.magenta, // P\r
-      Color.green, // S\r
-      Color.green, // T\r
-      Color.orange, // W\r
-      Color.orange, // Y\r
-      Color.pink, // V\r
-      Color.white, // B\r
-      Color.white, // Z\r
-      Color.white, // X\r
-      Color.white, // -\r
-      Color.white, // *\r
-      Color.white, // .\r
-      Color.white // ' '\r
-  };\r
-\r
-  // Dunno where I got these numbers from\r
-  public static final double[] hyd2 =\r
-      {\r
-      0.62, //A\r
-      0.29, //R\r
-      -0.90, //N\r
-      -0.74, //D\r
-      1.19, //C\r
-      0.48, //Q\r
-      -0.40, //E\r
-      1.38, //G\r
-      -1.50, //H\r
-      1.06, //I\r
-      0.64, //L\r
-      -0.78, //K\r
-      0.12, //M\r
-      -0.85, //F\r
-      -2.53, //P\r
-      -0.18, //S\r
-      -0.05, //T\r
-      1.08, //W\r
-      0.81, //Y\r
-      0.0, //V\r
-      0.26, //B\r
-      0.0, //Z\r
-      0.0 //X\r
-  };\r
-  public static final double[] helix =\r
-      {\r
-      1.42, 0.98, 0.67, 1.01, 0.70, 1.11, 1.51, 0.57, 1.00, 1.08, 1.21, 1.16,\r
-      1.45, 1.13, 0.57, 0.77, 0.83, 1.08, 0.69, 1.06, 0.84, 1.31, 1.00, 0.0\r
-  };\r
-  public static final double helixmin = 0.57;\r
-  public static final double helixmax = 1.51;\r
-  public static final double[] strand =\r
-      {\r
-      0.83, 0.93, 0.89, 0.54, 1.19, 1.10, 0.37, 0.75, 0.87, 1.60, 1.30, 0.74,\r
-      1.05, 1.38, 0.55, 0.75, 1.19, 1.37, 1.47, 1.70, 0.72, 0.74, 1.0, 0.0\r
-  };\r
-  public static final double strandmin = 0.37;\r
-  public static final double strandmax = 1.7;\r
-  public static final double[] turn =\r
-      {\r
-      0.66, 0.95, 1.56, 1.46, 1.19, 0.98, 0.74, 1.56, 0.95, 0.47, 0.59, 1.01,\r
-      0.60, 0.60, 1.52, 1.43, 0.96, 0.96, 1.14, 0.50, 1.51, 0.86, 1.00, 0, 0\r
-  };\r
-  public static final double turnmin = 0.47;\r
-  public static final double turnmax = 1.56;\r
-  public static final double[] buried =\r
-      {\r
-      1.7, 0.1, 0.4, 0.4, 4.6, 0.3, 0.3, 1.8, 0.8, 3.1, 2.4, 0.05, 1.9, 2.2,\r
-      0.6, 0.8, 0.7, 1.6, 0.5, 2.9, 0.4, 0.3, 1.358, 0.00\r
-  };\r
-  public static final double buriedmin = 0.05;\r
-  public static final double buriedmax = 4.6;\r
-\r
-  // This is hydropathy index\r
-  // Kyte, J., and Doolittle, R.F., J. Mol. Biol.\r
-  // 1157, 105-132, 1982\r
-  public static final double[] hyd =\r
-      {\r
-      1.8, -4.5, -3.5, -3.5, 2.5, -3.5, -3.5, -0.4, -3.2, 4.5, 3.8, -3.9, 1.9,\r
-      2.8, -1.6, -0.8, -0.7, -0.9, -1.3, 4.2, -3.5, -3.5, -0.49, 0.0\r
-  };\r
-  public static final double hydmax = 4.5;\r
-  public static final double hydmin = -3.9;\r
-\r
-  //public static final double hydmax = 1.38;\r
-  //public static final double hydmin = -2.53;\r
-  static final int[][] BLOSUM62 =\r
-      {\r
-      {\r
-      4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3,\r
-      -2, 0, -2, -1, 0, -4\r
-  },\r
-      {\r
-      -1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3, -2,\r
-      -3, -1, 0, -1, -4\r
-  },\r
-      {\r
-      -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2, -3,\r
-      3, 0, -1, -4\r
-  },\r
-      {\r
-      -2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4,\r
-      -3, -3, 4, 1, -1, -4\r
-  },\r
-      {\r
-      0, 3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2,\r
-      -2, -1, -3, -3, -2, -4\r
-  },\r
-      {\r
-      -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1,\r
-      -2, 0, 3, -1, -4\r
-  },\r
-      {\r
-      -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2,\r
-      -2, 1, 4, -1, -4\r
-  },\r
-      {\r
-      0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2,\r
-      -3, -3, -1, -2, -1, -4\r
-  },\r
-      {\r
-      -2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2, 2,\r
-      -3, 0, 0, -1, -4\r
-  },\r
-      {\r
-      -1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3,\r
-      -1, 3, -3, -3, -1, -4\r
-  },\r
-      {\r
-      -1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2,\r
-      -1, 1, -4, -3, -1, -4\r
-  },\r
-      {\r
-      -1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3, -2,\r
-      -2, 0, 1, -1, -4\r
-  },\r
-      {\r
-      -1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1,\r
-      -1, 1, -3, -1, -1, -4\r
-  },\r
-      {\r
-      -2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1, 3,\r
-      -1, -3, -3, -1, -4\r
-  },\r
-      {\r
-      -1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1,\r
-      -4, -3, -2, -2, -1, -2, -4\r
-  },\r
-      {\r
-      1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2,\r
-      -2, 0, 0, 0, -4\r
-  },\r
-      {\r
-      0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2,\r
-      -2, 0, -1, -1, 0, -4\r
-  },\r
-      {\r
-      -3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2,\r
-      11, 2, -3, -4, -3, -2, -4\r
-  },\r
-      {\r
-      -2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2, 2,\r
-      7, -1, -3, -2, -1, -4\r
-  },\r
-      {\r
-      0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3,\r
-      -1, 4, -3, -2, -1, -4\r
-  },\r
-      {\r
-      -2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4, -3,\r
-      -3, 4, 1, -1, -4\r
-  },\r
-      {\r
-      -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2,\r
-      -2, 1, 4, -1, -4\r
-  },\r
-      {\r
-      0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0, -2,\r
-      -1, -1, -1, -1, -1, -4\r
-  },\r
-      {\r
-      -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,\r
-      -4, -4, -4, -4, -4, -4, 1\r
-  },\r
-  };\r
-  static final int[][] PAM250 =\r
-      {\r
-      {\r
-      2, -2, 0, 0, -2, 0, 0, 1, -1, -1, -2, -1, -1, -3, 1, 1, 1, -6, -3, 0,\r
-      0, 0, 0, -8\r
-  },\r
-      {\r
-      -2, 6, 0, -1, -4, 1, -1, -3, 2, -2, -3, 3, 0, -4, 0, 0, -1, 2, -4,\r
-      -2, -1, 0, -1, -8\r
-  },\r
-      {\r
-      0, 0, 2, 2, -4, 1, 1, 0, 2, -2, -3, 1, -2, -3, 0, 1, 0, -4, -2, -2,\r
-      2, 1, 0, -8\r
-  },\r
-      {\r
-      0, -1, 2, 4, -5, 2, 3, 1, 1, -2, -4, 0, -3, -6, -1, 0, 0, -7, -4, -2,\r
-      3, 3, -1, -8\r
-  },\r
-      {\r
-      -2, -4, -4, -5, 12, -5, -5, -3, -3, -2, -6, -5, -5, -4, -3, 0, -2,\r
-      -8, 0, -2, -4, -5, -3, -8\r
-  },\r
-      {\r
-      0, 1, 1, 2, -5, 4, 2, -1, 3, -2, -2, 1, -1, -5, 0, -1, -1, -5, -4,\r
-      -2, 1, 3, -1, -8\r
-  },\r
-      {\r
-      0, -1, 1, 3, -5, 2, 4, 0, 1, -2, -3, 0, -2, -5, -1, 0, 0, -7, -4, -2,\r
-      3, 3, -1, -8\r
-  },\r
-      {\r
-      1, -3, 0, 1, -3, -1, 0, 5, -2, -3, -4, -2, -3, -5, 0, 1, 0, -7, -5,\r
-      -1, 0, 0, -1, -8\r
-  },\r
-      {\r
-      -1, 2, 2, 1, -3, 3, 1, -2, 6, -2, -2, 0, -2, -2, 0, -1, -1, -3, 0,\r
-      -2, 1, 2, -1, -8\r
-  },\r
-      {\r
-      -1, -2, -2, -2, -2, -2, -2, -3, -2, 5, 2, -2, 2, 1, -2, -1, 0, -5,\r
-      -1, 4, -2, -2, -1, -8\r
-  },\r
-      {\r
-      -2, -3, -3, -4, -6, -2, -3, -4, -2, 2, 6, -3, 4, 2, -3, -3, -2, -2,\r
-      -1, 2, -3, -3, -1, -8\r
-  },\r
-      {\r
-      -1, 3, 1, 0, -5, 1, 0, -2, 0, -2, -3, 5, 0, -5, -1, 0, 0, -3, -4, -2,\r
-      1, 0, -1, -8\r
-  },\r
-      {\r
-      -1, 0, -2, -3, -5, -1, -2, -3, -2, 2, 4, 0, 6, 0, -2, -2, -1, -4, -2,\r
-      2, -2, -2, -1, -8\r
-  },\r
-      {\r
-      -3, -4, -3, -6, -4, -5, -5, -5, -2, 1, 2, -5, 0, 9, -5, -3, -3, 0, 7,\r
-      -1, -4, -5, -2, -8\r
-  },\r
-      {\r
-      1, 0, 0, -1, -3, 0, -1, 0, 0, -2, -3, -1, -2, -5, 6, 1, 0, -6, -5,\r
-      -1, -1, 0, -1, -8\r
-  },\r
-      {\r
-      1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -3, 0, -2, -3, 1, 2, 1, -2, -3, -1,\r
-      0, 0, 0, -8\r
-  },\r
-      {\r
-      1, -1, 0, 0, -2, -1, 0, 0, -1, 0, -2, 0, -1, -3, 0, 1, 3, -5, -3, 0,\r
-      0, -1, 0, -8\r
-  },\r
-      {\r
-      -6, 2, -4, -7, -8, -5, -7, -7, -3, -5, -2, -3, -4, 0, -6, -2, -5, 17,\r
-      0, -6, -5, -6, -4, -8\r
-  },\r
-      {\r
-      -3, -4, -2, -4, 0, -4, -4, -5, 0, -1, -1, -4, -2, 7, -5, -3, -3, 0,\r
-      10, -2, -3, -4, -2, -8\r
-  },\r
-      {\r
-      0, -2, -2, -2, -2, -2, -2, -1, -2, 4, 2, -2, 2, -1, -1, -1, 0, -6,\r
-      -2, 4, -2, -2, -1, -8\r
-  },\r
-      {\r
-      0, -1, 2, 3, -4, 1, 3, 0, 1, -2, -3, 1, -2, -4, -1, 0, 0, -5, -3, -2,\r
-      3, 2, -1, -8\r
-  },\r
-      {\r
-      0, 0, 1, 3, -5, 3, 3, 0, 2, -2, -3, 0, -2, -5, 0, 0, -1, -6, -4, -2,\r
-      2, 3, -1, -8\r
-  },\r
-      {\r
-      0, -1, 0, -1, -3, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, 0, 0, -4,\r
-      -2, -1, -1, -1, -1, -8\r
-  },\r
-      {\r
-      -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,\r
-      -8, -8, -8, -8, -8, -8, 1\r
-  },\r
-  };\r
-  public static final Hashtable ssHash = new Hashtable(); // stores the number value of the aa\r
-\r
-  static\r
-  {\r
-    ssHash.put("H", Color.magenta);\r
-    ssHash.put("E", Color.yellow);\r
-    ssHash.put("-", Color.white);\r
-    ssHash.put(".", Color.white);\r
-    ssHash.put("S", Color.cyan);\r
-    ssHash.put("T", Color.blue);\r
-    ssHash.put("G", Color.pink);\r
-    ssHash.put("I", Color.pink);\r
-    ssHash.put("B", Color.yellow);\r
-  }\r
-\r
-  static final int[][] DNA =\r
-      {\r
-      {\r
-      5, -4, -4, -4, 1}, // C\r
-      {\r
-      -4, 5, -4, -4, 1}, // T\r
-      {\r
-      -4, -4, 5, -4, 1}, // A\r
-      {\r
-      -4, -4, -4, 5, 1}, // G\r
-      {\r
-      1, 1, 1, 1, 1}, // -\r
-  };\r
-  public static final Color[] pidColours =\r
-      {\r
-      midBlue, new Color(153, 153, 255),\r
-      //    Color.lightGray,\r
-      new Color(204, 204, 255),\r
-  };\r
-  public static final float[] pidThresholds =\r
-      {\r
-      80, 60, 40, };\r
-  public static Hashtable codonHash = new Hashtable();\r
-  public static Vector Lys = new Vector();\r
-  public static Vector Asn = new Vector();\r
-  public static Vector Gln = new Vector();\r
-  public static Vector His = new Vector();\r
-  public static Vector Glu = new Vector();\r
-  public static Vector Asp = new Vector();\r
-  public static Vector Tyr = new Vector();\r
-  public static Vector Thr = new Vector();\r
-  public static Vector Pro = new Vector();\r
-  public static Vector Ala = new Vector();\r
-  public static Vector Ser = new Vector();\r
-  public static Vector Arg = new Vector();\r
-  public static Vector Gly = new Vector();\r
-  public static Vector Trp = new Vector();\r
-  public static Vector Cys = new Vector();\r
-  public static Vector Ile = new Vector();\r
-  public static Vector Met = new Vector();\r
-  public static Vector Leu = new Vector();\r
-  public static Vector Val = new Vector();\r
-  public static Vector Phe = new Vector();\r
-  public static Vector STOP = new Vector();\r
-\r
-  static\r
-  {\r
-    codonHash.put("K", Lys);\r
-    codonHash.put("N", Asn);\r
-    codonHash.put("Q", Gln);\r
-    codonHash.put("H", His);\r
-    codonHash.put("E", Glu);\r
-    codonHash.put("D", Asp);\r
-    codonHash.put("Y", Tyr);\r
-    codonHash.put("T", Thr);\r
-    codonHash.put("P", Pro);\r
-    codonHash.put("A", Ala);\r
-    codonHash.put("S", Ser);\r
-    codonHash.put("R", Arg);\r
-    codonHash.put("G", Gly);\r
-    codonHash.put("W", Trp);\r
-    codonHash.put("C", Cys);\r
-    codonHash.put("I", Ile);\r
-    codonHash.put("M", Met);\r
-    codonHash.put("L", Leu);\r
-    codonHash.put("V", Val);\r
-    codonHash.put("F", Phe);\r
-    codonHash.put("STOP", STOP);\r
-  }\r
-\r
-  public static Hashtable codonHash2 = new Hashtable();\r
-\r
-  static\r
-  {\r
-    codonHash2.put("AAA", "K");\r
-    codonHash2.put("AAG", "K");\r
-    codonHash2.put("AAC", "N");\r
-    codonHash2.put("AAT", "N");\r
-\r
-    codonHash2.put("CAA", "E");\r
-    codonHash2.put("CAG", "E");\r
-    codonHash2.put("CAC", "H");\r
-    codonHash2.put("CAT", "H");\r
-\r
-    codonHash2.put("GAA", "Q");\r
-    codonHash2.put("GAG", "Q");\r
-    codonHash2.put("GAC", "D");\r
-    codonHash2.put("GAT", "D");\r
-\r
-    codonHash2.put("TAC", "Y");\r
-    codonHash2.put("TAT", "Y");\r
-\r
-    codonHash2.put("ACA", "T");\r
-    codonHash2.put("AAG", "T");\r
-    codonHash2.put("ACC", "T");\r
-    codonHash2.put("ACT", "T");\r
-\r
-    codonHash2.put("CCA", "P");\r
-    codonHash2.put("CCG", "P");\r
-    codonHash2.put("CCC", "P");\r
-    codonHash2.put("CCT", "P");\r
-\r
-    codonHash2.put("GCA", "A");\r
-    codonHash2.put("GCG", "A");\r
-    codonHash2.put("GCC", "A");\r
-    codonHash2.put("GCT", "A");\r
-\r
-    codonHash2.put("TCA", "S");\r
-    codonHash2.put("TCG", "S");\r
-    codonHash2.put("TCC", "S");\r
-    codonHash2.put("TCT", "S");\r
-    codonHash2.put("AGC", "S");\r
-    codonHash2.put("AGT", "S");\r
-\r
-    codonHash2.put("AGA", "R");\r
-    codonHash2.put("AGG", "R");\r
-    codonHash2.put("CGA", "R");\r
-    codonHash2.put("CGG", "R");\r
-    codonHash2.put("CGC", "R");\r
-    codonHash2.put("CGT", "R");\r
-\r
-    codonHash2.put("GGA", "G");\r
-    codonHash2.put("GGG", "G");\r
-    codonHash2.put("GGC", "G");\r
-    codonHash2.put("GGT", "G");\r
-\r
-    codonHash2.put("TGA", "*");\r
-    codonHash2.put("TAA", "*");\r
-    codonHash2.put("TAG", "*");\r
-\r
-    codonHash2.put("TGG", "W");\r
-\r
-    codonHash2.put("TGC", "C");\r
-    codonHash2.put("TGT", "C");\r
-\r
-    codonHash2.put("ATA", "I");\r
-    codonHash2.put("ATC", "I");\r
-    codonHash2.put("ATT", "I");\r
-\r
-    codonHash2.put("ATG", "M");\r
-\r
-    codonHash2.put("CTA", "L");\r
-    codonHash2.put("CTG", "L");\r
-    codonHash2.put("CTC", "L");\r
-    codonHash2.put("CTT", "L");\r
-    codonHash2.put("TTA", "L");\r
-    codonHash2.put("TTG", "L");\r
-\r
-    codonHash2.put("GTA", "V");\r
-    codonHash2.put("GTG", "V");\r
-    codonHash2.put("GTC", "V");\r
-    codonHash2.put("GTT", "V");\r
-\r
-    codonHash2.put("TTC", "F");\r
-    codonHash2.put("TTT", "F");\r
-  }\r
-\r
-  static\r
-  {\r
-    Lys.addElement("AAA");\r
-    Lys.addElement("AAG");\r
-    Asn.addElement("AAC");\r
-    Asn.addElement("AAT");\r
-\r
-    Gln.addElement("CAA");\r
-    Gln.addElement("CAG");\r
-    His.addElement("CAC");\r
-    His.addElement("CAT");\r
-\r
-    Glu.addElement("GAA");\r
-    Glu.addElement("GAG");\r
-    Asp.addElement("GAC");\r
-    Asp.addElement("GAT");\r
-\r
-    Tyr.addElement("TAC");\r
-    Tyr.addElement("TAT");\r
-\r
-    Thr.addElement("ACA");\r
-    Thr.addElement("ACG");\r
-    Thr.addElement("ACC");\r
-    Thr.addElement("ACT");\r
-\r
-    Pro.addElement("CCA");\r
-    Pro.addElement("CCG");\r
-    Pro.addElement("CCC");\r
-    Pro.addElement("CCT");\r
-\r
-    Ala.addElement("GCA");\r
-    Ala.addElement("GCG");\r
-    Ala.addElement("GCC");\r
-    Ala.addElement("GCT");\r
-\r
-    Ser.addElement("TCA");\r
-    Ser.addElement("TCG");\r
-    Ser.addElement("TCC");\r
-    Ser.addElement("TCT");\r
-    Ser.addElement("AGC");\r
-    Ser.addElement("AGT");\r
-\r
-    Arg.addElement("AGA");\r
-    Arg.addElement("AGG");\r
-    Arg.addElement("CGA");\r
-    Arg.addElement("CGG");\r
-    Arg.addElement("CGC");\r
-    Arg.addElement("CGT");\r
-\r
-    Gly.addElement("GGA");\r
-    Gly.addElement("GGG");\r
-    Gly.addElement("GGC");\r
-    Gly.addElement("GGT");\r
-\r
-    STOP.addElement("TGA");\r
-    STOP.addElement("TAA");\r
-    STOP.addElement("TAG");\r
-\r
-    Trp.addElement("TGG");\r
-\r
-    Cys.addElement("TGC");\r
-    Cys.addElement("TGT");\r
-\r
-    Ile.addElement("ATA");\r
-    Ile.addElement("ATC");\r
-    Ile.addElement("ATT");\r
-\r
-    Met.addElement("ATG");\r
-\r
-    Leu.addElement("CTA");\r
-    Leu.addElement("CTG");\r
-    Leu.addElement("CTC");\r
-    Leu.addElement("CTT");\r
-    Leu.addElement("TTA");\r
-    Leu.addElement("TTG");\r
-\r
-    Val.addElement("GTA");\r
-    Val.addElement("GTG");\r
-    Val.addElement("GTC");\r
-    Val.addElement("GTT");\r
-\r
-    Phe.addElement("TTC");\r
-    Phe.addElement("TTT");\r
-  }\r
-\r
-\r
-  //Stores residue codes/names and colours and other things\r
-  public static Hashtable propHash = new Hashtable();\r
-  public static Hashtable hydrophobic = new Hashtable();\r
-  public static Hashtable polar = new Hashtable();\r
-  public static Hashtable small = new Hashtable();\r
-  public static Hashtable positive = new Hashtable();\r
-  public static Hashtable negative = new Hashtable();\r
-  public static Hashtable charged = new Hashtable();\r
-  public static Hashtable aromatic = new Hashtable();\r
-  public static Hashtable aliphatic = new Hashtable();\r
-  public static Hashtable tiny = new Hashtable();\r
-  public static Hashtable proline = new Hashtable();\r
-\r
-  static\r
-  {\r
-    hydrophobic.put("I", new Integer(1));\r
-    hydrophobic.put("L", new Integer(1));\r
-    hydrophobic.put("V", new Integer(1));\r
-    hydrophobic.put("C", new Integer(1));\r
-    hydrophobic.put("A", new Integer(1));\r
-    hydrophobic.put("G", new Integer(1));\r
-    hydrophobic.put("M", new Integer(1));\r
-    hydrophobic.put("F", new Integer(1));\r
-    hydrophobic.put("Y", new Integer(1));\r
-    hydrophobic.put("W", new Integer(1));\r
-    hydrophobic.put("H", new Integer(1));\r
-    hydrophobic.put("K", new Integer(1));\r
-    hydrophobic.put("X", new Integer(1));\r
-    hydrophobic.put("-", new Integer(1));\r
-    hydrophobic.put("*", new Integer(1));\r
-    hydrophobic.put("R", new Integer(0));\r
-    hydrophobic.put("E", new Integer(0));\r
-    hydrophobic.put("Q", new Integer(0));\r
-    hydrophobic.put("D", new Integer(0));\r
-    hydrophobic.put("N", new Integer(0));\r
-    hydrophobic.put("S", new Integer(0));\r
-    hydrophobic.put("T", new Integer(0));\r
-    hydrophobic.put("P", new Integer(0));\r
-  }\r
-\r
-  static\r
-  {\r
-    polar.put("Y", new Integer(1));\r
-    polar.put("W", new Integer(1));\r
-    polar.put("H", new Integer(1));\r
-    polar.put("K", new Integer(1));\r
-    polar.put("R", new Integer(1));\r
-    polar.put("E", new Integer(1));\r
-    polar.put("Q", new Integer(1));\r
-    polar.put("D", new Integer(1));\r
-    polar.put("N", new Integer(1));\r
-    polar.put("S", new Integer(1));\r
-    polar.put("T", new Integer(1));\r
-    polar.put("X", new Integer(1));\r
-    polar.put("-", new Integer(1));\r
-    polar.put("*", new Integer(1));\r
-    polar.put("I", new Integer(0));\r
-    polar.put("L", new Integer(0));\r
-    polar.put("V", new Integer(0));\r
-    polar.put("C", new Integer(0));\r
-    polar.put("A", new Integer(0));\r
-    polar.put("G", new Integer(0));\r
-    polar.put("M", new Integer(0));\r
-    polar.put("F", new Integer(0));\r
-    polar.put("P", new Integer(0));\r
-  }\r
-\r
-  static\r
-  {\r
-    small.put("I", new Integer(0));\r
-    small.put("L", new Integer(0));\r
-    small.put("V", new Integer(1));\r
-    small.put("C", new Integer(1));\r
-    small.put("A", new Integer(1));\r
-    small.put("G", new Integer(1));\r
-    small.put("M", new Integer(0));\r
-    small.put("F", new Integer(0));\r
-    small.put("Y", new Integer(0));\r
-    small.put("W", new Integer(0));\r
-    small.put("H", new Integer(0));\r
-    small.put("K", new Integer(0));\r
-    small.put("R", new Integer(0));\r
-    small.put("E", new Integer(0));\r
-    small.put("Q", new Integer(0));\r
-    small.put("D", new Integer(1));\r
-    small.put("N", new Integer(1));\r
-    small.put("S", new Integer(1));\r
-    small.put("T", new Integer(1));\r
-    small.put("P", new Integer(1));\r
-    small.put("-", new Integer(1));\r
-    small.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    positive.put("I", new Integer(0));\r
-    positive.put("L", new Integer(0));\r
-    positive.put("V", new Integer(0));\r
-    positive.put("C", new Integer(0));\r
-    positive.put("A", new Integer(0));\r
-    positive.put("G", new Integer(0));\r
-    positive.put("M", new Integer(0));\r
-    positive.put("F", new Integer(0));\r
-    positive.put("Y", new Integer(0));\r
-    positive.put("W", new Integer(0));\r
-    positive.put("H", new Integer(1));\r
-    positive.put("K", new Integer(1));\r
-    positive.put("R", new Integer(1));\r
-    positive.put("E", new Integer(0));\r
-    positive.put("Q", new Integer(0));\r
-    positive.put("D", new Integer(0));\r
-    positive.put("N", new Integer(0));\r
-    positive.put("S", new Integer(0));\r
-    positive.put("T", new Integer(0));\r
-    positive.put("P", new Integer(0));\r
-    positive.put("-", new Integer(1));\r
-    positive.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    negative.put("I", new Integer(0));\r
-    negative.put("L", new Integer(0));\r
-    negative.put("V", new Integer(0));\r
-    negative.put("C", new Integer(0));\r
-    negative.put("A", new Integer(0));\r
-    negative.put("G", new Integer(0));\r
-    negative.put("M", new Integer(0));\r
-    negative.put("F", new Integer(0));\r
-    negative.put("Y", new Integer(0));\r
-    negative.put("W", new Integer(0));\r
-    negative.put("H", new Integer(0));\r
-    negative.put("K", new Integer(0));\r
-    negative.put("R", new Integer(0));\r
-    negative.put("E", new Integer(1));\r
-    negative.put("Q", new Integer(0));\r
-    negative.put("D", new Integer(1));\r
-    negative.put("N", new Integer(0));\r
-    negative.put("S", new Integer(0));\r
-    negative.put("T", new Integer(0));\r
-    negative.put("P", new Integer(0));\r
-    negative.put("-", new Integer(1));\r
-    negative.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    charged.put("I", new Integer(0));\r
-    charged.put("L", new Integer(0));\r
-    charged.put("V", new Integer(0));\r
-    charged.put("C", new Integer(0));\r
-    charged.put("A", new Integer(0));\r
-    charged.put("G", new Integer(0));\r
-    charged.put("M", new Integer(0));\r
-    charged.put("F", new Integer(0));\r
-    charged.put("Y", new Integer(0));\r
-    charged.put("W", new Integer(0));\r
-    charged.put("H", new Integer(1));\r
-    charged.put("K", new Integer(1));\r
-    charged.put("R", new Integer(1));\r
-    charged.put("E", new Integer(1));\r
-    charged.put("Q", new Integer(0));\r
-    charged.put("D", new Integer(1));\r
-    charged.put("N", new Integer(1));\r
-    charged.put("S", new Integer(0));\r
-    charged.put("T", new Integer(0));\r
-    charged.put("P", new Integer(0));\r
-    charged.put("-", new Integer(1));\r
-    charged.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    aromatic.put("I", new Integer(0));\r
-    aromatic.put("L", new Integer(0));\r
-    aromatic.put("V", new Integer(0));\r
-    aromatic.put("C", new Integer(0));\r
-    aromatic.put("A", new Integer(0));\r
-    aromatic.put("G", new Integer(0));\r
-    aromatic.put("M", new Integer(0));\r
-    aromatic.put("F", new Integer(1));\r
-    aromatic.put("Y", new Integer(1));\r
-    aromatic.put("W", new Integer(1));\r
-    aromatic.put("H", new Integer(1));\r
-    aromatic.put("K", new Integer(0));\r
-    aromatic.put("R", new Integer(0));\r
-    aromatic.put("E", new Integer(0));\r
-    aromatic.put("Q", new Integer(0));\r
-    aromatic.put("D", new Integer(0));\r
-    aromatic.put("N", new Integer(0));\r
-    aromatic.put("S", new Integer(0));\r
-    aromatic.put("T", new Integer(0));\r
-    aromatic.put("P", new Integer(0));\r
-    aromatic.put("-", new Integer(1));\r
-    aromatic.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    aliphatic.put("I", new Integer(1));\r
-    aliphatic.put("L", new Integer(1));\r
-    aliphatic.put("V", new Integer(1));\r
-    aliphatic.put("C", new Integer(0));\r
-    aliphatic.put("A", new Integer(0));\r
-    aliphatic.put("G", new Integer(0));\r
-    aliphatic.put("M", new Integer(0));\r
-    aliphatic.put("F", new Integer(0));\r
-    aliphatic.put("Y", new Integer(0));\r
-    aliphatic.put("W", new Integer(0));\r
-    aliphatic.put("H", new Integer(0));\r
-    aliphatic.put("K", new Integer(0));\r
-    aliphatic.put("R", new Integer(0));\r
-    aliphatic.put("E", new Integer(0));\r
-    aliphatic.put("Q", new Integer(0));\r
-    aliphatic.put("D", new Integer(0));\r
-    aliphatic.put("N", new Integer(0));\r
-    aliphatic.put("S", new Integer(0));\r
-    aliphatic.put("T", new Integer(0));\r
-    aliphatic.put("P", new Integer(0));\r
-    aliphatic.put("-", new Integer(1));\r
-    aliphatic.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    tiny.put("I", new Integer(0));\r
-    tiny.put("L", new Integer(0));\r
-    tiny.put("V", new Integer(0));\r
-    tiny.put("C", new Integer(0));\r
-    tiny.put("A", new Integer(1));\r
-    tiny.put("G", new Integer(1));\r
-    tiny.put("M", new Integer(0));\r
-    tiny.put("F", new Integer(0));\r
-    tiny.put("Y", new Integer(0));\r
-    tiny.put("W", new Integer(0));\r
-    tiny.put("H", new Integer(0));\r
-    tiny.put("K", new Integer(0));\r
-    tiny.put("R", new Integer(0));\r
-    tiny.put("E", new Integer(0));\r
-    tiny.put("Q", new Integer(0));\r
-    tiny.put("D", new Integer(0));\r
-    tiny.put("N", new Integer(0));\r
-    tiny.put("S", new Integer(1));\r
-    tiny.put("T", new Integer(0));\r
-    tiny.put("P", new Integer(0));\r
-    tiny.put("-", new Integer(1));\r
-    tiny.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    proline.put("I", new Integer(0));\r
-    proline.put("L", new Integer(0));\r
-    proline.put("V", new Integer(0));\r
-    proline.put("C", new Integer(0));\r
-    proline.put("A", new Integer(0));\r
-    proline.put("G", new Integer(0));\r
-    proline.put("M", new Integer(0));\r
-    proline.put("F", new Integer(0));\r
-    proline.put("Y", new Integer(0));\r
-    proline.put("W", new Integer(0));\r
-    proline.put("H", new Integer(0));\r
-    proline.put("K", new Integer(0));\r
-    proline.put("R", new Integer(0));\r
-    proline.put("E", new Integer(0));\r
-    proline.put("Q", new Integer(0));\r
-    proline.put("D", new Integer(0));\r
-    proline.put("N", new Integer(0));\r
-    proline.put("S", new Integer(0));\r
-    proline.put("T", new Integer(0));\r
-    proline.put("P", new Integer(1));\r
-    proline.put("-", new Integer(1));\r
-    proline.put("*", new Integer(1));\r
-  }\r
-\r
-  static\r
-  {\r
-    propHash.put("hydrophobic", hydrophobic);\r
-    propHash.put("small", small);\r
-    propHash.put("positive", positive);\r
-    propHash.put("negative", negative);\r
-    propHash.put("charged", charged);\r
-    propHash.put("aromatic", aromatic);\r
-    propHash.put("aliphatic", aliphatic);\r
-    propHash.put("tiny", tiny);\r
-    propHash.put("proline", proline);\r
-    propHash.put("polar", polar);\r
-  }\r
-\r
-  private ResidueProperties()\r
-  {\r
-  }\r
-\r
-  public static double getHydmax()\r
-  {\r
-    return hydmax;\r
-  }\r
-\r
-  public static double getHydmin()\r
-  {\r
-    return hydmin;\r
-  }\r
-\r
-  public static double[] getHyd()\r
-  {\r
-    return hyd;\r
-  }\r
-\r
-  public static Hashtable getAAHash()\r
-  {\r
-    return aaHash;\r
-  }\r
-\r
-  public static Hashtable getAA3Hash()\r
-  {\r
-    return aa3Hash;\r
-  }\r
-\r
-  public static int[][] getDNA()\r
-  {\r
-    return ResidueProperties.DNA;\r
-  }\r
-\r
-  public static int[][] getBLOSUM62()\r
-  {\r
-    return ResidueProperties.BLOSUM62;\r
-  }\r
-\r
-  public static int getPAM250(String A1, String A2)\r
-  {\r
-    Integer pog1 = (Integer) aaHash.get(A1);\r
-    Integer pog2 = (Integer) aaHash.get(A2);\r
-    int pog = ResidueProperties.PAM250[pog1.intValue()][pog2.intValue()];\r
-\r
-    return pog;\r
-  }\r
-\r
-  public static int getBLOSUM62(String A1, String A2)\r
-  {\r
-    int pog = 0;\r
-\r
-    try\r
-    {\r
-      Integer pog1 = (Integer) aaHash.get(A1);\r
-      Integer pog2 = (Integer) aaHash.get(A2);\r
-      pog = ResidueProperties.BLOSUM62[pog1.intValue()][pog2.intValue()];\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      //System.out.println("Unknown residue in " + A1 + " " + A2);\r
-    }\r
-\r
-    return pog;\r
-  }\r
-\r
-  public static Vector getCodons(String res)\r
-  {\r
-    if (codonHash.containsKey(res))\r
-    {\r
-      return (Vector) codonHash.get(res);\r
-    }\r
-\r
-    return null;\r
-  }\r
-\r
-  public static String codonTranslate(String codon)\r
-  {\r
-    Enumeration e = codonHash.keys();\r
-\r
-    while (e.hasMoreElements())\r
-    {\r
-      String key = (String) e.nextElement();\r
-      Vector tmp = (Vector) codonHash.get(key);\r
-\r
-      if (tmp.contains(codon.toUpperCase()))\r
-      {\r
-        return key;\r
-      }\r
-    }\r
-\r
-    return null;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+import java.util.*;
+
+import java.awt.*;
+
+public class ResidueProperties
+{
+  //Stores residue codes/names and colours and other things
+  public static final Hashtable aaHash = new Hashtable(); // stores the number value of the aa
+  public static final Hashtable aa3Hash = new Hashtable();
+  public static final Hashtable aa2Triplet = new Hashtable();
+  public static final Hashtable nucleotideHash = new Hashtable();
+  public static final Hashtable nucleotideName = new Hashtable();
+
+  static
+  {
+    aaHash.put("A", new Integer(0));
+    aaHash.put("R", new Integer(1));
+    aaHash.put("N", new Integer(2));
+    aaHash.put("D", new Integer(3));
+    aaHash.put("C", new Integer(4));
+    aaHash.put("Q", new Integer(5));
+    aaHash.put("E", new Integer(6));
+    aaHash.put("G", new Integer(7));
+    aaHash.put("H", new Integer(8));
+    aaHash.put("I", new Integer(9));
+    aaHash.put("L", new Integer(10));
+    aaHash.put("K", new Integer(11));
+    aaHash.put("M", new Integer(12));
+    aaHash.put("F", new Integer(13));
+    aaHash.put("P", new Integer(14));
+    aaHash.put("S", new Integer(15));
+    aaHash.put("T", new Integer(16));
+    aaHash.put("W", new Integer(17));
+    aaHash.put("Y", new Integer(18));
+    aaHash.put("V", new Integer(19));
+    aaHash.put("B", new Integer(20));
+    aaHash.put("Z", new Integer(21));
+    aaHash.put("X", new Integer(22));
+    aaHash.put("U", new Integer(22));
+    aaHash.put("a", new Integer(0));
+    aaHash.put("r", new Integer(1));
+    aaHash.put("n", new Integer(2));
+    aaHash.put("d", new Integer(3));
+    aaHash.put("c", new Integer(4));
+    aaHash.put("q", new Integer(5));
+    aaHash.put("e", new Integer(6));
+    aaHash.put("g", new Integer(7));
+    aaHash.put("h", new Integer(8));
+    aaHash.put("i", new Integer(9));
+    aaHash.put("l", new Integer(10));
+    aaHash.put("k", new Integer(11));
+    aaHash.put("m", new Integer(12));
+    aaHash.put("f", new Integer(13));
+    aaHash.put("p", new Integer(14));
+    aaHash.put("s", new Integer(15));
+    aaHash.put("t", new Integer(16));
+    aaHash.put("w", new Integer(17));
+    aaHash.put("y", new Integer(18));
+    aaHash.put("v", new Integer(19));
+    aaHash.put("b", new Integer(20));
+    aaHash.put("z", new Integer(21));
+    aaHash.put("x", new Integer(22));
+    aaHash.put("u", new Integer(22));
+    aaHash.put("-", new Integer(23));
+    aaHash.put("*", new Integer(23));
+    aaHash.put(".", new Integer(23));
+    aaHash.put(" ", new Integer(23));
+  }
+
+  static
+  {
+    nucleotideHash.put("A", new Integer(0));
+    nucleotideHash.put("a", new Integer(0));
+    nucleotideHash.put("C", new Integer(1));
+    nucleotideHash.put("c", new Integer(1));
+    nucleotideHash.put("G", new Integer(2));
+    nucleotideHash.put("g", new Integer(2));
+    nucleotideHash.put("T", new Integer(3));
+    nucleotideHash.put("t", new Integer(3));
+    nucleotideHash.put("U", new Integer(4));
+    nucleotideHash.put("u", new Integer(4));
+    nucleotideHash.put("I", new Integer(5));
+    nucleotideHash.put("i", new Integer(5));
+    nucleotideHash.put("X", new Integer(6));
+    nucleotideHash.put("x", new Integer(6));
+    nucleotideHash.put("R", new Integer(7));
+    nucleotideHash.put("r", new Integer(7));
+    nucleotideHash.put("Y", new Integer(8));
+    nucleotideHash.put("y", new Integer(8));
+    nucleotideHash.put("N", new Integer(9));
+    nucleotideHash.put("n", new Integer(9));
+
+
+    nucleotideName.put("A", "Adenine");
+    nucleotideName.put("a", "Adenine");
+    nucleotideName.put("G", "Guanine");
+    nucleotideName.put("g", "Guanine");
+    nucleotideName.put("C", "Cytosine");
+    nucleotideName.put("c", "Cytosine");
+    nucleotideName.put("T", "Thymine");
+    nucleotideName.put("t", "Thymine");
+    nucleotideName.put("U", "Uracil");
+    nucleotideName.put("u", "Uracil");
+    nucleotideName.put("I", "Inosine");
+    nucleotideName.put("i", "Inosine");
+    nucleotideName.put("X", "Xanthine");
+    nucleotideName.put("x", "Xanthine");
+    nucleotideName.put("R", "Unknown Purine");
+    nucleotideName.put("r", "Unknown Purine");
+    nucleotideName.put("Y", "Unknown Pyrimidine");
+    nucleotideName.put("y", "Unknown Pyrimidine");
+    nucleotideName.put("N", "Unknown");
+    nucleotideName.put("n", "Unknown");
+  }
+
+
+  static
+  {
+    aa3Hash.put("ALA", new Integer(0));
+    aa3Hash.put("ARG", new Integer(1));
+    aa3Hash.put("ASN", new Integer(2));
+    aa3Hash.put("ASP", new Integer(3)); //D
+    aa3Hash.put("CYS", new Integer(4));
+    aa3Hash.put("GLN", new Integer(5)); //Q
+    aa3Hash.put("GLU", new Integer(6)); // E
+    aa3Hash.put("GLY", new Integer(7));
+    aa3Hash.put("HIS", new Integer(8));
+    aa3Hash.put("ILE", new Integer(9));
+    aa3Hash.put("LEU", new Integer(10));
+    aa3Hash.put("LYS", new Integer(11));
+    aa3Hash.put("MET", new Integer(12));
+    aa3Hash.put("PHE", new Integer(13));
+    aa3Hash.put("PRO", new Integer(14));
+    aa3Hash.put("SER", new Integer(15));
+    aa3Hash.put("THR", new Integer(16));
+    aa3Hash.put("TRP", new Integer(17));
+    aa3Hash.put("TYR", new Integer(18));
+    aa3Hash.put("VAL", new Integer(19));
+    // IUB Nomenclature for ambiguous peptides
+    aa3Hash.put("ASX", new Integer(20)); // "B";
+    aa3Hash.put("GLX", new Integer(21)); // X
+    aa3Hash.put("XAA", new Integer(22));// X unknown
+    aa3Hash.put("-", new Integer(23));
+    aa3Hash.put("*", new Integer(23));
+    aa3Hash.put(".", new Integer(23));
+    aa3Hash.put(" ", new Integer(23));
+    aa3Hash.put("Gap", new Integer(23));
+  }
+
+  static
+  {
+    aa2Triplet.put("A", "ALA");
+    aa2Triplet.put("a", "ALA");
+    aa2Triplet.put("R", "ARG");
+    aa2Triplet.put("r", "ARG");
+    aa2Triplet.put("N", "ASN");
+    aa2Triplet.put("n", "ASN");
+    aa2Triplet.put("D", "ASP");
+    aa2Triplet.put("d", "ASP");
+    aa2Triplet.put("C", "CYS");
+    aa2Triplet.put("c", "CYS");
+    aa2Triplet.put("Q", "GLN");
+    aa2Triplet.put("q", "GLN");
+    aa2Triplet.put("E", "GLU");
+    aa2Triplet.put("e", "GLU");
+    aa2Triplet.put("G", "GLY");
+    aa2Triplet.put("g", "GLY");
+    aa2Triplet.put("H", "HIS");
+    aa2Triplet.put("h", "HIS");
+    aa2Triplet.put("I", "ILE");
+    aa2Triplet.put("i", "ILE");
+    aa2Triplet.put("L", "LEU");
+    aa2Triplet.put("l", "LEU");
+    aa2Triplet.put("K", "LYS");
+    aa2Triplet.put("k", "LYS");
+    aa2Triplet.put("M", "MET");
+    aa2Triplet.put("m", "MET");
+    aa2Triplet.put("F", "PHE");
+    aa2Triplet.put("f", "PHE");
+    aa2Triplet.put("P", "PRO");
+    aa2Triplet.put("p", "PRO");
+    aa2Triplet.put("S", "SER");
+    aa2Triplet.put("s", "SER");
+    aa2Triplet.put("T", "THR");
+    aa2Triplet.put("t", "THR");
+    aa2Triplet.put("W", "TRP");
+    aa2Triplet.put("w", "TRP");
+    aa2Triplet.put("Y", "TYR");
+    aa2Triplet.put("y", "TYR");
+    aa2Triplet.put("V", "VAL");
+    aa2Triplet.put("v", "VAL");
+  }
+
+  public static final String[] aa =
+      {
+      "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I", "L", "K", "M", "F",
+      "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "_", "*", ".", " "
+  };
+  public static final Color midBlue = new Color(100, 100, 255);
+  public static final Vector scaleColours = new Vector();
+
+  static
+  {
+    scaleColours.addElement(new Color(114, 0, 147));
+    scaleColours.addElement(new Color(156, 0, 98));
+    scaleColours.addElement(new Color(190, 0, 0));
+    scaleColours.addElement(Color.red);
+    scaleColours.addElement(new Color(255, 125, 0));
+    scaleColours.addElement(Color.orange);
+    scaleColours.addElement(new Color(255, 194, 85));
+    scaleColours.addElement(Color.yellow);
+    scaleColours.addElement(new Color(255, 255, 181));
+    scaleColours.addElement(Color.white);
+  }
+
+  public static final Color[] taylor =
+      {
+      new Color(204, 255, 0), // A  Greenish-yellowy-yellow
+      new Color(0, 0, 255), // R  Blueish-bluey-blue
+      new Color(204, 0, 255), // N  Blueish-reddy-blue
+      new Color(255, 0, 0), // D  Reddish-reddy-red
+      new Color(255, 255, 0), // C  Yellowish-yellowy-yellow
+      new Color(255, 0, 204), // Q  Reddish-bluey-red
+      new Color(255, 0, 102), // E  Blueish-reddy-red
+      new Color(255, 153, 0), // G  Yellowy-reddy-yellow
+      new Color(0, 102, 255), // H  Greenish-bluey-blue
+      new Color(102, 255, 0), // I  Greenish-yellowy-green
+      new Color(51, 255, 0), // L  Yellowish-greeny-green
+      new Color(102, 0, 255), // K  Reddish-bluey-blue
+      new Color(0, 255, 0), // M  Greenish-greeny-green
+      new Color(0, 255, 102), // F  Blueish-greeny-green
+      new Color(255, 204, 0), // P  Reddish-yellowy-yellow
+      new Color(255, 51, 0), // S  Yellowish-reddy-red
+      new Color(255, 102, 0), // T  Reddish-yellowy-red
+      new Color(0, 204, 255), // W  Blueish-greeny-green
+      new Color(0, 255, 204), // Y  Greenish-bluey-green
+      new Color(153, 255, 0), // V  Yellowish-greeny-yellow
+      Color.white, // B
+      Color.white, // Z
+      Color.white, // X
+      Color.white, // -
+      Color.white, // *
+      Color.white // .
+  };
+  public static final Color[] nucleotide =
+      {
+      new Color(100, 247, 63), // A
+      new Color(255, 179, 64), // C
+      new Color(235, 65, 60), // G
+      new Color(60, 136, 238), // T
+      new Color(60, 136, 238) // U
+  };
+  public static final Color[] color =
+      {
+      Color.pink, // A
+      midBlue, // R
+      Color.green, // N
+      Color.red, // D
+      Color.yellow, // C
+      Color.green, // Q
+      Color.red, // E
+      Color.magenta, // G
+      Color.red, // H
+      Color.pink, // I
+      Color.pink, // L
+      midBlue, // K
+      Color.pink, // M
+      Color.orange, // F
+      Color.magenta, // P
+      Color.green, // S
+      Color.green, // T
+      Color.orange, // W
+      Color.orange, // Y
+      Color.pink, // V
+      Color.white, // B
+      Color.white, // Z
+      Color.white, // X
+      Color.white, // -
+      Color.white, // *
+      Color.white, // .
+      Color.white // ' '
+  };
+
+  // Dunno where I got these numbers from
+  public static final double[] hyd2 =
+      {
+      0.62, //A
+      0.29, //R
+      -0.90, //N
+      -0.74, //D
+      1.19, //C
+      0.48, //Q
+      -0.40, //E
+      1.38, //G
+      -1.50, //H
+      1.06, //I
+      0.64, //L
+      -0.78, //K
+      0.12, //M
+      -0.85, //F
+      -2.53, //P
+      -0.18, //S
+      -0.05, //T
+      1.08, //W
+      0.81, //Y
+      0.0, //V
+      0.26, //B
+      0.0, //Z
+      0.0 //X
+  };
+  public static final double[] helix =
+      {
+      1.42, 0.98, 0.67, 1.01, 0.70, 1.11, 1.51, 0.57, 1.00, 1.08, 1.21, 1.16,
+      1.45, 1.13, 0.57, 0.77, 0.83, 1.08, 0.69, 1.06, 0.84, 1.31, 1.00, 0.0
+  };
+  public static final double helixmin = 0.57;
+  public static final double helixmax = 1.51;
+  public static final double[] strand =
+      {
+      0.83, 0.93, 0.89, 0.54, 1.19, 1.10, 0.37, 0.75, 0.87, 1.60, 1.30, 0.74,
+      1.05, 1.38, 0.55, 0.75, 1.19, 1.37, 1.47, 1.70, 0.72, 0.74, 1.0, 0.0
+  };
+  public static final double strandmin = 0.37;
+  public static final double strandmax = 1.7;
+  public static final double[] turn =
+      {
+      0.66, 0.95, 1.56, 1.46, 1.19, 0.98, 0.74, 1.56, 0.95, 0.47, 0.59, 1.01,
+      0.60, 0.60, 1.52, 1.43, 0.96, 0.96, 1.14, 0.50, 1.51, 0.86, 1.00, 0, 0
+  };
+  public static final double turnmin = 0.47;
+  public static final double turnmax = 1.56;
+  public static final double[] buried =
+      {
+      1.7, 0.1, 0.4, 0.4, 4.6, 0.3, 0.3, 1.8, 0.8, 3.1, 2.4, 0.05, 1.9, 2.2,
+      0.6, 0.8, 0.7, 1.6, 0.5, 2.9, 0.4, 0.3, 1.358, 0.00
+  };
+  public static final double buriedmin = 0.05;
+  public static final double buriedmax = 4.6;
+
+  // This is hydropathy index
+  // Kyte, J., and Doolittle, R.F., J. Mol. Biol.
+  // 1157, 105-132, 1982
+  public static final double[] hyd =
+      {
+      1.8, -4.5, -3.5, -3.5, 2.5, -3.5, -3.5, -0.4, -3.2, 4.5, 3.8, -3.9, 1.9,
+      2.8, -1.6, -0.8, -0.7, -0.9, -1.3, 4.2, -3.5, -3.5, -0.49, 0.0
+  };
+  public static final double hydmax = 4.5;
+  public static final double hydmin = -3.9;
+
+  //public static final double hydmax = 1.38;
+  //public static final double hydmin = -2.53;
+  static final int[][] BLOSUM62 =
+      {
+      {
+      4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3,
+      -2, 0, -2, -1, 0, -4
+  },
+      {
+      -1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3, -2,
+      -3, -1, 0, -1, -4
+  },
+      {
+      -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2, -3,
+      3, 0, -1, -4
+  },
+      {
+      -2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4,
+      -3, -3, 4, 1, -1, -4
+  },
+      {
+      0, 3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2,
+      -2, -1, -3, -3, -2, -4
+  },
+      {
+      -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1,
+      -2, 0, 3, -1, -4
+  },
+      {
+      -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2,
+      -2, 1, 4, -1, -4
+  },
+      {
+      0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2,
+      -3, -3, -1, -2, -1, -4
+  },
+      {
+      -2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2, 2,
+      -3, 0, 0, -1, -4
+  },
+      {
+      -1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3,
+      -1, 3, -3, -3, -1, -4
+  },
+      {
+      -1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2,
+      -1, 1, -4, -3, -1, -4
+  },
+      {
+      -1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3, -2,
+      -2, 0, 1, -1, -4
+  },
+      {
+      -1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1,
+      -1, 1, -3, -1, -1, -4
+  },
+      {
+      -2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1, 3,
+      -1, -3, -3, -1, -4
+  },
+      {
+      -1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1,
+      -4, -3, -2, -2, -1, -2, -4
+  },
+      {
+      1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2,
+      -2, 0, 0, 0, -4
+  },
+      {
+      0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2,
+      -2, 0, -1, -1, 0, -4
+  },
+      {
+      -3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2,
+      11, 2, -3, -4, -3, -2, -4
+  },
+      {
+      -2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2, 2,
+      7, -1, -3, -2, -1, -4
+  },
+      {
+      0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3,
+      -1, 4, -3, -2, -1, -4
+  },
+      {
+      -2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4, -3,
+      -3, 4, 1, -1, -4
+  },
+      {
+      -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2,
+      -2, 1, 4, -1, -4
+  },
+      {
+      0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0, -2,
+      -1, -1, -1, -1, -1, -4
+  },
+      {
+      -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
+      -4, -4, -4, -4, -4, -4, 1
+  },
+  };
+  static final int[][] PAM250 =
+      {
+      {
+      2, -2, 0, 0, -2, 0, 0, 1, -1, -1, -2, -1, -1, -3, 1, 1, 1, -6, -3, 0,
+      0, 0, 0, -8
+  },
+      {
+      -2, 6, 0, -1, -4, 1, -1, -3, 2, -2, -3, 3, 0, -4, 0, 0, -1, 2, -4,
+      -2, -1, 0, -1, -8
+  },
+      {
+      0, 0, 2, 2, -4, 1, 1, 0, 2, -2, -3, 1, -2, -3, 0, 1, 0, -4, -2, -2,
+      2, 1, 0, -8
+  },
+      {
+      0, -1, 2, 4, -5, 2, 3, 1, 1, -2, -4, 0, -3, -6, -1, 0, 0, -7, -4, -2,
+      3, 3, -1, -8
+  },
+      {
+      -2, -4, -4, -5, 12, -5, -5, -3, -3, -2, -6, -5, -5, -4, -3, 0, -2,
+      -8, 0, -2, -4, -5, -3, -8
+  },
+      {
+      0, 1, 1, 2, -5, 4, 2, -1, 3, -2, -2, 1, -1, -5, 0, -1, -1, -5, -4,
+      -2, 1, 3, -1, -8
+  },
+      {
+      0, -1, 1, 3, -5, 2, 4, 0, 1, -2, -3, 0, -2, -5, -1, 0, 0, -7, -4, -2,
+      3, 3, -1, -8
+  },
+      {
+      1, -3, 0, 1, -3, -1, 0, 5, -2, -3, -4, -2, -3, -5, 0, 1, 0, -7, -5,
+      -1, 0, 0, -1, -8
+  },
+      {
+      -1, 2, 2, 1, -3, 3, 1, -2, 6, -2, -2, 0, -2, -2, 0, -1, -1, -3, 0,
+      -2, 1, 2, -1, -8
+  },
+      {
+      -1, -2, -2, -2, -2, -2, -2, -3, -2, 5, 2, -2, 2, 1, -2, -1, 0, -5,
+      -1, 4, -2, -2, -1, -8
+  },
+      {
+      -2, -3, -3, -4, -6, -2, -3, -4, -2, 2, 6, -3, 4, 2, -3, -3, -2, -2,
+      -1, 2, -3, -3, -1, -8
+  },
+      {
+      -1, 3, 1, 0, -5, 1, 0, -2, 0, -2, -3, 5, 0, -5, -1, 0, 0, -3, -4, -2,
+      1, 0, -1, -8
+  },
+      {
+      -1, 0, -2, -3, -5, -1, -2, -3, -2, 2, 4, 0, 6, 0, -2, -2, -1, -4, -2,
+      2, -2, -2, -1, -8
+  },
+      {
+      -3, -4, -3, -6, -4, -5, -5, -5, -2, 1, 2, -5, 0, 9, -5, -3, -3, 0, 7,
+      -1, -4, -5, -2, -8
+  },
+      {
+      1, 0, 0, -1, -3, 0, -1, 0, 0, -2, -3, -1, -2, -5, 6, 1, 0, -6, -5,
+      -1, -1, 0, -1, -8
+  },
+      {
+      1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -3, 0, -2, -3, 1, 2, 1, -2, -3, -1,
+      0, 0, 0, -8
+  },
+      {
+      1, -1, 0, 0, -2, -1, 0, 0, -1, 0, -2, 0, -1, -3, 0, 1, 3, -5, -3, 0,
+      0, -1, 0, -8
+  },
+      {
+      -6, 2, -4, -7, -8, -5, -7, -7, -3, -5, -2, -3, -4, 0, -6, -2, -5, 17,
+      0, -6, -5, -6, -4, -8
+  },
+      {
+      -3, -4, -2, -4, 0, -4, -4, -5, 0, -1, -1, -4, -2, 7, -5, -3, -3, 0,
+      10, -2, -3, -4, -2, -8
+  },
+      {
+      0, -2, -2, -2, -2, -2, -2, -1, -2, 4, 2, -2, 2, -1, -1, -1, 0, -6,
+      -2, 4, -2, -2, -1, -8
+  },
+      {
+      0, -1, 2, 3, -4, 1, 3, 0, 1, -2, -3, 1, -2, -4, -1, 0, 0, -5, -3, -2,
+      3, 2, -1, -8
+  },
+      {
+      0, 0, 1, 3, -5, 3, 3, 0, 2, -2, -3, 0, -2, -5, 0, 0, -1, -6, -4, -2,
+      2, 3, -1, -8
+  },
+      {
+      0, -1, 0, -1, -3, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, 0, 0, -4,
+      -2, -1, -1, -1, -1, -8
+  },
+      {
+      -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+      -8, -8, -8, -8, -8, -8, 1
+  },
+  };
+  public static final Hashtable ssHash = new Hashtable(); // stores the number value of the aa
+
+  static
+  {
+    ssHash.put("H", Color.magenta);
+    ssHash.put("E", Color.yellow);
+    ssHash.put("-", Color.white);
+    ssHash.put(".", Color.white);
+    ssHash.put("S", Color.cyan);
+    ssHash.put("T", Color.blue);
+    ssHash.put("G", Color.pink);
+    ssHash.put("I", Color.pink);
+    ssHash.put("B", Color.yellow);
+  }
+
+  static final int[][] DNA =
+      {
+      {
+      5, -4, -4, -4, 1}, // C
+      {
+      -4, 5, -4, -4, 1}, // T
+      {
+      -4, -4, 5, -4, 1}, // A
+      {
+      -4, -4, -4, 5, 1}, // G
+      {
+      1, 1, 1, 1, 1}, // -
+  };
+  public static final Color[] pidColours =
+      {
+      midBlue, new Color(153, 153, 255),
+      //    Color.lightGray,
+      new Color(204, 204, 255),
+  };
+  public static final float[] pidThresholds =
+      {
+      80, 60, 40, };
+  public static Hashtable codonHash = new Hashtable();
+  public static Vector Lys = new Vector();
+  public static Vector Asn = new Vector();
+  public static Vector Gln = new Vector();
+  public static Vector His = new Vector();
+  public static Vector Glu = new Vector();
+  public static Vector Asp = new Vector();
+  public static Vector Tyr = new Vector();
+  public static Vector Thr = new Vector();
+  public static Vector Pro = new Vector();
+  public static Vector Ala = new Vector();
+  public static Vector Ser = new Vector();
+  public static Vector Arg = new Vector();
+  public static Vector Gly = new Vector();
+  public static Vector Trp = new Vector();
+  public static Vector Cys = new Vector();
+  public static Vector Ile = new Vector();
+  public static Vector Met = new Vector();
+  public static Vector Leu = new Vector();
+  public static Vector Val = new Vector();
+  public static Vector Phe = new Vector();
+  public static Vector STOP = new Vector();
+
+  static
+  {
+    codonHash.put("K", Lys);
+    codonHash.put("N", Asn);
+    codonHash.put("Q", Gln);
+    codonHash.put("H", His);
+    codonHash.put("E", Glu);
+    codonHash.put("D", Asp);
+    codonHash.put("Y", Tyr);
+    codonHash.put("T", Thr);
+    codonHash.put("P", Pro);
+    codonHash.put("A", Ala);
+    codonHash.put("S", Ser);
+    codonHash.put("R", Arg);
+    codonHash.put("G", Gly);
+    codonHash.put("W", Trp);
+    codonHash.put("C", Cys);
+    codonHash.put("I", Ile);
+    codonHash.put("M", Met);
+    codonHash.put("L", Leu);
+    codonHash.put("V", Val);
+    codonHash.put("F", Phe);
+    codonHash.put("STOP", STOP);
+  }
+
+  public static Hashtable codonHash2 = new Hashtable();
+
+  static
+  {
+    codonHash2.put("AAA", "K");
+    codonHash2.put("AAG", "K");
+    codonHash2.put("AAC", "N");
+    codonHash2.put("AAT", "N");
+
+    codonHash2.put("CAA", "E");
+    codonHash2.put("CAG", "E");
+    codonHash2.put("CAC", "H");
+    codonHash2.put("CAT", "H");
+
+    codonHash2.put("GAA", "Q");
+    codonHash2.put("GAG", "Q");
+    codonHash2.put("GAC", "D");
+    codonHash2.put("GAT", "D");
+
+    codonHash2.put("TAC", "Y");
+    codonHash2.put("TAT", "Y");
+
+    codonHash2.put("ACA", "T");
+    codonHash2.put("AAG", "T");
+    codonHash2.put("ACC", "T");
+    codonHash2.put("ACT", "T");
+
+    codonHash2.put("CCA", "P");
+    codonHash2.put("CCG", "P");
+    codonHash2.put("CCC", "P");
+    codonHash2.put("CCT", "P");
+
+    codonHash2.put("GCA", "A");
+    codonHash2.put("GCG", "A");
+    codonHash2.put("GCC", "A");
+    codonHash2.put("GCT", "A");
+
+    codonHash2.put("TCA", "S");
+    codonHash2.put("TCG", "S");
+    codonHash2.put("TCC", "S");
+    codonHash2.put("TCT", "S");
+    codonHash2.put("AGC", "S");
+    codonHash2.put("AGT", "S");
+
+    codonHash2.put("AGA", "R");
+    codonHash2.put("AGG", "R");
+    codonHash2.put("CGA", "R");
+    codonHash2.put("CGG", "R");
+    codonHash2.put("CGC", "R");
+    codonHash2.put("CGT", "R");
+
+    codonHash2.put("GGA", "G");
+    codonHash2.put("GGG", "G");
+    codonHash2.put("GGC", "G");
+    codonHash2.put("GGT", "G");
+
+    codonHash2.put("TGA", "*");
+    codonHash2.put("TAA", "*");
+    codonHash2.put("TAG", "*");
+
+    codonHash2.put("TGG", "W");
+
+    codonHash2.put("TGC", "C");
+    codonHash2.put("TGT", "C");
+
+    codonHash2.put("ATA", "I");
+    codonHash2.put("ATC", "I");
+    codonHash2.put("ATT", "I");
+
+    codonHash2.put("ATG", "M");
+
+    codonHash2.put("CTA", "L");
+    codonHash2.put("CTG", "L");
+    codonHash2.put("CTC", "L");
+    codonHash2.put("CTT", "L");
+    codonHash2.put("TTA", "L");
+    codonHash2.put("TTG", "L");
+
+    codonHash2.put("GTA", "V");
+    codonHash2.put("GTG", "V");
+    codonHash2.put("GTC", "V");
+    codonHash2.put("GTT", "V");
+
+    codonHash2.put("TTC", "F");
+    codonHash2.put("TTT", "F");
+  }
+
+  static
+  {
+    Lys.addElement("AAA");
+    Lys.addElement("AAG");
+    Asn.addElement("AAC");
+    Asn.addElement("AAT");
+
+    Gln.addElement("CAA");
+    Gln.addElement("CAG");
+    His.addElement("CAC");
+    His.addElement("CAT");
+
+    Glu.addElement("GAA");
+    Glu.addElement("GAG");
+    Asp.addElement("GAC");
+    Asp.addElement("GAT");
+
+    Tyr.addElement("TAC");
+    Tyr.addElement("TAT");
+
+    Thr.addElement("ACA");
+    Thr.addElement("ACG");
+    Thr.addElement("ACC");
+    Thr.addElement("ACT");
+
+    Pro.addElement("CCA");
+    Pro.addElement("CCG");
+    Pro.addElement("CCC");
+    Pro.addElement("CCT");
+
+    Ala.addElement("GCA");
+    Ala.addElement("GCG");
+    Ala.addElement("GCC");
+    Ala.addElement("GCT");
+
+    Ser.addElement("TCA");
+    Ser.addElement("TCG");
+    Ser.addElement("TCC");
+    Ser.addElement("TCT");
+    Ser.addElement("AGC");
+    Ser.addElement("AGT");
+
+    Arg.addElement("AGA");
+    Arg.addElement("AGG");
+    Arg.addElement("CGA");
+    Arg.addElement("CGG");
+    Arg.addElement("CGC");
+    Arg.addElement("CGT");
+
+    Gly.addElement("GGA");
+    Gly.addElement("GGG");
+    Gly.addElement("GGC");
+    Gly.addElement("GGT");
+
+    STOP.addElement("TGA");
+    STOP.addElement("TAA");
+    STOP.addElement("TAG");
+
+    Trp.addElement("TGG");
+
+    Cys.addElement("TGC");
+    Cys.addElement("TGT");
+
+    Ile.addElement("ATA");
+    Ile.addElement("ATC");
+    Ile.addElement("ATT");
+
+    Met.addElement("ATG");
+
+    Leu.addElement("CTA");
+    Leu.addElement("CTG");
+    Leu.addElement("CTC");
+    Leu.addElement("CTT");
+    Leu.addElement("TTA");
+    Leu.addElement("TTG");
+
+    Val.addElement("GTA");
+    Val.addElement("GTG");
+    Val.addElement("GTC");
+    Val.addElement("GTT");
+
+    Phe.addElement("TTC");
+    Phe.addElement("TTT");
+  }
+
+
+  //Stores residue codes/names and colours and other things
+  public static Hashtable propHash = new Hashtable();
+  public static Hashtable hydrophobic = new Hashtable();
+  public static Hashtable polar = new Hashtable();
+  public static Hashtable small = new Hashtable();
+  public static Hashtable positive = new Hashtable();
+  public static Hashtable negative = new Hashtable();
+  public static Hashtable charged = new Hashtable();
+  public static Hashtable aromatic = new Hashtable();
+  public static Hashtable aliphatic = new Hashtable();
+  public static Hashtable tiny = new Hashtable();
+  public static Hashtable proline = new Hashtable();
+
+  static
+  {
+    hydrophobic.put("I", new Integer(1));
+    hydrophobic.put("L", new Integer(1));
+    hydrophobic.put("V", new Integer(1));
+    hydrophobic.put("C", new Integer(1));
+    hydrophobic.put("A", new Integer(1));
+    hydrophobic.put("G", new Integer(1));
+    hydrophobic.put("M", new Integer(1));
+    hydrophobic.put("F", new Integer(1));
+    hydrophobic.put("Y", new Integer(1));
+    hydrophobic.put("W", new Integer(1));
+    hydrophobic.put("H", new Integer(1));
+    hydrophobic.put("K", new Integer(1));
+    hydrophobic.put("X", new Integer(1));
+    hydrophobic.put("-", new Integer(1));
+    hydrophobic.put("*", new Integer(1));
+    hydrophobic.put("R", new Integer(0));
+    hydrophobic.put("E", new Integer(0));
+    hydrophobic.put("Q", new Integer(0));
+    hydrophobic.put("D", new Integer(0));
+    hydrophobic.put("N", new Integer(0));
+    hydrophobic.put("S", new Integer(0));
+    hydrophobic.put("T", new Integer(0));
+    hydrophobic.put("P", new Integer(0));
+  }
+
+  static
+  {
+    polar.put("Y", new Integer(1));
+    polar.put("W", new Integer(1));
+    polar.put("H", new Integer(1));
+    polar.put("K", new Integer(1));
+    polar.put("R", new Integer(1));
+    polar.put("E", new Integer(1));
+    polar.put("Q", new Integer(1));
+    polar.put("D", new Integer(1));
+    polar.put("N", new Integer(1));
+    polar.put("S", new Integer(1));
+    polar.put("T", new Integer(1));
+    polar.put("X", new Integer(1));
+    polar.put("-", new Integer(1));
+    polar.put("*", new Integer(1));
+    polar.put("I", new Integer(0));
+    polar.put("L", new Integer(0));
+    polar.put("V", new Integer(0));
+    polar.put("C", new Integer(0));
+    polar.put("A", new Integer(0));
+    polar.put("G", new Integer(0));
+    polar.put("M", new Integer(0));
+    polar.put("F", new Integer(0));
+    polar.put("P", new Integer(0));
+  }
+
+  static
+  {
+    small.put("I", new Integer(0));
+    small.put("L", new Integer(0));
+    small.put("V", new Integer(1));
+    small.put("C", new Integer(1));
+    small.put("A", new Integer(1));
+    small.put("G", new Integer(1));
+    small.put("M", new Integer(0));
+    small.put("F", new Integer(0));
+    small.put("Y", new Integer(0));
+    small.put("W", new Integer(0));
+    small.put("H", new Integer(0));
+    small.put("K", new Integer(0));
+    small.put("R", new Integer(0));
+    small.put("E", new Integer(0));
+    small.put("Q", new Integer(0));
+    small.put("D", new Integer(1));
+    small.put("N", new Integer(1));
+    small.put("S", new Integer(1));
+    small.put("T", new Integer(1));
+    small.put("P", new Integer(1));
+    small.put("-", new Integer(1));
+    small.put("*", new Integer(1));
+  }
+
+  static
+  {
+    positive.put("I", new Integer(0));
+    positive.put("L", new Integer(0));
+    positive.put("V", new Integer(0));
+    positive.put("C", new Integer(0));
+    positive.put("A", new Integer(0));
+    positive.put("G", new Integer(0));
+    positive.put("M", new Integer(0));
+    positive.put("F", new Integer(0));
+    positive.put("Y", new Integer(0));
+    positive.put("W", new Integer(0));
+    positive.put("H", new Integer(1));
+    positive.put("K", new Integer(1));
+    positive.put("R", new Integer(1));
+    positive.put("E", new Integer(0));
+    positive.put("Q", new Integer(0));
+    positive.put("D", new Integer(0));
+    positive.put("N", new Integer(0));
+    positive.put("S", new Integer(0));
+    positive.put("T", new Integer(0));
+    positive.put("P", new Integer(0));
+    positive.put("-", new Integer(1));
+    positive.put("*", new Integer(1));
+  }
+
+  static
+  {
+    negative.put("I", new Integer(0));
+    negative.put("L", new Integer(0));
+    negative.put("V", new Integer(0));
+    negative.put("C", new Integer(0));
+    negative.put("A", new Integer(0));
+    negative.put("G", new Integer(0));
+    negative.put("M", new Integer(0));
+    negative.put("F", new Integer(0));
+    negative.put("Y", new Integer(0));
+    negative.put("W", new Integer(0));
+    negative.put("H", new Integer(0));
+    negative.put("K", new Integer(0));
+    negative.put("R", new Integer(0));
+    negative.put("E", new Integer(1));
+    negative.put("Q", new Integer(0));
+    negative.put("D", new Integer(1));
+    negative.put("N", new Integer(0));
+    negative.put("S", new Integer(0));
+    negative.put("T", new Integer(0));
+    negative.put("P", new Integer(0));
+    negative.put("-", new Integer(1));
+    negative.put("*", new Integer(1));
+  }
+
+  static
+  {
+    charged.put("I", new Integer(0));
+    charged.put("L", new Integer(0));
+    charged.put("V", new Integer(0));
+    charged.put("C", new Integer(0));
+    charged.put("A", new Integer(0));
+    charged.put("G", new Integer(0));
+    charged.put("M", new Integer(0));
+    charged.put("F", new Integer(0));
+    charged.put("Y", new Integer(0));
+    charged.put("W", new Integer(0));
+    charged.put("H", new Integer(1));
+    charged.put("K", new Integer(1));
+    charged.put("R", new Integer(1));
+    charged.put("E", new Integer(1));
+    charged.put("Q", new Integer(0));
+    charged.put("D", new Integer(1));
+    charged.put("N", new Integer(1));
+    charged.put("S", new Integer(0));
+    charged.put("T", new Integer(0));
+    charged.put("P", new Integer(0));
+    charged.put("-", new Integer(1));
+    charged.put("*", new Integer(1));
+  }
+
+  static
+  {
+    aromatic.put("I", new Integer(0));
+    aromatic.put("L", new Integer(0));
+    aromatic.put("V", new Integer(0));
+    aromatic.put("C", new Integer(0));
+    aromatic.put("A", new Integer(0));
+    aromatic.put("G", new Integer(0));
+    aromatic.put("M", new Integer(0));
+    aromatic.put("F", new Integer(1));
+    aromatic.put("Y", new Integer(1));
+    aromatic.put("W", new Integer(1));
+    aromatic.put("H", new Integer(1));
+    aromatic.put("K", new Integer(0));
+    aromatic.put("R", new Integer(0));
+    aromatic.put("E", new Integer(0));
+    aromatic.put("Q", new Integer(0));
+    aromatic.put("D", new Integer(0));
+    aromatic.put("N", new Integer(0));
+    aromatic.put("S", new Integer(0));
+    aromatic.put("T", new Integer(0));
+    aromatic.put("P", new Integer(0));
+    aromatic.put("-", new Integer(1));
+    aromatic.put("*", new Integer(1));
+  }
+
+  static
+  {
+    aliphatic.put("I", new Integer(1));
+    aliphatic.put("L", new Integer(1));
+    aliphatic.put("V", new Integer(1));
+    aliphatic.put("C", new Integer(0));
+    aliphatic.put("A", new Integer(0));
+    aliphatic.put("G", new Integer(0));
+    aliphatic.put("M", new Integer(0));
+    aliphatic.put("F", new Integer(0));
+    aliphatic.put("Y", new Integer(0));
+    aliphatic.put("W", new Integer(0));
+    aliphatic.put("H", new Integer(0));
+    aliphatic.put("K", new Integer(0));
+    aliphatic.put("R", new Integer(0));
+    aliphatic.put("E", new Integer(0));
+    aliphatic.put("Q", new Integer(0));
+    aliphatic.put("D", new Integer(0));
+    aliphatic.put("N", new Integer(0));
+    aliphatic.put("S", new Integer(0));
+    aliphatic.put("T", new Integer(0));
+    aliphatic.put("P", new Integer(0));
+    aliphatic.put("-", new Integer(1));
+    aliphatic.put("*", new Integer(1));
+  }
+
+  static
+  {
+    tiny.put("I", new Integer(0));
+    tiny.put("L", new Integer(0));
+    tiny.put("V", new Integer(0));
+    tiny.put("C", new Integer(0));
+    tiny.put("A", new Integer(1));
+    tiny.put("G", new Integer(1));
+    tiny.put("M", new Integer(0));
+    tiny.put("F", new Integer(0));
+    tiny.put("Y", new Integer(0));
+    tiny.put("W", new Integer(0));
+    tiny.put("H", new Integer(0));
+    tiny.put("K", new Integer(0));
+    tiny.put("R", new Integer(0));
+    tiny.put("E", new Integer(0));
+    tiny.put("Q", new Integer(0));
+    tiny.put("D", new Integer(0));
+    tiny.put("N", new Integer(0));
+    tiny.put("S", new Integer(1));
+    tiny.put("T", new Integer(0));
+    tiny.put("P", new Integer(0));
+    tiny.put("-", new Integer(1));
+    tiny.put("*", new Integer(1));
+  }
+
+  static
+  {
+    proline.put("I", new Integer(0));
+    proline.put("L", new Integer(0));
+    proline.put("V", new Integer(0));
+    proline.put("C", new Integer(0));
+    proline.put("A", new Integer(0));
+    proline.put("G", new Integer(0));
+    proline.put("M", new Integer(0));
+    proline.put("F", new Integer(0));
+    proline.put("Y", new Integer(0));
+    proline.put("W", new Integer(0));
+    proline.put("H", new Integer(0));
+    proline.put("K", new Integer(0));
+    proline.put("R", new Integer(0));
+    proline.put("E", new Integer(0));
+    proline.put("Q", new Integer(0));
+    proline.put("D", new Integer(0));
+    proline.put("N", new Integer(0));
+    proline.put("S", new Integer(0));
+    proline.put("T", new Integer(0));
+    proline.put("P", new Integer(1));
+    proline.put("-", new Integer(1));
+    proline.put("*", new Integer(1));
+  }
+
+  static
+  {
+    propHash.put("hydrophobic", hydrophobic);
+    propHash.put("small", small);
+    propHash.put("positive", positive);
+    propHash.put("negative", negative);
+    propHash.put("charged", charged);
+    propHash.put("aromatic", aromatic);
+    propHash.put("aliphatic", aliphatic);
+    propHash.put("tiny", tiny);
+    propHash.put("proline", proline);
+    propHash.put("polar", polar);
+  }
+
+  private ResidueProperties()
+  {
+  }
+
+  public static double getHydmax()
+  {
+    return hydmax;
+  }
+
+  public static double getHydmin()
+  {
+    return hydmin;
+  }
+
+  public static double[] getHyd()
+  {
+    return hyd;
+  }
+
+  public static Hashtable getAAHash()
+  {
+    return aaHash;
+  }
+
+  public static Hashtable getAA3Hash()
+  {
+    return aa3Hash;
+  }
+
+  public static int[][] getDNA()
+  {
+    return ResidueProperties.DNA;
+  }
+
+  public static int[][] getBLOSUM62()
+  {
+    return ResidueProperties.BLOSUM62;
+  }
+
+  public static int getPAM250(String A1, String A2)
+  {
+    Integer pog1 = (Integer) aaHash.get(A1);
+    Integer pog2 = (Integer) aaHash.get(A2);
+    int pog = ResidueProperties.PAM250[pog1.intValue()][pog2.intValue()];
+
+    return pog;
+  }
+
+  public static int getBLOSUM62(String A1, String A2)
+  {
+    int pog = 0;
+
+    try
+    {
+      Integer pog1 = (Integer) aaHash.get(A1);
+      Integer pog2 = (Integer) aaHash.get(A2);
+      pog = ResidueProperties.BLOSUM62[pog1.intValue()][pog2.intValue()];
+    }
+    catch (Exception e)
+    {
+      //System.out.println("Unknown residue in " + A1 + " " + A2);
+    }
+
+    return pog;
+  }
+
+  public static Vector getCodons(String res)
+  {
+    if (codonHash.containsKey(res))
+    {
+      return (Vector) codonHash.get(res);
+    }
+
+    return null;
+  }
+
+  public static String codonTranslate(String codon)
+  {
+    Enumeration e = codonHash.keys();
+
+    while (e.hasMoreElements())
+    {
+      String key = (String) e.nextElement();
+      Vector tmp = (Vector) codonHash.get(key);
+
+      if (tmp.contains(codon.toUpperCase()))
+      {
+        return key;
+      }
+    }
+
+    return null;
+  }
+}
index c11e1ec..acf2ae5 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class ScoreColourScheme extends ResidueColourScheme\r
-{\r
-    /** DOCUMENT ME!! */\r
-    public double min;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public double max;\r
-\r
-    /** DOCUMENT ME!! */\r
-    public double[] scores;\r
-\r
-    /**\r
-     * Creates a new ScoreColourScheme object.\r
-     *\r
-     * @param scores DOCUMENT ME!\r
-     * @param min DOCUMENT ME!\r
-     * @param max DOCUMENT ME!\r
-     */\r
-    public ScoreColourScheme(double[] scores, double min, double max)\r
-    {\r
-        super();\r
-\r
-        this.scores = scores;\r
-        this.min = min;\r
-        this.max = max;\r
-\r
-        // Make colours in constructor\r
-        // Why wasn't this done earlier?\r
-        int i, iSize=scores.length;\r
-        colors = new Color[scores.length];\r
-        for (i = 0; i < iSize; i++)\r
-        {\r
-          float red = (float) (scores[i] - (float) min) / (float) (max - min);\r
-\r
-          if (red > 1.0f)\r
-          {\r
-            red = 1.0f;\r
-          }\r
-\r
-          if (red < 0.0f)\r
-          {\r
-            red = 0.0f;\r
-          }\r
-          colors[i] = makeColour(red);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param s DOCUMENT ME!\r
-     * @param j DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color findColour(String s, int j)\r
-    {\r
-        if (threshold > 0)\r
-        {\r
-            if (!aboveThreshold(s, j))\r
-            {\r
-                return Color.white;\r
-            }\r
-        }\r
-\r
-        char c = s.charAt(0);\r
-\r
-        if (jalview.util.Comparison.isGap((c)))\r
-        {\r
-            return Color.white;\r
-        }\r
-\r
-        currentColour = colors[((Integer) ResidueProperties.aaHash.get(s)).intValue()];\r
-\r
-        if(conservationColouring)\r
-         applyConservation(j);\r
-\r
-        return currentColour;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color makeColour(float c)\r
-    {\r
-        return new Color(c, (float) 0.0, (float) 1.0 - c);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ScoreColourScheme extends ResidueColourScheme
+{
+    /** DOCUMENT ME!! */
+    public double min;
+
+    /** DOCUMENT ME!! */
+    public double max;
+
+    /** DOCUMENT ME!! */
+    public double[] scores;
+
+    /**
+     * Creates a new ScoreColourScheme object.
+     *
+     * @param scores DOCUMENT ME!
+     * @param min DOCUMENT ME!
+     * @param max DOCUMENT ME!
+     */
+    public ScoreColourScheme(double[] scores, double min, double max)
+    {
+        super();
+
+        this.scores = scores;
+        this.min = min;
+        this.max = max;
+
+        // Make colours in constructor
+        // Why wasn't this done earlier?
+        int i, iSize=scores.length;
+        colors = new Color[scores.length];
+        for (i = 0; i < iSize; i++)
+        {
+          float red = (float) (scores[i] - (float) min) / (float) (max - min);
+
+          if (red > 1.0f)
+          {
+            red = 1.0f;
+          }
+
+          if (red < 0.0f)
+          {
+            red = 0.0f;
+          }
+          colors[i] = makeColour(red);
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param s DOCUMENT ME!
+     * @param j DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color findColour(String s, int j)
+    {
+        if (threshold > 0)
+        {
+            if (!aboveThreshold(s, j))
+            {
+                return Color.white;
+            }
+        }
+
+        char c = s.charAt(0);
+
+        if (jalview.util.Comparison.isGap((c)))
+        {
+            return Color.white;
+        }
+
+        currentColour = colors[((Integer) ResidueProperties.aaHash.get(s)).intValue()];
+
+        if(conservationColouring)
+         applyConservation(j);
+
+        return currentColour;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color makeColour(float c)
+    {
+        return new Color(c, (float) 0.0, (float) 1.0 - c);
+    }
+}
index 9944155..211bd24 100755 (executable)
@@ -1,52 +1,52 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class StrandColourScheme extends ScoreColourScheme\r
-{\r
-    /**\r
-     * Creates a new StrandColourScheme object.\r
-     */\r
-    public StrandColourScheme()\r
-    {\r
-        super(ResidueProperties.strand, ResidueProperties.strandmin,\r
-            ResidueProperties.strandmax);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color makeColour(float c)\r
-    {\r
-        return new Color(c, c, (float) 1.0 - c);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class StrandColourScheme extends ScoreColourScheme
+{
+    /**
+     * Creates a new StrandColourScheme object.
+     */
+    public StrandColourScheme()
+    {
+        super(ResidueProperties.strand, ResidueProperties.strandmin,
+            ResidueProperties.strandmax);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color makeColour(float c)
+    {
+        return new Color(c, c, (float) 1.0 - c);
+    }
+}
index 6220eaa..692994c 100755 (executable)
@@ -1,28 +1,28 @@
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-public class TaylorColourScheme\r
-    extends ResidueColourScheme\r
-{\r
-  public TaylorColourScheme()\r
-  {\r
-    super(ResidueProperties.taylor, 0);\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+public class TaylorColourScheme
+    extends ResidueColourScheme
+{
+  public TaylorColourScheme()
+  {
+    super(ResidueProperties.taylor, 0);
+  }
+}
index dbf36e3..0cfcce8 100755 (executable)
@@ -1,52 +1,52 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class TurnColourScheme extends ScoreColourScheme\r
-{\r
-    /**\r
-     * Creates a new TurnColourScheme object.\r
-     */\r
-    public TurnColourScheme()\r
-    {\r
-        super(ResidueProperties.turn, ResidueProperties.turnmin,\r
-            ResidueProperties.turnmax);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param c DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public Color makeColour(float c)\r
-    {\r
-        return new Color(c, 1 - c, 1 - c);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+import java.awt.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class TurnColourScheme extends ScoreColourScheme
+{
+    /**
+     * Creates a new TurnColourScheme object.
+     */
+    public TurnColourScheme()
+    {
+        super(ResidueProperties.turn, ResidueProperties.turnmin,
+            ResidueProperties.turnmax);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Color makeColour(float c)
+    {
+        return new Color(c, 1 - c, 1 - c);
+    }
+}
index 4b963fe..90d6264 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.schemes;\r
-\r
-import java.awt.*;\r
-\r
-public class UserColourScheme\r
-    extends ResidueColourScheme\r
-{\r
-  protected String schemeName;\r
-\r
-  public UserColourScheme(String colour)\r
-  {\r
-    Color col = null;\r
-    try{\r
-      int value = Integer.parseInt(colour, 16);\r
-      col = new Color(value);\r
-    }\r
-    catch(NumberFormatException ex){}\r
-\r
-    if(col==null)\r
-      col = ColourSchemeProperty.getAWTColorFromName(colour);\r
-\r
-    if(col==null)\r
-    {try{\r
-      java.util.StringTokenizer st = new java.util.StringTokenizer(colour, ",");\r
-      int r = Integer.parseInt( st.nextToken() );\r
-      int g = Integer.parseInt( st.nextToken() );\r
-      int b = Integer.parseInt( st.nextToken() );\r
-      col = new Color(r,g,b);\r
-    }catch(Exception ex){}\r
-    }\r
-\r
-    if(col==null)\r
-    {\r
-      System.out.println("Unknown colour!! "+colour);\r
-    }\r
-\r
-    colors = new Color[24];\r
-    for(int i=0; i<24; i++)\r
-      colors[i] = col;\r
-  }\r
-\r
-  public UserColourScheme(Color[] newColors)\r
-  {\r
-    colors = newColors;\r
-  }\r
-\r
-  public Color[] getColours()\r
-  {\r
-    return colors;\r
-  }\r
-\r
-  public void setName(String name)\r
-  {\r
-    schemeName = name;\r
-  }\r
-  public String getName()\r
-  {\r
-    return schemeName;\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.schemes;
+
+import java.awt.*;
+import java.util.StringTokenizer;
+
+public class UserColourScheme
+    extends ResidueColourScheme
+{
+  Color [] lowerCaseColours;
+
+  protected String schemeName;
+
+  public UserColourScheme()
+  {  }
+
+  public UserColourScheme(Color[] newColors)
+  {
+    colors = newColors;
+  }
+
+  public UserColourScheme(String colour)
+  {
+    Color col = getColourFromString(colour);
+
+    if(col==null)
+    {
+      System.out.println("Unknown colour!! "+colour);
+      col = createColourFromName(colour);
+    }
+
+    colors = new Color[24];
+    for(int i=0; i<24; i++)
+      colors[i] = col;
+  }
+
+  public Color[] getColours()
+  {
+    return colors;
+  }
+
+  public Color[] getLowerCaseColours()
+  {
+    return lowerCaseColours;
+  }
+
+  public void setName(String name)
+  {
+    schemeName = name;
+  }
+
+  public String getName()
+  {
+    return schemeName;
+  }
+
+  public Color getColourFromString(String colour)
+  {
+    colour = colour.trim();
+
+    Color col = null;
+    try
+    {
+      int value = Integer.parseInt(colour, 16);
+      col = new Color(value);
+    }
+    catch (NumberFormatException ex)
+    {}
+
+    if (col == null)
+      col = ColourSchemeProperty.getAWTColorFromName(colour);
+
+    if (col == null)
+    {
+      try
+      {
+        java.util.StringTokenizer st = new java.util.StringTokenizer(colour,
+            ",");
+        int r = Integer.parseInt(st.nextToken());
+        int g = Integer.parseInt(st.nextToken());
+        int b = Integer.parseInt(st.nextToken());
+        col = new Color(r, g, b);
+      }
+      catch (Exception ex)
+      {}
+    }
+
+    return col;
+
+  }
+
+  public Color createColourFromName(String name)
+  {
+    int r, g, b;
+
+    int lsize = name.length();
+    int start = 0, end = lsize / 3;
+
+    int rgbOffset = Math.abs(name.hashCode() % 10) * 15;
+
+    r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
+    start = end;
+    end += lsize / 3;
+    if (end > lsize)
+      end = lsize;
+
+    g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
+
+    b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20;
+
+    Color color = new Color(r, g, b);
+
+    return color;
+  }
+
+  public void parseAppletParameter(String paramValue)
+  {
+    StringTokenizer st = new StringTokenizer(paramValue, ";");
+    StringTokenizer st2;
+    String token=null, colour, residues, residue;
+    try{
+      while (st.hasMoreElements())
+      {
+        token = st.nextToken().trim();
+        residues = token.substring(0, token.indexOf("="));
+        colour = token.substring(token.indexOf("=") + 1);
+
+        st2 = new StringTokenizer(residues, " ,");
+        while (st2.hasMoreTokens())
+        {
+          token = st2.nextToken();
+          if(token.equalsIgnoreCase("lowerCase"))
+          {
+            if (lowerCaseColours == null)
+              lowerCaseColours = new Color[23];
+            for (int i = 0; i < 23; i++)
+              if (lowerCaseColours[i] == null)
+                lowerCaseColours[i] = getColourFromString(colour);
+
+              continue;
+          }
+
+          int colIndex =
+              ( (Integer) ResidueProperties.aaHash.
+               get(token)).intValue();
+
+          if(token.equals(token.toLowerCase()))
+          {
+            if(lowerCaseColours==null)
+            {
+              lowerCaseColours = new Color[23];
+            }
+            lowerCaseColours[colIndex] = getColourFromString(colour);
+          }
+          else
+            colors[colIndex] = getColourFromString(colour);
+        }
+      }
+    }
+    catch(Exception ex)
+  {
+    System.out.println("Error parsing userDefinedColours:\n"
+                       +token+"\n"+ex);
+  }
+
+  }
+
+
+
+  public Color findColour(String s, int j)
+  {
+      int index = ((Integer) (ResidueProperties.aaHash.get(s))).intValue();
+
+      if ((threshold == 0) || aboveThreshold(ResidueProperties.aa[index], j))
+      {
+        if(lowerCaseColours!=null && 'a' <= s.charAt(0) && s.charAt(0) <= 'z')
+          currentColour = lowerCaseColours[index];
+        else
+          currentColour = colors[index];
+      }
+      else
+      {
+          currentColour = Color.white;
+      }
+
+      if(conservationColouring)
+        applyConservation(j);
+
+
+      return currentColour;
+   }
+
+   public void setLowerCaseColours(Color [] lcolours)
+   {
+     lowerCaseColours = lcolours;
+   }
+
+}
index 4f5c42a..8b21fda 100755 (executable)
@@ -1,37 +1,37 @@
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.schemes;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class ZappoColourScheme extends ResidueColourScheme\r
-{\r
-    /**\r
-     * Creates a new ZappoColourScheme object.\r
-     */\r
-    public ZappoColourScheme()\r
-    {\r
-        super(ResidueProperties.color, 0);\r
-    }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.schemes;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ZappoColourScheme extends ResidueColourScheme
+{
+    /**
+     * Creates a new ZappoColourScheme object.
+     */
+    public ZappoColourScheme()
+    {
+        super(ResidueProperties.color, 0);
+    }
+}
index d912173..2fa3b97 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.util;\r
-\r
-import java.io.*;\r
-import java.lang.reflect.*;\r
-\r
-/**\r
- * BrowserLauncher is a class that provides one static method, openURL, which opens the default\r
- * web browser for the current user of the system to the given URL.  It may support other\r
- * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously\r
- * tested and is not guaranteed to work.\r
- * <p>\r
- * Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms\r
- * that are not part of the standard JDK.  What we're trying to do, though, is to take something\r
- * that's frequently desirable but inherently platform-specific -- opening a default browser --\r
- * and allow programmers (you, for example) to do so without worrying about dropping into native\r
- * code or doing anything else similarly evil.\r
- * <p>\r
- * Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without\r
- * modification or a need for additional libraries.  All classes that are required on certain\r
- * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not\r
- * found, will not cause this to do anything other than returning an error when opening the\r
- * browser.\r
- * <p>\r
- * There are certain system requirements for this class, as it's running through Runtime.exec(),\r
- * which is Java's way of making a native system call.  Currently, this requires that a Macintosh\r
- * have a Finder which supports the GURL event, which is true for Mac OS 8.0 and 8.1 systems that\r
- * have the Internet Scripting AppleScript dictionary installed in the Scripting Additions folder\r
- * in the Extensions folder (which is installed by default as far as I know under Mac OS 8.0 and\r
- * 8.1), and for all Mac OS 8.5 and later systems.  On Windows, it only runs under Win32 systems\r
- * (Windows 95, 98, and NT 4.0, as well as later versions of all).  On other systems, this drops\r
- * back from the inherently platform-sensitive concept of a default browser and simply attempts\r
- * to launch Netscape via a shell command.\r
- * <p>\r
- * This code is Copyright 1999-2001 by Eric Albert (ejalbert\@cs.stanford.edu) and may be\r
- * redistributed or modified in any form without restrictions as long as the portion of this\r
- * comment from this paragraph through the end of the comment is not removed.  The author\r
- * requests that he be notified of any application, applet, or other binary that makes use of\r
- * this code, but that's more out of curiosity than anything and is not required.  This software\r
- * includes no warranty.  The author is not repsonsible for any loss of data or functionality\r
- * or any adverse or unexpected effects of using this software.\r
- * <p>\r
- * Credits:\r
- * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)\r
- * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,\r
- * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk\r
- *\r
- * @author Eric Albert (<a href="mailto:ejalbert@cs.stanford.edu">ejalbert@cs.stanford.edu</a>)\r
- * @version 1.4b1 (Released June 20, 2001)\r
- */\r
-public class BrowserLauncher\r
-{\r
-  /**\r
-   * The Java virtual machine that we are running on.  Actually, in most cases we only care\r
-   * about the operating system, but some operating systems require us to switch on the VM. */\r
-  private static int jvm;\r
-\r
-  /** The browser for the system */\r
-  private static Object browser;\r
-\r
-  /**\r
-   * Caches whether any classes, methods, and fields that are not part of the JDK and need to\r
-   * be dynamically loaded at runtime loaded successfully.\r
-   * <p>\r
-   * Note that if this is <code>false</code>, <code>openURL()</code> will always return an\r
-   * IOException.\r
-   */\r
-  private static boolean loadedWithoutErrors;\r
-\r
-  /** The com.apple.mrj.MRJFileUtils class */\r
-  private static Class mrjFileUtilsClass;\r
-\r
-  /** The com.apple.mrj.MRJOSType class */\r
-  private static Class mrjOSTypeClass;\r
-\r
-  /** The com.apple.MacOS.AEDesc class */\r
-  private static Class aeDescClass;\r
-\r
-  /** The &lt;init&gt;(int) method of com.apple.MacOS.AETarget */\r
-  private static Constructor aeTargetConstructor;\r
-\r
-  /** The &lt;init&gt;(int, int, int) method of com.apple.MacOS.AppleEvent */\r
-  private static Constructor appleEventConstructor;\r
-\r
-  /** The &lt;init&gt;(String) method of com.apple.MacOS.AEDesc */\r
-  private static Constructor aeDescConstructor;\r
-\r
-  /** The findFolder method of com.apple.mrj.MRJFileUtils */\r
-  private static Method findFolder;\r
-\r
-  /** The getFileCreator method of com.apple.mrj.MRJFileUtils */\r
-  private static Method getFileCreator;\r
-\r
-  /** The getFileType method of com.apple.mrj.MRJFileUtils */\r
-  private static Method getFileType;\r
-\r
-  /** The openURL method of com.apple.mrj.MRJFileUtils */\r
-  private static Method openURL;\r
-\r
-  /** The makeOSType method of com.apple.MacOS.OSUtils */\r
-  private static Method makeOSType;\r
-\r
-  /** The putParameter method of com.apple.MacOS.AppleEvent */\r
-  private static Method putParameter;\r
-\r
-  /** The sendNoReply method of com.apple.MacOS.AppleEvent */\r
-  private static Method sendNoReply;\r
-\r
-  /** Actually an MRJOSType pointing to the System Folder on a Macintosh */\r
-  private static Object kSystemFolderType;\r
-\r
-  /** The keyDirectObject AppleEvent parameter type */\r
-  private static Integer keyDirectObject;\r
-\r
-  /** The kAutoGenerateReturnID AppleEvent code */\r
-  private static Integer kAutoGenerateReturnID;\r
-\r
-  /** The kAnyTransactionID AppleEvent code */\r
-  private static Integer kAnyTransactionID;\r
-\r
-  /** The linkage object required for JDirect 3 on Mac OS X. */\r
-  private static Object linkage;\r
-\r
-  /** The framework to reference on Mac OS X */\r
-  private static final String JDirect_MacOSX = "/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox";\r
-\r
-  /** JVM constant for MRJ 2.0 */\r
-  private static final int MRJ_2_0 = 0;\r
-\r
-  /** JVM constant for MRJ 2.1 or later */\r
-  private static final int MRJ_2_1 = 1;\r
-\r
-  /** JVM constant for Java on Mac OS X 10.0 (MRJ 3.0) */\r
-  private static final int MRJ_3_0 = 3;\r
-\r
-  /** JVM constant for MRJ 3.1 */\r
-  private static final int MRJ_3_1 = 4;\r
-\r
-  /** JVM constant for any Windows NT JVM */\r
-  private static final int WINDOWS_NT = 5;\r
-\r
-  /** JVM constant for any Windows 9x JVM */\r
-  private static final int WINDOWS_9x = 6;\r
-\r
-  /** JVM constant for any other platform */\r
-  private static final int OTHER = -1;\r
-\r
-  /**\r
-   * The file type of the Finder on a Macintosh.  Hardcoding "Finder" would keep non-U.S. English\r
-   * systems from working properly.\r
-   */\r
-  private static final String FINDER_TYPE = "FNDR";\r
-\r
-  /**\r
-   * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the\r
-   * application.\r
-   */\r
-  private static final String FINDER_CREATOR = "MACS";\r
-\r
-  /** The name for the AppleEvent type corresponding to a GetURL event. */\r
-  private static final String GURL_EVENT = "GURL";\r
-\r
-  /**\r
-   * The first parameter that needs to be passed into Runtime.exec() to open the default web\r
-   * browser on Windows.\r
-   */\r
-  private static final String FIRST_WINDOWS_PARAMETER = "/c";\r
-\r
-  /** The second parameter for Runtime.exec() on Windows. */\r
-  private static final String SECOND_WINDOWS_PARAMETER = "start";\r
-\r
-  /**\r
-   * The third parameter for Runtime.exec() on Windows.  This is a "title"\r
-   * parameter that the command line expects.  Setting this parameter allows\r
-   * URLs containing spaces to work.\r
-   */\r
-  private static final String THIRD_WINDOWS_PARAMETER = "\"\"";\r
-\r
-  /**\r
-   * The shell parameters for Netscape that opens a given URL in an already-open copy of Netscape\r
-   * on many command-line systems.\r
-   */\r
-  private static final String NETSCAPE_REMOTE_PARAMETER = "-remote";\r
-  private static final String NETSCAPE_OPEN_PARAMETER_START = "openURL(";\r
-  private static final String NETSCAPE_OPEN_NEW_WINDOW = ", new-window";\r
-  private static final String NETSCAPE_OPEN_PARAMETER_END = ")";\r
-\r
-  /**\r
-   * The message from any exception thrown throughout the initialization process.\r
-   */\r
-  private static String errorMessage;\r
-\r
-  /**\r
-   * An initialization block that determines the operating system and loads the necessary\r
-   * runtime data.\r
-   */\r
-  static\r
-  {\r
-    loadedWithoutErrors = true;\r
-\r
-    String osName = System.getProperty("os.name");\r
-\r
-    if (osName.startsWith("Mac OS"))\r
-    {\r
-      String mrjVersion = System.getProperty("mrj.version");\r
-      String majorMRJVersion = mrjVersion.substring(0, 3);\r
-\r
-      try\r
-      {\r
-        double version = Double.valueOf(majorMRJVersion).doubleValue();\r
-\r
-        if (version == 2)\r
-        {\r
-          jvm = MRJ_2_0;\r
-        }\r
-        else if ( (version >= 2.1) && (version < 3))\r
-        {\r
-          // Assume that all 2.x versions of MRJ work the same.  MRJ 2.1 actually\r
-          // works via Runtime.exec() and 2.2 supports that but has an openURL() method\r
-          // as well that we currently ignore.\r
-          jvm = MRJ_2_1;\r
-        }\r
-        else if (version == 3.0)\r
-        {\r
-          jvm = MRJ_3_0;\r
-        }\r
-        else if (version >= 3.1)\r
-        {\r
-          // Assume that all 3.1 and later versions of MRJ work the same.\r
-          jvm = MRJ_3_1;\r
-        }\r
-        else\r
-        {\r
-          loadedWithoutErrors = false;\r
-          errorMessage = "Unsupported MRJ version: " + version;\r
-        }\r
-      }\r
-      catch (NumberFormatException nfe)\r
-      {\r
-        loadedWithoutErrors = false;\r
-        errorMessage = "Invalid MRJ version: " + mrjVersion;\r
-      }\r
-    }\r
-    else if (osName.startsWith("Windows"))\r
-    {\r
-      if (osName.indexOf("9") != -1)\r
-      {\r
-        jvm = WINDOWS_9x;\r
-      }\r
-      else\r
-      {\r
-        jvm = WINDOWS_NT;\r
-      }\r
-    }\r
-    else\r
-    {\r
-      jvm = OTHER;\r
-    }\r
-\r
-    if (loadedWithoutErrors)\r
-    { // if we haven't hit any errors yet\r
-      loadedWithoutErrors = loadClasses();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * This class should be never be instantiated; this just ensures so.\r
-   */\r
-  private BrowserLauncher()\r
-  {\r
-  }\r
-\r
-  /**\r
-   * Called by a static initializer to load any classes, fields, and methods required at runtime\r
-   * to locate the user's web browser.\r
-   * @return <code>true</code> if all intialization succeeded\r
-   *                        <code>false</code> if any portion of the initialization failed\r
-   */\r
-  private static boolean loadClasses()\r
-  {\r
-    switch (jvm)\r
-    {\r
-      case MRJ_2_0:\r
-\r
-        try\r
-        {\r
-          Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");\r
-          Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");\r
-          Class appleEventClass = Class.forName(\r
-              "com.apple.MacOS.AppleEvent");\r
-          Class aeClass = Class.forName("com.apple.MacOS.ae");\r
-          aeDescClass = Class.forName("com.apple.MacOS.AEDesc");\r
-\r
-          aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class[]\r
-              {\r
-              int.class\r
-          });\r
-          appleEventConstructor = appleEventClass.getDeclaredConstructor(new\r
-              Class[]\r
-              {\r
-              int.class, int.class, aeTargetClass, int.class,\r
-              int.class\r
-          });\r
-          aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[]\r
-              {\r
-              String.class\r
-          });\r
-\r
-          makeOSType = osUtilsClass.getDeclaredMethod("makeOSType",\r
-              new Class[]\r
-              {String.class});\r
-          putParameter = appleEventClass.getDeclaredMethod("putParameter",\r
-              new Class[]\r
-              {int.class, aeDescClass});\r
-          sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply",\r
-              new Class[]\r
-              {});\r
-\r
-          Field keyDirectObjectField = aeClass.getDeclaredField(\r
-              "keyDirectObject");\r
-          keyDirectObject = (Integer) keyDirectObjectField.get(null);\r
-\r
-          Field autoGenerateReturnIDField = appleEventClass.getDeclaredField(\r
-              "kAutoGenerateReturnID");\r
-          kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);\r
-\r
-          Field anyTransactionIDField = appleEventClass.getDeclaredField(\r
-              "kAnyTransactionID");\r
-          kAnyTransactionID = (Integer) anyTransactionIDField.get(null);\r
-        }\r
-        catch (ClassNotFoundException cnfe)\r
-        {\r
-          errorMessage = cnfe.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (NoSuchMethodException nsme)\r
-        {\r
-          errorMessage = nsme.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (NoSuchFieldException nsfe)\r
-        {\r
-          errorMessage = nsfe.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (IllegalAccessException iae)\r
-        {\r
-          errorMessage = iae.getMessage();\r
-\r
-          return false;\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      case MRJ_2_1:\r
-\r
-        try\r
-        {\r
-          mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");\r
-          mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");\r
-\r
-          Field systemFolderField = mrjFileUtilsClass.getDeclaredField(\r
-              "kSystemFolderType");\r
-          kSystemFolderType = systemFolderField.get(null);\r
-          findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder",\r
-              new Class[]\r
-              {mrjOSTypeClass});\r
-          getFileCreator = mrjFileUtilsClass.getDeclaredMethod("getFileCreator",\r
-              new Class[]\r
-              {File.class});\r
-          getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType",\r
-              new Class[]\r
-              {File.class});\r
-        }\r
-        catch (ClassNotFoundException cnfe)\r
-        {\r
-          errorMessage = cnfe.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (NoSuchFieldException nsfe)\r
-        {\r
-          errorMessage = nsfe.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (NoSuchMethodException nsme)\r
-        {\r
-          errorMessage = nsme.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (SecurityException se)\r
-        {\r
-          errorMessage = se.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (IllegalAccessException iae)\r
-        {\r
-          errorMessage = iae.getMessage();\r
-\r
-          return false;\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      case MRJ_3_0:\r
-\r
-        try\r
-        {\r
-          Class linker = Class.forName("com.apple.mrj.jdirect.Linker");\r
-          Constructor constructor = linker.getConstructor(new Class[]\r
-              {\r
-              Class.class\r
-          });\r
-          linkage = constructor.newInstance(new Object[]\r
-                                            {\r
-                                            BrowserLauncher.class\r
-          });\r
-        }\r
-        catch (ClassNotFoundException cnfe)\r
-        {\r
-          errorMessage = cnfe.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (NoSuchMethodException nsme)\r
-        {\r
-          errorMessage = nsme.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (InvocationTargetException ite)\r
-        {\r
-          errorMessage = ite.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (InstantiationException ie)\r
-        {\r
-          errorMessage = ie.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (IllegalAccessException iae)\r
-        {\r
-          errorMessage = iae.getMessage();\r
-\r
-          return false;\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      case MRJ_3_1:\r
-\r
-        try\r
-        {\r
-          mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");\r
-          openURL = mrjFileUtilsClass.getDeclaredMethod("openURL",\r
-              new Class[]\r
-              {String.class});\r
-        }\r
-        catch (ClassNotFoundException cnfe)\r
-        {\r
-          errorMessage = cnfe.getMessage();\r
-\r
-          return false;\r
-        }\r
-        catch (NoSuchMethodException nsme)\r
-        {\r
-          errorMessage = nsme.getMessage();\r
-\r
-          return false;\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      default:\r
-        break;\r
-    }\r
-\r
-    return true;\r
-  }\r
-\r
-  /**\r
-   * Attempts to locate the default web browser on the local system.    s results so it\r
-   * only locates the browser once for each use of this class per JVM instance.\r
-   * @return The browser for the system.  Note that this may not be what you would consider\r
-   *                        to be a standard web browser; instead, it's the application that gets called to\r
-   *                        open the default web browser.  In some cases, this will be a non-String object\r
-   *                        that provides the means of calling the default browser.\r
-   */\r
-  private static Object locateBrowser()\r
-  {\r
-    if (browser != null)\r
-    {\r
-      return browser;\r
-    }\r
-\r
-    switch (jvm)\r
-    {\r
-      case MRJ_2_0:\r
-\r
-        try\r
-        {\r
-          Integer finderCreatorCode = (Integer) makeOSType.invoke(null,\r
-              new Object[]\r
-              {FINDER_CREATOR});\r
-          Object aeTarget = aeTargetConstructor.newInstance(new Object[]\r
-              {\r
-              finderCreatorCode\r
-          });\r
-          Integer gurlType = (Integer) makeOSType.invoke(null,\r
-              new Object[]\r
-              {GURL_EVENT});\r
-          Object appleEvent = appleEventConstructor.newInstance(new Object[]\r
-              {\r
-              gurlType, gurlType, aeTarget, kAutoGenerateReturnID,\r
-              kAnyTransactionID\r
-          });\r
-\r
-          // Don't set browser = appleEvent because then the next time we call\r
-          // locateBrowser(), we'll get the same AppleEvent, to which we'll already have\r
-          // added the relevant parameter. Instead, regenerate the AppleEvent every time.\r
-          // There's probably a way to do this better; if any has any ideas, please let\r
-          // me know.\r
-          return appleEvent;\r
-        }\r
-        catch (IllegalAccessException iae)\r
-        {\r
-          browser = null;\r
-          errorMessage = iae.getMessage();\r
-\r
-          return browser;\r
-        }\r
-        catch (InstantiationException ie)\r
-        {\r
-          browser = null;\r
-          errorMessage = ie.getMessage();\r
-\r
-          return browser;\r
-        }\r
-        catch (InvocationTargetException ite)\r
-        {\r
-          browser = null;\r
-          errorMessage = ite.getMessage();\r
-\r
-          return browser;\r
-        }\r
-\r
-        case MRJ_2_1:\r
-\r
-          File systemFolder;\r
-\r
-          try\r
-          {\r
-            systemFolder = (File) findFolder.invoke(null,\r
-                new Object[]\r
-                {kSystemFolderType});\r
-          }\r
-          catch (IllegalArgumentException iare)\r
-          {\r
-            browser = null;\r
-            errorMessage = iare.getMessage();\r
-\r
-            return browser;\r
-          }\r
-          catch (IllegalAccessException iae)\r
-          {\r
-            browser = null;\r
-            errorMessage = iae.getMessage();\r
-\r
-            return browser;\r
-          }\r
-          catch (InvocationTargetException ite)\r
-          {\r
-            browser = null;\r
-            errorMessage = ite.getTargetException().getClass() + ": " +\r
-                ite.getTargetException().getMessage();\r
-\r
-            return browser;\r
-          }\r
-\r
-          String[] systemFolderFiles = systemFolder.list();\r
-\r
-          // Avoid a FilenameFilter because that can't be stopped mid-list\r
-          for (int i = 0; i < systemFolderFiles.length; i++)\r
-          {\r
-            try\r
-            {\r
-              File file = new File(systemFolder, systemFolderFiles[i]);\r
-\r
-              if (!file.isFile())\r
-              {\r
-                continue;\r
-              }\r
-\r
-              // We're looking for a file with a creator code of 'MACS' and\r
-              // a type of 'FNDR'.  Only requiring the type results in non-Finder\r
-              // applications being picked up on certain Mac OS 9 systems,\r
-              // especially German ones, and sending a GURL event to those\r
-              // applications results in a logout under Multiple Users.\r
-              Object fileType = getFileType.invoke(null,\r
-                  new Object[]\r
-                  {file});\r
-\r
-              if (FINDER_TYPE.equals(fileType.toString()))\r
-              {\r
-                Object fileCreator = getFileCreator.invoke(null,\r
-                    new Object[]\r
-                    {file});\r
-\r
-                if (FINDER_CREATOR.equals(fileCreator.toString()))\r
-                {\r
-                  browser = file.toString(); // Actually the Finder, but that's OK\r
-\r
-                  return browser;\r
-                }\r
-              }\r
-            }\r
-            catch (IllegalArgumentException iare)\r
-            {\r
-              errorMessage = iare.getMessage();\r
-\r
-              return null;\r
-            }\r
-            catch (IllegalAccessException iae)\r
-            {\r
-              browser = null;\r
-              errorMessage = iae.getMessage();\r
-\r
-              return browser;\r
-            }\r
-            catch (InvocationTargetException ite)\r
-            {\r
-              browser = null;\r
-              errorMessage = ite.getTargetException().getClass() + ": " +\r
-                  ite.getTargetException().getMessage();\r
-\r
-              return browser;\r
-            }\r
-          }\r
-\r
-          browser = null;\r
-\r
-          break;\r
-\r
-      case MRJ_3_0:\r
-      case MRJ_3_1:\r
-        browser = ""; // Return something non-null\r
-\r
-        break;\r
-\r
-      case WINDOWS_NT:\r
-        browser = "cmd.exe";\r
-\r
-        break;\r
-\r
-      case WINDOWS_9x:\r
-        browser = "command.com";\r
-\r
-        break;\r
-\r
-      case OTHER:\r
-      default:\r
-        browser = jalview.bin.Cache.getDefault("DEFAULT_BROWSER", "firefox");\r
-\r
-        break;\r
-    }\r
-\r
-    return browser;\r
-  }\r
-  /**\r
-   * used to ensure that browser is up-to-date after a configuration\r
-   * change (Unix DEFAULT_BROWSER property change).\r
-   */\r
-  public static void resetBrowser() {\r
-    browser = null;\r
-  }\r
-  /**\r
-   * Attempts to open the default web browser to the given URL.\r
-   * @param url The URL to open\r
-   * @throws IOException If the web browser could not be located or does not run\r
-   */\r
-  public static void openURL(String url)\r
-      throws IOException\r
-  {\r
-    if (!loadedWithoutErrors)\r
-    {\r
-      throw new IOException("Exception in finding browser: " +\r
-                            errorMessage);\r
-    }\r
-\r
-    Object browser = locateBrowser();\r
-\r
-    if (browser == null)\r
-    {\r
-      throw new IOException("Unable to locate browser: " + errorMessage);\r
-    }\r
-\r
-    switch (jvm)\r
-    {\r
-      case MRJ_2_0:\r
-\r
-        Object aeDesc = null;\r
-\r
-        try\r
-        {\r
-          aeDesc = aeDescConstructor.newInstance(new Object[]\r
-                                                 {url});\r
-          putParameter.invoke(browser,\r
-                              new Object[]\r
-                              {keyDirectObject, aeDesc});\r
-          sendNoReply.invoke(browser, new Object[]\r
-                             {});\r
-        }\r
-        catch (InvocationTargetException ite)\r
-        {\r
-          throw new IOException(\r
-              "InvocationTargetException while creating AEDesc: " +\r
-              ite.getMessage());\r
-        }\r
-        catch (IllegalAccessException iae)\r
-        {\r
-          throw new IOException(\r
-              "IllegalAccessException while building AppleEvent: " +\r
-              iae.getMessage());\r
-        }\r
-        catch (InstantiationException ie)\r
-        {\r
-          throw new IOException(\r
-              "InstantiationException while creating AEDesc: " +\r
-              ie.getMessage());\r
-        }\r
-        finally\r
-        {\r
-          aeDesc = null; // Encourage it to get disposed if it was created\r
-          browser = null; // Ditto\r
-        }\r
-\r
-        break;\r
-\r
-      case MRJ_2_1:\r
-        Runtime.getRuntime().exec(new String[]\r
-                                  { (String) browser, url});\r
-\r
-        break;\r
-\r
-      case MRJ_3_0:\r
-\r
-        int[] instance = new int[1];\r
-        int result = ICStart(instance, 0);\r
-\r
-        if (result == 0)\r
-        {\r
-          int[] selectionStart = new int[]\r
-              {\r
-              0};\r
-          byte[] urlBytes = url.getBytes();\r
-          int[] selectionEnd = new int[]\r
-              {\r
-              urlBytes.length};\r
-          result = ICLaunchURL(instance[0], new byte[]\r
-                               {0}, urlBytes,\r
-                               urlBytes.length, selectionStart, selectionEnd);\r
-\r
-          if (result == 0)\r
-          {\r
-            // Ignore the return value; the URL was launched successfully\r
-            // regardless of what happens here.\r
-            ICStop(instance);\r
-          }\r
-          else\r
-          {\r
-            throw new IOException("Unable to launch URL: " + result);\r
-          }\r
-        }\r
-        else\r
-        {\r
-          throw new IOException(\r
-              "Unable to create an Internet Config instance: " + result);\r
-        }\r
-\r
-        break;\r
-\r
-      case MRJ_3_1:\r
-\r
-        try\r
-        {\r
-          openURL.invoke(null, new Object[]\r
-                         {url});\r
-        }\r
-        catch (InvocationTargetException ite)\r
-        {\r
-          throw new IOException(\r
-              "InvocationTargetException while calling openURL: " +\r
-              ite.getMessage());\r
-        }\r
-        catch (IllegalAccessException iae)\r
-        {\r
-          throw new IOException(\r
-              "IllegalAccessException while calling openURL: " +\r
-              iae.getMessage());\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      case WINDOWS_NT:\r
-      case WINDOWS_9x:\r
-\r
-        // Add quotes around the URL to allow ampersands and other special\r
-        // characters to work.\r
-        Process process = Runtime.getRuntime().exec(new String[]\r
-            {\r
-            (String) browser, FIRST_WINDOWS_PARAMETER,\r
-            SECOND_WINDOWS_PARAMETER, THIRD_WINDOWS_PARAMETER,\r
-            '"' + url + '"'\r
-        });\r
-\r
-        // This avoids a memory leak on some versions of Java on Windows.\r
-        // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.\r
-        try\r
-        {\r
-          process.waitFor();\r
-          process.exitValue();\r
-        }\r
-        catch (InterruptedException ie)\r
-        {\r
-          throw new IOException(\r
-              "InterruptedException while launching browser: " +\r
-              ie.getMessage());\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      case OTHER:\r
-\r
-        // Assume that we're on Unix and that Netscape (actually Firefox) is installed\r
-        // First, attempt to open the URL in a currently running session of Netscape\r
-        // JBPNote log debug\r
-\r
-        /* System.out.println("Executing : "+browser+" "+\r
-         NETSCAPE_REMOTE_PARAMETER+" "+\r
-         NETSCAPE_OPEN_PARAMETER_START +\r
-         url +\r
-         NETSCAPE_OPEN_NEW_WINDOW +\r
-         NETSCAPE_OPEN_PARAMETER_END);\r
-         */\r
-        process = Runtime.getRuntime().exec(new String[]\r
-                                            {\r
-                                            (String) browser,\r
-                                            NETSCAPE_REMOTE_PARAMETER,\r
-\r
-                                            NETSCAPE_OPEN_PARAMETER_START + url +\r
-                                            NETSCAPE_OPEN_NEW_WINDOW +\r
-                                            NETSCAPE_OPEN_PARAMETER_END\r
-        });\r
-\r
-        try\r
-        {\r
-          int exitCode = process.waitFor();\r
-\r
-          if (exitCode != 0)\r
-          { // if Netscape was not open\r
-            Runtime.getRuntime().exec(new String[]\r
-                                      { (String) browser, url});\r
-          }\r
-        }\r
-        catch (InterruptedException ie)\r
-        {\r
-          throw new IOException(\r
-              "InterruptedException while launching browser: " +\r
-              ie.getMessage());\r
-        }\r
-\r
-        break\r
-            ;\r
-\r
-      default:\r
-\r
-        // This should never occur, but if it does, we'll try the simplest thing possible\r
-        Runtime.getRuntime().exec(new String[]\r
-                                  { (String) browser, url});\r
-\r
-        break;\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Methods required for Mac OS X.  The presence of native methods does not cause\r
-   * any problems on other platforms.\r
-   */\r
-  private native static int ICStart(int[] instance, int signature);\r
-\r
-  private native static int ICStop(int[] instance);\r
-\r
-  private native static int ICLaunchURL(int instance, byte[] hint,\r
-                                        byte[] data, int len,\r
-                                        int[] selectionStart,\r
-                                        int[] selectionEnd);\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.util;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+/**
+ * BrowserLauncher is a class that provides one static method, openURL, which opens the default
+ * web browser for the current user of the system to the given URL.  It may support other
+ * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously
+ * tested and is not guaranteed to work.
+ * <p>
+ * Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms
+ * that are not part of the standard JDK.  What we're trying to do, though, is to take something
+ * that's frequently desirable but inherently platform-specific -- opening a default browser --
+ * and allow programmers (you, for example) to do so without worrying about dropping into native
+ * code or doing anything else similarly evil.
+ * <p>
+ * Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without
+ * modification or a need for additional libraries.  All classes that are required on certain
+ * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not
+ * found, will not cause this to do anything other than returning an error when opening the
+ * browser.
+ * <p>
+ * There are certain system requirements for this class, as it's running through Runtime.exec(),
+ * which is Java's way of making a native system call.  Currently, this requires that a Macintosh
+ * have a Finder which supports the GURL event, which is true for Mac OS 8.0 and 8.1 systems that
+ * have the Internet Scripting AppleScript dictionary installed in the Scripting Additions folder
+ * in the Extensions folder (which is installed by default as far as I know under Mac OS 8.0 and
+ * 8.1), and for all Mac OS 8.5 and later systems.  On Windows, it only runs under Win32 systems
+ * (Windows 95, 98, and NT 4.0, as well as later versions of all).  On other systems, this drops
+ * back from the inherently platform-sensitive concept of a default browser and simply attempts
+ * to launch Netscape via a shell command.
+ * <p>
+ * This code is Copyright 1999-2001 by Eric Albert (ejalbert\@cs.stanford.edu) and may be
+ * redistributed or modified in any form without restrictions as long as the portion of this
+ * comment from this paragraph through the end of the comment is not removed.  The author
+ * requests that he be notified of any application, applet, or other binary that makes use of
+ * this code, but that's more out of curiosity than anything and is not required.  This software
+ * includes no warranty.  The author is not repsonsible for any loss of data or functionality
+ * or any adverse or unexpected effects of using this software.
+ * <p>
+ * Credits:
+ * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)
+ * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,
+ * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk
+ *
+ * @author Eric Albert (<a href="mailto:ejalbert@cs.stanford.edu">ejalbert@cs.stanford.edu</a>)
+ * @version 1.4b1 (Released June 20, 2001)
+ */
+public class BrowserLauncher
+{
+  /**
+   * The Java virtual machine that we are running on.  Actually, in most cases we only care
+   * about the operating system, but some operating systems require us to switch on the VM. */
+  private static int jvm;
+
+  /** The browser for the system */
+  private static Object browser;
+
+  /**
+   * Caches whether any classes, methods, and fields that are not part of the JDK and need to
+   * be dynamically loaded at runtime loaded successfully.
+   * <p>
+   * Note that if this is <code>false</code>, <code>openURL()</code> will always return an
+   * IOException.
+   */
+  private static boolean loadedWithoutErrors;
+
+  /** The com.apple.mrj.MRJFileUtils class */
+  private static Class mrjFileUtilsClass;
+
+  /** The com.apple.mrj.MRJOSType class */
+  private static Class mrjOSTypeClass;
+
+  /** The com.apple.MacOS.AEDesc class */
+  private static Class aeDescClass;
+
+  /** The &lt;init&gt;(int) method of com.apple.MacOS.AETarget */
+  private static Constructor aeTargetConstructor;
+
+  /** The &lt;init&gt;(int, int, int) method of com.apple.MacOS.AppleEvent */
+  private static Constructor appleEventConstructor;
+
+  /** The &lt;init&gt;(String) method of com.apple.MacOS.AEDesc */
+  private static Constructor aeDescConstructor;
+
+  /** The findFolder method of com.apple.mrj.MRJFileUtils */
+  private static Method findFolder;
+
+  /** The getFileCreator method of com.apple.mrj.MRJFileUtils */
+  private static Method getFileCreator;
+
+  /** The getFileType method of com.apple.mrj.MRJFileUtils */
+  private static Method getFileType;
+
+  /** The openURL method of com.apple.mrj.MRJFileUtils */
+  private static Method openURL;
+
+  /** The makeOSType method of com.apple.MacOS.OSUtils */
+  private static Method makeOSType;
+
+  /** The putParameter method of com.apple.MacOS.AppleEvent */
+  private static Method putParameter;
+
+  /** The sendNoReply method of com.apple.MacOS.AppleEvent */
+  private static Method sendNoReply;
+
+  /** Actually an MRJOSType pointing to the System Folder on a Macintosh */
+  private static Object kSystemFolderType;
+
+  /** The keyDirectObject AppleEvent parameter type */
+  private static Integer keyDirectObject;
+
+  /** The kAutoGenerateReturnID AppleEvent code */
+  private static Integer kAutoGenerateReturnID;
+
+  /** The kAnyTransactionID AppleEvent code */
+  private static Integer kAnyTransactionID;
+
+  /** The linkage object required for JDirect 3 on Mac OS X. */
+  private static Object linkage;
+
+  /** The framework to reference on Mac OS X */
+  private static final String JDirect_MacOSX = "/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox";
+
+  /** JVM constant for MRJ 2.0 */
+  private static final int MRJ_2_0 = 0;
+
+  /** JVM constant for MRJ 2.1 or later */
+  private static final int MRJ_2_1 = 1;
+
+  /** JVM constant for Java on Mac OS X 10.0 (MRJ 3.0) */
+  private static final int MRJ_3_0 = 3;
+
+  /** JVM constant for MRJ 3.1 */
+  private static final int MRJ_3_1 = 4;
+
+  /** JVM constant for any Windows NT JVM */
+  private static final int WINDOWS_NT = 5;
+
+  /** JVM constant for any Windows 9x JVM */
+  private static final int WINDOWS_9x = 6;
+
+  /** JVM constant for any other platform */
+  private static final int OTHER = -1;
+
+  /**
+   * The file type of the Finder on a Macintosh.  Hardcoding "Finder" would keep non-U.S. English
+   * systems from working properly.
+   */
+  private static final String FINDER_TYPE = "FNDR";
+
+  /**
+   * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the
+   * application.
+   */
+  private static final String FINDER_CREATOR = "MACS";
+
+  /** The name for the AppleEvent type corresponding to a GetURL event. */
+  private static final String GURL_EVENT = "GURL";
+
+  /**
+   * The first parameter that needs to be passed into Runtime.exec() to open the default web
+   * browser on Windows.
+   */
+  private static final String FIRST_WINDOWS_PARAMETER = "/c";
+
+  /** The second parameter for Runtime.exec() on Windows. */
+  private static final String SECOND_WINDOWS_PARAMETER = "start";
+
+  /**
+   * The third parameter for Runtime.exec() on Windows.  This is a "title"
+   * parameter that the command line expects.  Setting this parameter allows
+   * URLs containing spaces to work.
+   */
+  private static final String THIRD_WINDOWS_PARAMETER = "\"\"";
+
+  /**
+   * The shell parameters for Netscape that opens a given URL in an already-open copy of Netscape
+   * on many command-line systems.
+   */
+  private static final String NETSCAPE_REMOTE_PARAMETER = "-remote";
+  private static final String NETSCAPE_OPEN_PARAMETER_START = "openURL(";
+  private static final String NETSCAPE_OPEN_NEW_WINDOW = ", new-window";
+  private static final String NETSCAPE_OPEN_PARAMETER_END = ")";
+
+  /**
+   * The message from any exception thrown throughout the initialization process.
+   */
+  private static String errorMessage;
+
+  /**
+   * An initialization block that determines the operating system and loads the necessary
+   * runtime data.
+   */
+  static
+  {
+    loadedWithoutErrors = true;
+
+    String osName = System.getProperty("os.name");
+
+    if (osName.startsWith("Mac OS"))
+    {
+      String mrjVersion = System.getProperty("mrj.version");
+      String majorMRJVersion = mrjVersion.substring(0, 3);
+
+      try
+      {
+        double version = Double.valueOf(majorMRJVersion).doubleValue();
+
+        if (version == 2)
+        {
+          jvm = MRJ_2_0;
+        }
+        else if ( (version >= 2.1) && (version < 3))
+        {
+          // Assume that all 2.x versions of MRJ work the same.  MRJ 2.1 actually
+          // works via Runtime.exec() and 2.2 supports that but has an openURL() method
+          // as well that we currently ignore.
+          jvm = MRJ_2_1;
+        }
+        else if (version == 3.0)
+        {
+          jvm = MRJ_3_0;
+        }
+        else if (version >= 3.1)
+        {
+          // Assume that all 3.1 and later versions of MRJ work the same.
+          jvm = MRJ_3_1;
+        }
+        else
+        {
+          loadedWithoutErrors = false;
+          errorMessage = "Unsupported MRJ version: " + version;
+        }
+      }
+      catch (NumberFormatException nfe)
+      {
+        loadedWithoutErrors = false;
+        errorMessage = "Invalid MRJ version: " + mrjVersion;
+      }
+    }
+    else if (osName.startsWith("Windows"))
+    {
+      if (osName.indexOf("9") != -1)
+      {
+        jvm = WINDOWS_9x;
+      }
+      else
+      {
+        jvm = WINDOWS_NT;
+      }
+    }
+    else
+    {
+      jvm = OTHER;
+    }
+
+    if (loadedWithoutErrors)
+    { // if we haven't hit any errors yet
+      loadedWithoutErrors = loadClasses();
+    }
+  }
+
+  /**
+   * This class should be never be instantiated; this just ensures so.
+   */
+  private BrowserLauncher()
+  {
+  }
+
+  /**
+   * Called by a static initializer to load any classes, fields, and methods required at runtime
+   * to locate the user's web browser.
+   * @return <code>true</code> if all intialization succeeded
+   *                        <code>false</code> if any portion of the initialization failed
+   */
+  private static boolean loadClasses()
+  {
+    switch (jvm)
+    {
+      case MRJ_2_0:
+
+        try
+        {
+          Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");
+          Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");
+          Class appleEventClass = Class.forName(
+              "com.apple.MacOS.AppleEvent");
+          Class aeClass = Class.forName("com.apple.MacOS.ae");
+          aeDescClass = Class.forName("com.apple.MacOS.AEDesc");
+
+          aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class[]
+              {
+              int.class
+          });
+          appleEventConstructor = appleEventClass.getDeclaredConstructor(new
+              Class[]
+              {
+              int.class, int.class, aeTargetClass, int.class,
+              int.class
+          });
+          aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[]
+              {
+              String.class
+          });
+
+          makeOSType = osUtilsClass.getDeclaredMethod("makeOSType",
+              new Class[]
+              {String.class});
+          putParameter = appleEventClass.getDeclaredMethod("putParameter",
+              new Class[]
+              {int.class, aeDescClass});
+          sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply",
+              new Class[]
+              {});
+
+          Field keyDirectObjectField = aeClass.getDeclaredField(
+              "keyDirectObject");
+          keyDirectObject = (Integer) keyDirectObjectField.get(null);
+
+          Field autoGenerateReturnIDField = appleEventClass.getDeclaredField(
+              "kAutoGenerateReturnID");
+          kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);
+
+          Field anyTransactionIDField = appleEventClass.getDeclaredField(
+              "kAnyTransactionID");
+          kAnyTransactionID = (Integer) anyTransactionIDField.get(null);
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+          errorMessage = cnfe.getMessage();
+
+          return false;
+        }
+        catch (NoSuchMethodException nsme)
+        {
+          errorMessage = nsme.getMessage();
+
+          return false;
+        }
+        catch (NoSuchFieldException nsfe)
+        {
+          errorMessage = nsfe.getMessage();
+
+          return false;
+        }
+        catch (IllegalAccessException iae)
+        {
+          errorMessage = iae.getMessage();
+
+          return false;
+        }
+
+        break
+            ;
+
+      case MRJ_2_1:
+
+        try
+        {
+          mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+          mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
+
+          Field systemFolderField = mrjFileUtilsClass.getDeclaredField(
+              "kSystemFolderType");
+          kSystemFolderType = systemFolderField.get(null);
+          findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder",
+              new Class[]
+              {mrjOSTypeClass});
+          getFileCreator = mrjFileUtilsClass.getDeclaredMethod("getFileCreator",
+              new Class[]
+              {File.class});
+          getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType",
+              new Class[]
+              {File.class});
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+          errorMessage = cnfe.getMessage();
+
+          return false;
+        }
+        catch (NoSuchFieldException nsfe)
+        {
+          errorMessage = nsfe.getMessage();
+
+          return false;
+        }
+        catch (NoSuchMethodException nsme)
+        {
+          errorMessage = nsme.getMessage();
+
+          return false;
+        }
+        catch (SecurityException se)
+        {
+          errorMessage = se.getMessage();
+
+          return false;
+        }
+        catch (IllegalAccessException iae)
+        {
+          errorMessage = iae.getMessage();
+
+          return false;
+        }
+
+        break
+            ;
+
+      case MRJ_3_0:
+
+        try
+        {
+          Class linker = Class.forName("com.apple.mrj.jdirect.Linker");
+          Constructor constructor = linker.getConstructor(new Class[]
+              {
+              Class.class
+          });
+          linkage = constructor.newInstance(new Object[]
+                                            {
+                                            BrowserLauncher.class
+          });
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+          errorMessage = cnfe.getMessage();
+
+          return false;
+        }
+        catch (NoSuchMethodException nsme)
+        {
+          errorMessage = nsme.getMessage();
+
+          return false;
+        }
+        catch (InvocationTargetException ite)
+        {
+          errorMessage = ite.getMessage();
+
+          return false;
+        }
+        catch (InstantiationException ie)
+        {
+          errorMessage = ie.getMessage();
+
+          return false;
+        }
+        catch (IllegalAccessException iae)
+        {
+          errorMessage = iae.getMessage();
+
+          return false;
+        }
+
+        break
+            ;
+
+      case MRJ_3_1:
+
+        try
+        {
+          mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+          openURL = mrjFileUtilsClass.getDeclaredMethod("openURL",
+              new Class[]
+              {String.class});
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+          errorMessage = cnfe.getMessage();
+
+          return false;
+        }
+        catch (NoSuchMethodException nsme)
+        {
+          errorMessage = nsme.getMessage();
+
+          return false;
+        }
+
+        break
+            ;
+
+      default:
+        break;
+    }
+
+    return true;
+  }
+
+  /**
+   * Attempts to locate the default web browser on the local system.    s results so it
+   * only locates the browser once for each use of this class per JVM instance.
+   * @return The browser for the system.  Note that this may not be what you would consider
+   *                        to be a standard web browser; instead, it's the application that gets called to
+   *                        open the default web browser.  In some cases, this will be a non-String object
+   *                        that provides the means of calling the default browser.
+   */
+  private static Object locateBrowser()
+  {
+    if (browser != null)
+    {
+      return browser;
+    }
+
+    switch (jvm)
+    {
+      case MRJ_2_0:
+
+        try
+        {
+          Integer finderCreatorCode = (Integer) makeOSType.invoke(null,
+              new Object[]
+              {FINDER_CREATOR});
+          Object aeTarget = aeTargetConstructor.newInstance(new Object[]
+              {
+              finderCreatorCode
+          });
+          Integer gurlType = (Integer) makeOSType.invoke(null,
+              new Object[]
+              {GURL_EVENT});
+          Object appleEvent = appleEventConstructor.newInstance(new Object[]
+              {
+              gurlType, gurlType, aeTarget, kAutoGenerateReturnID,
+              kAnyTransactionID
+          });
+
+          // Don't set browser = appleEvent because then the next time we call
+          // locateBrowser(), we'll get the same AppleEvent, to which we'll already have
+          // added the relevant parameter. Instead, regenerate the AppleEvent every time.
+          // There's probably a way to do this better; if any has any ideas, please let
+          // me know.
+          return appleEvent;
+        }
+        catch (IllegalAccessException iae)
+        {
+          browser = null;
+          errorMessage = iae.getMessage();
+
+          return browser;
+        }
+        catch (InstantiationException ie)
+        {
+          browser = null;
+          errorMessage = ie.getMessage();
+
+          return browser;
+        }
+        catch (InvocationTargetException ite)
+        {
+          browser = null;
+          errorMessage = ite.getMessage();
+
+          return browser;
+        }
+
+        case MRJ_2_1:
+
+          File systemFolder;
+
+          try
+          {
+            systemFolder = (File) findFolder.invoke(null,
+                new Object[]
+                {kSystemFolderType});
+          }
+          catch (IllegalArgumentException iare)
+          {
+            browser = null;
+            errorMessage = iare.getMessage();
+
+            return browser;
+          }
+          catch (IllegalAccessException iae)
+          {
+            browser = null;
+            errorMessage = iae.getMessage();
+
+            return browser;
+          }
+          catch (InvocationTargetException ite)
+          {
+            browser = null;
+            errorMessage = ite.getTargetException().getClass() + ": " +
+                ite.getTargetException().getMessage();
+
+            return browser;
+          }
+
+          String[] systemFolderFiles = systemFolder.list();
+
+          // Avoid a FilenameFilter because that can't be stopped mid-list
+          for (int i = 0; i < systemFolderFiles.length; i++)
+          {
+            try
+            {
+              File file = new File(systemFolder, systemFolderFiles[i]);
+
+              if (!file.isFile())
+              {
+                continue;
+              }
+
+              // We're looking for a file with a creator code of 'MACS' and
+              // a type of 'FNDR'.  Only requiring the type results in non-Finder
+              // applications being picked up on certain Mac OS 9 systems,
+              // especially German ones, and sending a GURL event to those
+              // applications results in a logout under Multiple Users.
+              Object fileType = getFileType.invoke(null,
+                  new Object[]
+                  {file});
+
+              if (FINDER_TYPE.equals(fileType.toString()))
+              {
+                Object fileCreator = getFileCreator.invoke(null,
+                    new Object[]
+                    {file});
+
+                if (FINDER_CREATOR.equals(fileCreator.toString()))
+                {
+                  browser = file.toString(); // Actually the Finder, but that's OK
+
+                  return browser;
+                }
+              }
+            }
+            catch (IllegalArgumentException iare)
+            {
+              errorMessage = iare.getMessage();
+
+              return null;
+            }
+            catch (IllegalAccessException iae)
+            {
+              browser = null;
+              errorMessage = iae.getMessage();
+
+              return browser;
+            }
+            catch (InvocationTargetException ite)
+            {
+              browser = null;
+              errorMessage = ite.getTargetException().getClass() + ": " +
+                  ite.getTargetException().getMessage();
+
+              return browser;
+            }
+          }
+
+          browser = null;
+
+          break;
+
+      case MRJ_3_0:
+      case MRJ_3_1:
+        browser = ""; // Return something non-null
+
+        break;
+
+      case WINDOWS_NT:
+        browser = "cmd.exe";
+
+        break;
+
+      case WINDOWS_9x:
+        browser = "command.com";
+
+        break;
+
+      case OTHER:
+      default:
+        browser = jalview.bin.Cache.getDefault("DEFAULT_BROWSER", "firefox");
+
+        break;
+    }
+
+    return browser;
+  }
+  /**
+   * used to ensure that browser is up-to-date after a configuration
+   * change (Unix DEFAULT_BROWSER property change).
+   */
+  public static void resetBrowser() {
+    browser = null;
+  }
+  /**
+   * Attempts to open the default web browser to the given URL.
+   * @param url The URL to open
+   * @throws IOException If the web browser could not be located or does not run
+   */
+  public static void openURL(String url)
+      throws IOException
+  {
+    if (!loadedWithoutErrors)
+    {
+      throw new IOException("Exception in finding browser: " +
+                            errorMessage);
+    }
+
+    Object browser = locateBrowser();
+
+    if (browser == null)
+    {
+      throw new IOException("Unable to locate browser: " + errorMessage);
+    }
+
+    switch (jvm)
+    {
+      case MRJ_2_0:
+
+        Object aeDesc = null;
+
+        try
+        {
+          aeDesc = aeDescConstructor.newInstance(new Object[]
+                                                 {url});
+          putParameter.invoke(browser,
+                              new Object[]
+                              {keyDirectObject, aeDesc});
+          sendNoReply.invoke(browser, new Object[]
+                             {});
+        }
+        catch (InvocationTargetException ite)
+        {
+          throw new IOException(
+              "InvocationTargetException while creating AEDesc: " +
+              ite.getMessage());
+        }
+        catch (IllegalAccessException iae)
+        {
+          throw new IOException(
+              "IllegalAccessException while building AppleEvent: " +
+              iae.getMessage());
+        }
+        catch (InstantiationException ie)
+        {
+          throw new IOException(
+              "InstantiationException while creating AEDesc: " +
+              ie.getMessage());
+        }
+        finally
+        {
+          aeDesc = null; // Encourage it to get disposed if it was created
+          browser = null; // Ditto
+        }
+
+        break;
+
+      case MRJ_2_1:
+        Runtime.getRuntime().exec(new String[]
+                                  { (String) browser, url});
+
+        break;
+
+      case MRJ_3_0:
+
+        int[] instance = new int[1];
+        int result = ICStart(instance, 0);
+
+        if (result == 0)
+        {
+          int[] selectionStart = new int[]
+              {
+              0};
+          byte[] urlBytes = url.getBytes();
+          int[] selectionEnd = new int[]
+              {
+              urlBytes.length};
+          result = ICLaunchURL(instance[0], new byte[]
+                               {0}, urlBytes,
+                               urlBytes.length, selectionStart, selectionEnd);
+
+          if (result == 0)
+          {
+            // Ignore the return value; the URL was launched successfully
+            // regardless of what happens here.
+            ICStop(instance);
+          }
+          else
+          {
+            throw new IOException("Unable to launch URL: " + result);
+          }
+        }
+        else
+        {
+          throw new IOException(
+              "Unable to create an Internet Config instance: " + result);
+        }
+
+        break;
+
+      case MRJ_3_1:
+
+        try
+        {
+          openURL.invoke(null, new Object[]
+                         {url});
+        }
+        catch (InvocationTargetException ite)
+        {
+          throw new IOException(
+              "InvocationTargetException while calling openURL: " +
+              ite.getMessage());
+        }
+        catch (IllegalAccessException iae)
+        {
+          throw new IOException(
+              "IllegalAccessException while calling openURL: " +
+              iae.getMessage());
+        }
+
+        break
+            ;
+
+      case WINDOWS_NT:
+      case WINDOWS_9x:
+
+        // Add quotes around the URL to allow ampersands and other special
+        // characters to work.
+        Process process = Runtime.getRuntime().exec(new String[]
+            {
+            (String) browser, FIRST_WINDOWS_PARAMETER,
+            SECOND_WINDOWS_PARAMETER, THIRD_WINDOWS_PARAMETER,
+            '"' + url + '"'
+        });
+
+        // This avoids a memory leak on some versions of Java on Windows.
+        // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
+        try
+        {
+          process.waitFor();
+          process.exitValue();
+        }
+        catch (InterruptedException ie)
+        {
+          throw new IOException(
+              "InterruptedException while launching browser: " +
+              ie.getMessage());
+        }
+
+        break
+            ;
+
+      case OTHER:
+
+        // Assume that we're on Unix and that Netscape (actually Firefox) is installed
+        // First, attempt to open the URL in a currently running session of Netscape
+        // JBPNote log debug
+
+        /* System.out.println("Executing : "+browser+" "+
+         NETSCAPE_REMOTE_PARAMETER+" "+
+         NETSCAPE_OPEN_PARAMETER_START +
+         url +
+         NETSCAPE_OPEN_NEW_WINDOW +
+         NETSCAPE_OPEN_PARAMETER_END);
+         */
+        process = Runtime.getRuntime().exec(new String[]
+                                            {
+                                            (String) browser,
+                                            NETSCAPE_REMOTE_PARAMETER,
+
+                                            NETSCAPE_OPEN_PARAMETER_START + url +
+                                            NETSCAPE_OPEN_NEW_WINDOW +
+                                            NETSCAPE_OPEN_PARAMETER_END
+        });
+
+        try
+        {
+          int exitCode = process.waitFor();
+
+          if (exitCode != 0)
+          { // if Netscape was not open
+            Runtime.getRuntime().exec(new String[]
+                                      { (String) browser, url});
+          }
+        }
+        catch (InterruptedException ie)
+        {
+          throw new IOException(
+              "InterruptedException while launching browser: " +
+              ie.getMessage());
+        }
+
+        break
+            ;
+
+      default:
+
+        // This should never occur, but if it does, we'll try the simplest thing possible
+        Runtime.getRuntime().exec(new String[]
+                                  { (String) browser, url});
+
+        break;
+    }
+  }
+
+  /**
+   * Methods required for Mac OS X.  The presence of native methods does not cause
+   * any problems on other platforms.
+   */
+  private native static int ICStart(int[] instance, int signature);
+
+  private native static int ICStop(int[] instance);
+
+  private native static int ICLaunchURL(int instance, byte[] hint,
+                                        byte[] data, int len,
+                                        int[] selectionStart,
+                                        int[] selectionEnd);
+}
index e48c0ca..da9ea1e 100755 (executable)
-/*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
-*\r
-* This program is free software; you can redistribute it and/or\r
-* modify it under the terms of the GNU General Public License\r
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
-package jalview.util;\r
-\r
-import jalview.datamodel.*;\r
-\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class Comparison\r
-{\r
-  /** DOCUMENT ME!! */\r
-  public static String GapChars = " .-";\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param ii DOCUMENT ME!\r
-   * @param jj DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public static float compare(SequenceI ii, SequenceI jj)\r
-  {\r
-    return Comparison.compare(ii, jj, 0, ii.getLength() - 1);\r
-  }\r
-\r
-  /**\r
-   * this was supposed to be an ungapped pid calculation\r
-   * @param ii SequenceI\r
-   * @param jj SequenceI\r
-   * @param start int\r
-   * @param end int\r
-   * @return float\r
-   */\r
-  public static float compare(SequenceI ii, SequenceI jj, int start, int end)\r
-  {\r
-    String si = ii.getSequence();\r
-    String sj = jj.getSequence();\r
-\r
-    int ilen = si.length() - 1;\r
-    int jlen = sj.length() - 1;\r
-\r
-    while (jalview.util.Comparison.isGap(si.charAt(start + ilen)))\r
-    {\r
-      ilen--;\r
-    }\r
-\r
-    while (jalview.util.Comparison.isGap(sj.charAt(start + jlen)))\r
-    {\r
-      jlen--;\r
-    }\r
-\r
-    int count = 0;\r
-    int match = 0;\r
-    float pid = -1;\r
-\r
-    if (ilen > jlen)\r
-    {\r
-      for (int j = 0; j < jlen; j++)\r
-      {\r
-        if (si.substring(start + j, start + j + 1).equals(sj.substring(start +\r
-            j, start + j + 1)))\r
-        {\r
-          match++;\r
-        }\r
-\r
-        count++;\r
-      }\r
-\r
-      pid = (float) match / (float) ilen * 100;\r
-    }\r
-    else\r
-    {\r
-      for (int j = 0; j < jlen; j++)\r
-      {\r
-        if (si.substring(start + j, start + j + 1).equals(sj.substring(start +\r
-            j, start + j + 1)))\r
-        {\r
-          match++;\r
-        }\r
-\r
-        count++;\r
-      }\r
-\r
-      pid = (float) match / (float) jlen * 100;\r
-    }\r
-\r
-    return pid;\r
-  }\r
-\r
-  /**\r
-   * this is a gapped PID calculation\r
-   *\r
-   * @param s1 SequenceI\r
-   * @param s2 SequenceI\r
-   * @return float\r
-   */\r
-  public static float PID(SequenceI s1, SequenceI s2)\r
-  {\r
-    int len;\r
-\r
-    if (s1.getSequence().length() > s2.getSequence().length())\r
-    {\r
-      len = s1.getSequence().length();\r
-    }\r
-    else\r
-    {\r
-      len = s2.getSequence().length();\r
-    }\r
-\r
-    int bad = 0;\r
-\r
-    for (int i = 0; i < len; i++)\r
-    {\r
-      char chr1;\r
-      char chr2;\r
-\r
-      if (i < s1.getSequence().length())\r
-      {\r
-        chr1 = Character.toUpperCase(s1.getSequence().charAt(i));\r
-      }\r
-      else\r
-      {\r
-        chr1 = '.';\r
-      }\r
-\r
-      if (i < s2.getSequence().length())\r
-      {\r
-        chr2 = Character.toUpperCase(s2.getSequence().charAt(i));\r
-      }\r
-      else\r
-      {\r
-        chr2 = '.';\r
-      }\r
-\r
-      if (! (jalview.util.Comparison.isGap(chr1)) &&\r
-          ! (jalview.util.Comparison.isGap(chr2)))\r
-      {\r
-        if (chr1 != chr2)\r
-        {\r
-          bad++;\r
-        }\r
-      }\r
-    }\r
-\r
-    return ( (float) 100 * (len - bad)) / len;\r
-  }\r
-\r
-  // Another pid with region specification\r
-  public static float PID(SequenceI s1, SequenceI s2, int start, int end)\r
-  {\r
-    int len;\r
-\r
-    if (s1.getSequence().length() > s2.getSequence().length())\r
-    {\r
-      len = s1.getSequence().length();\r
-    }\r
-    else\r
-    {\r
-      len = s2.getSequence().length();\r
-    }\r
-\r
-    if (end < len)\r
-    {\r
-      len = end;\r
-    }\r
-\r
-    if (len < start)\r
-    {\r
-      start = len - 1; // we just use a single residue for the difference\r
-    }\r
-\r
-    int bad = 0;\r
-\r
-    for (int i = start; i < len; i++)\r
-    {\r
-      char chr1;\r
-      char chr2;\r
-\r
-      if (i < s1.getSequence().length())\r
-      {\r
-        chr1 = Character.toUpperCase(s1.getSequence().charAt(i));\r
-      }\r
-      else\r
-      {\r
-        chr1 = '.';\r
-      }\r
-\r
-      if (i < s2.getSequence().length())\r
-      {\r
-        chr2 = Character.toUpperCase(s2.getSequence().charAt(i));\r
-      }\r
-      else\r
-      {\r
-        chr2 = '.';\r
-      }\r
-\r
-      if (! (jalview.util.Comparison.isGap(chr1)) &&\r
-          ! (jalview.util.Comparison.isGap(chr2)))\r
-      {\r
-        if (chr1 != chr2)\r
-        {\r
-          bad++;\r
-        }\r
-      }\r
-    }\r
-\r
-    return ( (float) 100 * (len - bad)) / len;\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @param c DOCUMENT ME!\r
-   *\r
-   * @return DOCUMENT ME!\r
-   */\r
-  public static boolean isGap(char c)\r
-  {\r
-    return (c == '-' || c == '.' || c == ' ') ? true : false;\r
-  }\r
-\r
-  public static boolean isNucleotide(SequenceI [] seqs)\r
-  {\r
-    int i = 0, iSize = seqs.length, j, jSize;\r
-    float nt = 0, aa = 0;\r
-    char c;\r
-    while (i < iSize)\r
-    {\r
-      jSize = seqs[i].getLength();\r
-      for (j = 0; j < jSize; j++)\r
-      {\r
-        c = seqs[i].getCharAt(j);\r
-        if ('a' <= c && c <= 'z')\r
-          c -= ('a' - 'A');\r
-\r
-        if (c == 'A' || c == 'G' || c == 'C' || c == 'T' || c == 'U')\r
-          nt++;\r
-        else if (!jalview.util.Comparison.isGap( seqs[i].getCharAt(j)))\r
-        {\r
-          aa++;\r
-        }\r
-      }\r
-      i++;\r
-    }\r
-\r
-    if ( (nt / (nt + aa)) > 0.85f)\r
-      return true;\r
-    else\r
-      return false;\r
-\r
-  }\r
-}\r
+/*
+* Jalview - A Sequence Alignment Editor and Viewer
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+*
+* This program 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+package jalview.util;
+
+import jalview.datamodel.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Comparison
+{
+  /** DOCUMENT ME!! */
+  public static String GapChars = " .-";
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param ii DOCUMENT ME!
+   * @param jj DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public static float compare(SequenceI ii, SequenceI jj)
+  {
+    return Comparison.compare(ii, jj, 0, ii.getLength() - 1);
+  }
+
+  /**
+   * this was supposed to be an ungapped pid calculation
+   * @param ii SequenceI
+   * @param jj SequenceI
+   * @param start int
+   * @param end int
+   * @return float
+   */
+  public static float compare(SequenceI ii, SequenceI jj, int start, int end)
+  {
+    String si = ii.getSequence();
+    String sj = jj.getSequence();
+
+    int ilen = si.length() - 1;
+    int jlen = sj.length() - 1;
+
+    while (jalview.util.Comparison.isGap(si.charAt(start + ilen)))
+    {
+      ilen--;
+    }
+
+    while (jalview.util.Comparison.isGap(sj.charAt(start + jlen)))
+    {
+      jlen--;
+    }
+
+    int count = 0;
+    int match = 0;
+    float pid = -1;
+
+    if (ilen > jlen)
+    {
+      for (int j = 0; j < jlen; j++)
+      {
+        if (si.substring(start + j, start + j + 1).equals(sj.substring(start +
+            j, start + j + 1)))
+        {
+          match++;
+        }
+
+        count++;
+      }
+
+      pid = (float) match / (float) ilen * 100;
+    }
+    else
+    {
+      for (int j = 0; j < jlen; j++)
+      {
+        if (si.substring(start + j, start + j + 1).equals(sj.substring(start +
+            j, start + j + 1)))
+        {
+          match++;
+        }
+
+        count++;
+      }
+
+      pid = (float) match / (float) jlen * 100;
+    }
+
+    return pid;
+  }
+
+  /**
+   * this is a gapped PID calculation
+   *
+   * @param s1 SequenceI
+   * @param s2 SequenceI
+   * @return float
+   */
+  public final static float PID(String seq1, String seq2)
+  {
+    return PID(seq1, seq2, 0, seq1.length());
+  }
+
+  static final int caseShift = 'a' - 'A';
+
+  // Another pid with region specification
+  public final static  float PID(String seq1, String seq2, int start, int end)
+  {
+
+    int s1len = seq1.length();
+    int s2len = seq2.length();
+
+    int len = Math.min(s1len, s2len);
+
+    if (end < len)
+    {
+      len = end;
+    }
+
+    if (len < start)
+    {
+      start = len - 1; // we just use a single residue for the difference
+    }
+
+
+    int bad = 0;
+    char chr1;
+    char chr2;
+
+
+    for (int i = start; i < len; i++)
+    {
+      chr1 =  seq1.charAt(i) ;
+
+      chr2 =  seq2.charAt(i) ;
+
+      if ('a' <= chr1 && chr1 <= 'z')
+      {
+        // TO UPPERCASE !!!
+        //Faster than toUpperCase
+        chr1 -= caseShift;
+      }
+      if ('a' <= chr2 && chr2 <= 'z')
+      {
+        // TO UPPERCASE !!!
+        //Faster than toUpperCase
+        chr2 -= caseShift;
+      }
+
+
+      if (chr1!=chr2 && !isGap(chr1) && !isGap(chr2) )
+      {
+          bad++;
+      }
+    }
+
+    return ( (float) 100 * (len - bad)) / len;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param c DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public static boolean isGap(char c)
+  {
+    return (c == '-' || c == '.' || c == ' ') ? true : false;
+  }
+
+  public static boolean isNucleotide(SequenceI [] seqs)
+  {
+    int i = 0, iSize = seqs.length, j, jSize;
+    float nt = 0, aa = 0;
+    char c;
+    while (i < iSize)
+    {
+      jSize = seqs[i].getLength();
+      for (j = 0; j < jSize; j++)
+      {
+        c = seqs[i].getCharAt(j);
+        if ('a' <= c && c <= 'z')
+          c -= ('a' - 'A');
+
+        if (c == 'A' || c == 'G' || c == 'C' || c == 'T' || c == 'U')
+          nt++;
+        else if (!jalview.util.Comparison.isGap( seqs[i].getCharAt(j)))
+        {
+          aa++;
+        }
+      }
+      i++;
+    }
+
+    if ( (nt / (nt + aa)) > 0.85f)
+      return true;
+    else
+      return false;
+
+  }
+}
index 86ab201..5aed125 100755 (executable)
@@ -1,32 +1,90 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
 package jalview.util;
 
 package jalview.util;
 
-import java.util.Vector;
-import java.util.Hashtable;
+import java.util.*;
+
+import jalview.datamodel.*;
+
 
 public class DBRefUtils
 {
     /**
      * Utilities for handling DBRef objects and their collections.
      */
 
 public class DBRefUtils
 {
     /**
      * Utilities for handling DBRef objects and their collections.
      */
-    public static Vector selectRefs(java.util.Vector dbrefs, String[] sources) {
+    /**
+     *
+     * @param dbrefs Vector of DBRef objects to search
+     * @param sources String[] array of source DBRef IDs to retrieve
+     * @return Vector
+     */
+    public static DBRefEntry [] selectRefs(DBRefEntry [] dbrefs, String[] sources) {
       if (dbrefs==null)
         return null;
       if (sources==null)
         return dbrefs;
       Hashtable srcs = new Hashtable();
       Vector res=new Vector();
       if (dbrefs==null)
         return null;
       if (sources==null)
         return dbrefs;
       Hashtable srcs = new Hashtable();
       Vector res=new Vector();
+
       for (int i=0; i<sources.length; i++)
         srcs.put(new String(sources[i]), new Integer(i));
       for (int i=0; i<sources.length; i++)
         srcs.put(new String(sources[i]), new Integer(i));
-      for (int i=0, j=dbrefs.size(); i<j; i++)
-        if (dbrefs.get(i) instanceof jalview.datamodel.DBRefEntry) {
-          jalview.datamodel.DBRefEntry entry = (jalview.datamodel.DBRefEntry) dbrefs.get(i);
-          if (srcs.containsKey(entry.getSource()))
-            res.add(entry);
+      for (int i = 0, j = dbrefs.length; i < j; i++)
+        {
+          if (srcs.containsKey(dbrefs[i].getSource()))
+            res.add(dbrefs[i]);
         }
         }
+
       if (res.size()>0)
       if (res.size()>0)
-        return res;
+      {
+        DBRefEntry [] reply = new DBRefEntry[res.size()];
+        for(int i=0; i<res.size(); i++)
+          reply[i] = (DBRefEntry)res.elementAt(i);
+        return reply;
+      }
       res = null;
       // there are probable  memory leaks in the hashtable!
       return null;
     }
       res = null;
       // there are probable  memory leaks in the hashtable!
       return null;
     }
+
+  /**
+   * isDasCoordinateSystem
+   *
+   * @param string String
+   * @param dBRefEntry DBRefEntry
+   * @return boolean true if Source DBRefEntry is compatible with DAS CoordinateSystem name
+   */
+  public static Hashtable DasCoordinateSystemsLookup = null;
+  public static boolean isDasCoordinateSystem(String string,
+                                              DBRefEntry dBRefEntry)
+  {
+    if (DasCoordinateSystemsLookup==null)
+    { // Initialise
+      DasCoordinateSystemsLookup = new Hashtable();
+      DasCoordinateSystemsLookup.put("pdbresnum",
+                                     jalview.datamodel.DBRefSource.PDB);
+      DasCoordinateSystemsLookup.put("uniprot",
+                                     jalview.datamodel.DBRefSource.UNIPROT);
+    }
+
+    String coordsys = (String) DasCoordinateSystemsLookup.get(string.toLowerCase());
+    if (coordsys!=null)
+      return coordsys.equals(dBRefEntry.getSource());
+    return false;
   }
   }
+}
index 59244eb..8c1e334 100755 (executable)
-package jalview.util;\r
-\r
-import java.awt.event.ActionEvent;\r
-import java.awt.RenderingHints;\r
-import javax.imageio.ImageIO;\r
-import org.jibble.epsgraphics.EpsGraphics2D;\r
-import jalview.gui.EPSOptions;\r
-import java.awt.Graphics2D;\r
-import java.io.*;\r
-import java.awt.image.BufferedImage;\r
-import java.awt.Graphics;\r
-import jalview.io.*;\r
-import java.awt.*;\r
-\r
-\r
-public class ImageMaker\r
-{\r
-  public static final int EPS = 0;\r
-  public static final int PNG = 1;\r
-  int type = -1;\r
-\r
-  EpsGraphics2D pg;\r
-  Graphics graphics;\r
-  FileOutputStream out;\r
-  BufferedImage bi;\r
-\r
-  public ImageMaker(Component parent, int type, String title,\r
-                           int width, int height, File file, String EPStitle)\r
-  {\r
-    this.type = type;\r
-\r
-    if (file == null)\r
-    {\r
-      JalviewFileChooser chooser;\r
-      chooser = type == EPS ? getEPSChooser() : getPNGChooser();\r
-\r
-      chooser.setFileView(new jalview.io.JalviewFileView());\r
-      chooser.setDialogTitle(title);\r
-      chooser.setToolTipText("Save");\r
-\r
-      int value = chooser.showSaveDialog(parent);\r
-\r
-      if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
-      {\r
-        jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
-                                      chooser.getSelectedFile().getParent());\r
-\r
-        file = chooser.getSelectedFile();\r
-      }\r
-    }\r
-\r
-    if(file!=null)\r
-    {\r
-      try\r
-      {\r
-        out = new FileOutputStream(file);\r
-\r
-        if (type == EPS)\r
-          setupEPS(width, height, EPStitle);\r
-        else\r
-          setupPNG(width, height);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        System.out.println("Error creating " + (type == EPS ? "EPS" : "PNG") +\r
-                           " file.");\r
-      }\r
-    }\r
-  }\r
-\r
-  public Graphics getGraphics()\r
-  {\r
-    return graphics;\r
-  }\r
-\r
-\r
-  void setupPNG(int width, int height)\r
-  {\r
-        bi = new BufferedImage(width, height,\r
-                BufferedImage.TYPE_INT_RGB);\r
-        graphics  = bi.getGraphics();\r
-        Graphics2D ig2 = (Graphics2D) graphics;\r
-        ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                                 RenderingHints.VALUE_ANTIALIAS_ON);\r
-  }\r
-\r
-  public void writeImage()\r
-  {\r
-    try{\r
-      switch(type)\r
-      {\r
-        case EPS:\r
-          pg.flush();\r
-          pg.close();\r
-          break;\r
-        case PNG:\r
-          ImageIO.write(bi, "png", out);\r
-          out.close();\r
-          break;\r
-      }\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-        ex.printStackTrace();\r
-    }\r
-  }\r
-\r
-  void setupEPS(int width, int height, String title)\r
-  {\r
-    boolean accurateText = true;\r
-\r
-    String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",\r
-        "Prompt each time");\r
-\r
-    // If we need to prompt, and if the GUI is visible then\r
-    // Prompt for EPS rendering style\r
-    if (renderStyle.equalsIgnoreCase("Prompt each time")\r
-        && !\r
-        (System.getProperty("java.awt.headless") != null\r
-         && System.getProperty("java.awt.headless").equals("true")))\r
-    {\r
-      EPSOptions eps = new EPSOptions();\r
-      renderStyle = eps.getValue();\r
-\r
-      if (renderStyle == null || eps.cancelled)\r
-        return;\r
-    }\r
-\r
-    if (renderStyle.equalsIgnoreCase("text"))\r
-    {\r
-      accurateText = false;\r
-    }\r
-\r
-    try   {\r
-      pg = new EpsGraphics2D(title, out, 0, 0, width,\r
-                                           height);\r
-      Graphics2D ig2 = (Graphics2D) pg;\r
-      ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                           RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
-      pg.setAccurateTextMode(accurateText);\r
-\r
-      graphics = pg;\r
-    }\r
-    catch (Exception ex) {  }\r
-  }\r
-\r
-\r
-  JalviewFileChooser getPNGChooser()\r
-  {\r
-    return new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-        "LAST_DIRECTORY"), new String[]\r
-                                             {"png"},\r
-                                             new String[]\r
-                                             {"Portable network graphics"},\r
-                                             "Portable network graphics");\r
-  }\r
-\r
-  JalviewFileChooser getEPSChooser()\r
-  {\r
-    return new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-        "LAST_DIRECTORY"), new String[]\r
-                                             {"eps"},\r
-                                             new String[]\r
-                                             {"Encapsulated Postscript"},\r
-                                             "Encapsulated Postscript");\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.util;
+
+import java.awt.event.ActionEvent;
+import java.awt.RenderingHints;
+import javax.imageio.ImageIO;
+import org.jibble.epsgraphics.EpsGraphics2D;
+import jalview.gui.EPSOptions;
+import java.awt.Graphics2D;
+import java.io.*;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics;
+import jalview.io.*;
+import java.awt.*;
+
+
+public class ImageMaker
+{
+  public static final int EPS = 0;
+  public static final int PNG = 1;
+  int type = -1;
+
+  EpsGraphics2D pg;
+  Graphics graphics;
+  FileOutputStream out;
+  BufferedImage bi;
+
+  public ImageMaker(Component parent, int type, String title,
+                           int width, int height, File file, String EPStitle)
+  {
+    this.type = type;
+
+    if (file == null)
+    {
+      JalviewFileChooser chooser;
+      chooser = type == EPS ? getEPSChooser() : getPNGChooser();
+
+      chooser.setFileView(new jalview.io.JalviewFileView());
+      chooser.setDialogTitle(title);
+      chooser.setToolTipText("Save");
+
+      int value = chooser.showSaveDialog(parent);
+
+      if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
+      {
+        jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+                                      chooser.getSelectedFile().getParent());
+
+        file = chooser.getSelectedFile();
+      }
+    }
+
+    if(file!=null)
+    {
+      try
+      {
+        out = new FileOutputStream(file);
+
+        if (type == EPS)
+          setupEPS(width, height, EPStitle);
+        else
+          setupPNG(width, height);
+      }
+      catch (Exception ex)
+      {
+        System.out.println("Error creating " + (type == EPS ? "EPS" : "PNG") +
+                           " file.");
+      }
+    }
+  }
+
+  public Graphics getGraphics()
+  {
+    return graphics;
+  }
+
+
+  void setupPNG(int width, int height)
+  {
+        bi = new BufferedImage(width, height,
+                BufferedImage.TYPE_INT_RGB);
+        graphics  = bi.getGraphics();
+        Graphics2D ig2 = (Graphics2D) graphics;
+        ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                 RenderingHints.VALUE_ANTIALIAS_ON);
+  }
+
+  public void writeImage()
+  {
+    try{
+      switch(type)
+      {
+        case EPS:
+          pg.flush();
+          pg.close();
+          break;
+        case PNG:
+          ImageIO.write(bi, "png", out);
+          out.close();
+          break;
+      }
+    }
+    catch (Exception ex)
+    {
+        ex.printStackTrace();
+    }
+  }
+
+  void setupEPS(int width, int height, String title)
+  {
+    boolean accurateText = true;
+
+    String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
+        "Prompt each time");
+
+    // If we need to prompt, and if the GUI is visible then
+    // Prompt for EPS rendering style
+    if (renderStyle.equalsIgnoreCase("Prompt each time")
+        && !
+        (System.getProperty("java.awt.headless") != null
+         && System.getProperty("java.awt.headless").equals("true")))
+    {
+      EPSOptions eps = new EPSOptions();
+      renderStyle = eps.getValue();
+
+      if (renderStyle == null || eps.cancelled)
+        return;
+    }
+
+    if (renderStyle.equalsIgnoreCase("text"))
+    {
+      accurateText = false;
+    }
+
+    try   {
+      pg = new EpsGraphics2D(title, out, 0, 0, width,
+                                           height);
+      Graphics2D ig2 = (Graphics2D) pg;
+      ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                           RenderingHints.VALUE_ANTIALIAS_ON);
+
+      pg.setAccurateTextMode(accurateText);
+
+      graphics = pg;
+    }
+    catch (Exception ex) {  }
+  }
+
+
+  JalviewFileChooser getPNGChooser()
+  {
+    return new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(
+        "LAST_DIRECTORY"), new String[]
+                                             {"png"},
+                                             new String[]
+                                             {"Portable network graphics"},
+                                             "Portable network graphics");
+  }
+
+  JalviewFileChooser getEPSChooser()
+  {
+    return new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(
+        "LAST_DIRECTORY"), new String[]
+                                             {"eps"},
+                                             new String[]
+                                             {"Encapsulated Postscript"},
+                                             "Encapsulated Postscript");
+  }
+}
index 80734f7..9c4b8d8 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.util;\r
-\r
-public class QuickSort\r
-{\r
-  public static void sort(float[] arr, Object[] s)\r
-  {\r
-    sort(arr, 0, arr.length - 1, s);\r
-  }\r
-\r
-  public static void sort(String[] arr, Object[] s)\r
-  {\r
-    stringSort(arr, 0, arr.length - 1, s);\r
-  }\r
-\r
-  public static void stringSort(String[] arr, int p, int r, Object[] s)\r
-  {\r
-    int q;\r
-\r
-    if (p < r)\r
-    {\r
-      q = stringPartition(arr, p, r, s);\r
-      stringSort(arr, p, q, s);\r
-      stringSort(arr, q + 1, r, s);\r
-    }\r
-  }\r
-\r
-  public static void sort(float[] arr, int p, int r, Object[] s)\r
-  {\r
-    int q;\r
-\r
-    if (p < r)\r
-    {\r
-      q = partition(arr, p, r, s);\r
-      sort(arr, p, q, s);\r
-      sort(arr, q + 1, r, s);\r
-    }\r
-  }\r
-\r
-  private static int partition(float[] arr, int p, int r, Object[] s)\r
-  {\r
-    float x = arr[p];\r
-    int i = p - 1;\r
-    int j = r + 1;\r
-\r
-    while (true)\r
-    {\r
-      do\r
-      {\r
-        j = j - 1;\r
-      }\r
-      while (arr[j] > x);\r
-\r
-      do\r
-      {\r
-        i = i + 1;\r
-      }\r
-      while (arr[i] < x);\r
-\r
-      if (i < j)\r
-      {\r
-        float tmp = arr[i];\r
-        arr[i] = arr[j];\r
-        arr[j] = tmp;\r
-\r
-        Object tmp2 = s[i];\r
-        s[i] = s[j];\r
-        s[j] = tmp2;\r
-      }\r
-      else\r
-      {\r
-        return j;\r
-      }\r
-    }\r
-  }\r
-\r
-  private static int stringPartition(String[] arr, int p, int r, Object[] s)\r
-  {\r
-    String x = arr[p];\r
-    int i = p - 1;\r
-    int j = r + 1;\r
-\r
-    while (true)\r
-    {\r
-      do\r
-      {\r
-        j = j - 1;\r
-      }\r
-      while (arr[j].compareTo(x) < 0);\r
-\r
-      do\r
-      {\r
-        i = i + 1;\r
-      }\r
-      while (arr[i].compareTo(x) > 0);\r
-\r
-      if (i < j)\r
-      {\r
-        String tmp = arr[i];\r
-        arr[i] = arr[j];\r
-        arr[j] = tmp;\r
-\r
-        Object tmp2 = s[i];\r
-        s[i] = s[j];\r
-        s[j] = tmp2;\r
-      }\r
-      else\r
-      {\r
-        return j;\r
-      }\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.util;
+
+public class QuickSort
+{
+  public static void sort(float[] arr, Object[] s)
+  {
+    sort(arr, 0, arr.length - 1, 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)
+  {
+    int q;
+
+    if (p < r)
+    {
+      q = stringPartition(arr, p, r, s);
+      stringSort(arr, p, q, s);
+      stringSort(arr, q + 1, r, s);
+    }
+  }
+
+  public static void sort(float[] arr, int p, int r, Object[] s)
+  {
+    int q;
+
+    if (p < r)
+    {
+      q = partition(arr, p, r, s);
+      sort(arr, p, q, s);
+      sort(arr, q + 1, r, s);
+    }
+  }
+
+  private static int partition(float[] arr, int p, int r, Object[] s)
+  {
+    float x = arr[p];
+    int i = p - 1;
+    int j = r + 1;
+
+    while (true)
+    {
+      do
+      {
+        j = j - 1;
+      }
+      while (arr[j] > x);
+
+      do
+      {
+        i = i + 1;
+      }
+      while (arr[i] < x);
+
+      if (i < j)
+      {
+        float tmp = arr[i];
+        arr[i] = arr[j];
+        arr[j] = tmp;
+
+        Object tmp2 = s[i];
+        s[i] = s[j];
+        s[j] = tmp2;
+      }
+      else
+      {
+        return j;
+      }
+    }
+  }
+
+  private static int stringPartition(String[] arr, int p, int r, Object[] s)
+  {
+    String x = arr[p];
+    int i = p - 1;
+    int j = r + 1;
+
+    while (true)
+    {
+      do
+      {
+        j = j - 1;
+      }
+      while (arr[j].compareTo(x) < 0);
+
+      do
+      {
+        i = i + 1;
+      }
+      while (arr[i].compareTo(x) > 0);
+
+      if (i < j)
+      {
+        String tmp = arr[i];
+        arr[i] = arr[j];
+        arr[j] = tmp;
+
+        Object tmp2 = s[i];
+        s[i] = s[j];
+        s[j] = tmp2;
+      }
+      else
+      {
+        return j;
+      }
+    }
+  }
+}
index 8ff4184..4a83ba7 100755 (executable)
@@ -1,6 +1,6 @@
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
@@ -34,6 +34,7 @@ import ext.vamsas.*;
 import java.util.Vector;
 import java.util.Hashtable;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.Hashtable;
 import java.util.StringTokenizer;
+import javax.swing.JOptionPane;
 
 public class Discoverer
     extends Thread implements Runnable
 
 public class Discoverer
     extends Thread implements Runnable
@@ -144,9 +145,13 @@ public class Discoverer
       return urls;
     return null;
   }
       return urls;
     return null;
   }
-  static
-  {
 
 
+  /**
+   * fetch new services or reset to hardwired defaults depending on preferences.
+   */
+  static public void doDiscovery()
+  {
+    jalview.bin.Cache.log.debug("(Re)-Initialising the discovery URL list.");
     try
     {
       reallyDiscoverServices = jalview.bin.Cache.getDefault("DISCOVERY_START", false);
     try
     {
       reallyDiscoverServices = jalview.bin.Cache.getDefault("DISCOVERY_START", false);
@@ -169,6 +174,13 @@ public class Discoverer
 ),
             new ServiceHandle(
                 "MsaWS",
 ),
             new ServiceHandle(
                 "MsaWS",
+                "Katoh, K., K. Kuma, K., Toh, H.,  and Miyata, T. (2005) "+
+                "\"MAFFT version 5: improvement in accuracy of multiple sequence alignment.\""+
+               " Nucleic Acids Research, 33 511-518",
+                "http://www.compbio.dundee.ac.uk/JalviewWS/services/MafftWS",
+                "MAFFT Multiple Sequence Alignment"),
+            new ServiceHandle(
+                "MsaWS",
                 "Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple" +
                 " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice." +
                 " Nucleic Acids Research, 22 4673-4680",
                 "Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple" +
                 " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice." +
                 " Nucleic Acids Research, 22 4673-4680",
@@ -206,12 +218,23 @@ public class Discoverer
       jalview.bin.Cache.log.debug("Discovering services using " + location);
       shs = locateWebService(location).getServices();
     }
       jalview.bin.Cache.log.debug("Discovering services using " + location);
       shs = locateWebService(location).getServices();
     }
-    catch (Exception e)
-    {
-      jalview.bin.Cache.log.debug("No Discovery service at " +
-                         location);
-      jalview.bin.Cache.log.debug(e);
-
+    catch (org.apache.axis.AxisFault f) {
+      // JBPNote - should do this a better way!
+      if (f.getFaultReason().indexOf("(407)")>-1) {
+        if (jalview.gui.Desktop.desktop!=null)
+          JOptionPane.showMessageDialog(jalview.gui.Desktop.desktop, "Please set up your proxy settings in the 'Connections' tab of the Preferences window",
+                                      "Proxy Authorization Failed",
+                                      JOptionPane.WARNING_MESSAGE);
+      } else {
+        jalview.bin.Cache.log.warn("No Discovery service at " +
+                                   location);
+        jalview.bin.Cache.log.debug("Axis Fault", f);
+      }
+    }
+    catch (Exception e) {
+      jalview.bin.Cache.log.warn("No Discovery service at " +
+                                 location);
+      jalview.bin.Cache.log.debug("Discovery Service General Exception", e);
     }
     if ( (shs != null) && shs.getServices().length > 0)
     {
     }
     if ( (shs != null) && shs.getServices().length > 0)
     {
@@ -314,8 +337,18 @@ public class Discoverer
     firePropertyChange("services", oldServices, services);
   }
 
     firePropertyChange("services", oldServices, services);
   }
 
+  /**
+   * creates a new thread to call discoverServices()
+   */
   public void run()
   {
   public void run()
   {
-    discoverServices();
+    final Discoverer discoverer = this;
+    Thread discoverThread = new Thread() {
+      public void run() {
+        discoverer.doDiscovery();
+        discoverer.discoverServices();
+      }
+    };
+    discoverThread.start();
   }
 }
   }
 }
index 8a4368c..55e65a5 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.ws;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-\r
-import ext.vamsas.*;\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-import jalview.gui.*;\r
-import jalview.io.FormatAdapter;\r
-\r
-public class JPredClient\r
-    extends WSClient\r
-{\r
-  ext.vamsas.Jpred server;\r
-  String altitle = "";\r
-  java.util.Hashtable SequenceInfo = null;\r
-  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI seq) {\r
-    wsInfo = setWebService(sh);\r
-    startJPredClient(title, seq);\r
-  }\r
-  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI[] msa) {\r
-    wsInfo = setWebService(sh);\r
-    startJPredClient(title, msa);\r
-  }\r
-\r
-  public JPredClient(String title, SequenceI[] msf) {\r
-    startJPredClient(title, msf);\r
-  }\r
-\r
-  public JPredClient(String title, SequenceI seq) {\r
-    startJPredClient(title, seq);\r
-  }\r
-\r
-  private void startJPredClient(String title, SequenceI[] msf)\r
-  {\r
-    if (wsInfo==null)\r
-      wsInfo = setWebService();\r
-\r
-    SequenceI seq = msf[0];\r
-\r
-    altitle = "JNet prediction on " + seq.getName() +\r
-        " using alignment from " + title;\r
-\r
-    wsInfo.setProgressText("Job details for MSA based prediction (" +\r
-                           title + ") on sequence :\n>" + seq.getName() + "\n" +\r
-                           AlignSeq.extractGaps("-. ", seq.getSequence()) +\r
-                           "\n");\r
-    SequenceI aln[] = new SequenceI[msf.length];\r
-    for (int i=0,j=msf.length; i<j;i++) {\r
-        aln[i] = new jalview.datamodel.Sequence(msf[i]);\r
-    }\r
-\r
-    SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln, true);\r
-\r
-    if (!locateWebService())\r
-    {\r
-      return;\r
-    }\r
-\r
-    JPredThread jthread = new JPredThread(aln);\r
-    jthread.start();\r
-  }\r
-\r
-  public void startJPredClient(String title, SequenceI seq)\r
-  {\r
-    if (wsInfo==null)\r
-      wsInfo = setWebService();\r
-    wsInfo.setProgressText("Job details for prediction on sequence :\n>" +\r
-                           seq.getName() + "\n" +\r
-                           AlignSeq.extractGaps("-. ", seq.getSequence()) +\r
-                           "\n");\r
-    altitle = "JNet prediction for sequence " + seq.getName() + " from " +\r
-        title;\r
-\r
-    SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(seq);\r
-\r
-    if (!locateWebService())\r
-    {\r
-      return;\r
-    }\r
-\r
-    JPredThread jthread = new JPredThread(seq);\r
-    jthread.start();\r
-  }\r
-\r
-  private WebserviceInfo setWebService()\r
-  {\r
-    WebServiceName = "JNetWS";\r
-    WebServiceJobTitle = "JNet secondary structure prediction";\r
-    WebServiceReference =\r
-        "\"Cuff J. A and Barton G.J (2000) Application of " +\r
-        "multiple sequence alignment profiles to improve protein secondary structure prediction, " +\r
-        "Proteins 40:502-511\".";\r
-    WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";\r
-\r
-    WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,\r
-                                               WebServiceReference);\r
-\r
-    return wsInfo;\r
-  }\r
-\r
-  private boolean locateWebService()\r
-  {\r
-    ext.vamsas.JpredServiceLocator loc = new JpredServiceLocator(); // Default\r
-\r
-    try\r
-    {\r
-      this.server = loc.getjpred(new java.net.URL(WsURL)); // JBPNote will be set from properties\r
-      ( (JpredSoapBindingStub)this.server).setTimeout(60000); // one minute stub\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                    "The Secondary Structure Prediction Service named " +\r
-                                    WebServiceName + " at " + WsURL +\r
-                                    " couldn't be located.",\r
-                                    "Internal Jalview Error",\r
-                                    JOptionPane.WARNING_MESSAGE);\r
-      wsInfo.setProgressText("Serious! " + WebServiceName +\r
-                             " Service location failed\nfor URL :" + WsURL +\r
-                             "\n" +\r
-                             ex.getMessage());\r
-      wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);\r
-\r
-      return false;\r
-    }\r
-\r
-    return true;\r
-  }\r
-\r
-  class JPredThread\r
-      extends Thread\r
-  {\r
-    String OutputHeader;\r
-    vamsas.objects.simple.JpredResult result;\r
-    vamsas.objects.simple.Sequence sequence;\r
-    vamsas.objects.simple.Msfalignment msa;\r
-    String jobId;\r
-    boolean jobComplete = false;\r
-    int allowedServerExceptions = 3; // thread dies if too many exceptions.\r
-\r
-    JPredThread(SequenceI seq)\r
-    {\r
-      OutputHeader = wsInfo.getProgressText();\r
-      this.sequence = new vamsas.objects.simple.Sequence();\r
-      this.sequence.setId(seq.getName());\r
-      this.sequence.setSeq(AlignSeq.extractGaps("-. ", seq.getSequence()));\r
-    }\r
-\r
-    JPredThread(SequenceI[] msf)\r
-    {\r
-      OutputHeader = wsInfo.getProgressText();\r
-      this.sequence = new vamsas.objects.simple.Sequence();\r
-      this.sequence.setId(msf[0].getName());\r
-      this.sequence.setSeq(AlignSeq.extractGaps("-. ",\r
-                                                msf[0].getSequence()));\r
-\r
-      this.msa = new vamsas.objects.simple.Msfalignment();\r
-      jalview.io.PileUpfile pileup = new jalview.io.PileUpfile();\r
-      msa.setMsf(pileup.print(msf));\r
-    }\r
-\r
-    public void run()\r
-    {\r
-      StartJob();\r
-\r
-      while (!jobComplete && (allowedServerExceptions > 0))\r
-      {\r
-        try\r
-        {\r
-          if ( (result = server.getresult(jobId)) == null)\r
-          {\r
-            throw (new Exception(\r
-                "Timed out when communicating with server\nTry again later.\n"));\r
-          }\r
-          if (result.getState()==0)\r
-            jalview.bin.Cache.log.debug("Finished "+jobId);\r
-          if (result.isRunning())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);\r
-          }\r
-          if (result.isQueued())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);\r
-          }\r
-\r
-          wsInfo.setProgressText(OutputHeader + "\n" +\r
-                                 result.getStatus());\r
-\r
-          if (result.isFinished())\r
-          {\r
-\r
-            parseResult();\r
-            jobComplete = true;\r
-            jobsRunning--;\r
-          } else {\r
-            // catch exceptions\r
-            if (! (result.isJobFailed() || result.isServerError()))\r
-            {\r
-              try\r
-              {\r
-                Thread.sleep(5000);\r
-              }\r
-              catch (InterruptedException ex1)\r
-              {\r
-              }\r
-\r
-              //  System.out.println("I'm alive "+seqid+" "+jobid);\r
-            }\r
-            else\r
-            {\r
-              wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
-              jobsRunning--;\r
-              jobComplete = true;\r
-            }\r
-          }\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          allowedServerExceptions--;\r
-          wsInfo.appendProgressText("\nJPredWS Server exception!\n" +\r
-                                    ex.getMessage());\r
-\r
-          try\r
-          {\r
-            if (allowedServerExceptions > 0)\r
-            {\r
-              Thread.sleep(5000);\r
-            }\r
-          }\r
-          catch (InterruptedException ex1)\r
-          {\r
-          }\r
-        }\r
-        catch (OutOfMemoryError er)\r
-        {\r
-          jobComplete = true;\r
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
-          JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-                                                "Out of memory handling result!!"\r
-                                                +\r
-              "\nSee help files for increasing Java Virtual Machine memory."\r
-                                                , "Out of memory",\r
-                                                JOptionPane.WARNING_MESSAGE);\r
-          System.out.println("JPredClient: "+er);\r
-          System.gc();\r
-        }\r
-      }\r
-      if (result!=null)\r
-        if (! (result.isJobFailed() || result.isServerError()))\r
-        {\r
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
-        }\r
-        else\r
-        {\r
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
-        }\r
-    }\r
-\r
-    void StartJob()\r
-    {\r
-      try\r
-      {\r
-        if (msa != null)\r
-        {\r
-          jobId = server.predictOnMsa(msa);\r
-        }\r
-        else\r
-        {\r
-          jobId = server.predict(sequence);\r
-        }\r
-\r
-        if (jobId != null)\r
-        {\r
-          if (jobId.startsWith("Broken"))\r
-          {\r
-            throw new Exception("Submission " + jobId);\r
-          }\r
-          else\r
-          {\r
-            System.out.println(WsURL + " Job Id '" + jobId + "'");\r
-          }\r
-        }\r
-        else\r
-        {\r
-          throw new Exception("Server timed out - try again later\n");\r
-        }\r
-      }\r
-      catch (Exception e)\r
-      {\r
-        if (e.getMessage().indexOf("Exception")>-1) {\r
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);\r
-          wsInfo.setProgressText(\r
-              "Failed to submit the prediction. (Just close the window)\n"\r
-              +\r
-              "It is most likely that there is a problem with the server.\n");\r
-          System.err.println(\r
-              "JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" +\r
-              e.getMessage() + "\n");\r
-\r
-          jalview.bin.Cache.log.warn("Server Exception",e);\r
-        } else {\r
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
-          // JBPNote - this could be a popup informing the user of the problem.\r
-          wsInfo.setProgressText("Failed to submit the prediction:\n"\r
-                                 +e.getMessage()+\r
-                                 wsInfo.getProgressText());\r
-\r
-          jalview.bin.Cache.log.debug("Failed Submission",e);\r
-\r
-        }\r
-        allowedServerExceptions = -1;\r
-        jobComplete = true;\r
-\r
-      }\r
-    }\r
-\r
-\r
-\r
-  /*  private void addFloatAnnotations(Alignment al, int[] gapmap,\r
-                                     Vector values, String Symname,\r
-                                     String Visname, float min,\r
-                                     float max, int winLength)\r
-    {\r
-      Annotation[] annotations = new Annotation[al.getWidth()];\r
-\r
-      for (int j = 0; j < values.size(); j++)\r
-      {\r
-        float value = Float.parseFloat(values.get(j).toString());\r
-        annotations[gapmap[j]] = new Annotation("", value + "", ' ',\r
-                                                value);\r
-      }\r
-\r
-      al.addAnnotation(new AlignmentAnnotation(Symname, Visname,\r
-                                               annotations, min, max, winLength));\r
-    }*/\r
-\r
-    void parseResult()\r
-    {\r
-      // OutputHeader = output.getText();\r
-      if (result.isFailed())\r
-      {\r
-        OutputHeader += "Job failed.\n";\r
-      }\r
-\r
-      if (result.getStatus() != null)\r
-      {\r
-        OutputHeader += ("\n" + result.getStatus());\r
-      }\r
-\r
-      if (result.getPredfile() != null)\r
-      {\r
-        OutputHeader += ("\n" + result.getPredfile());\r
-\r
-        // JBPNote The returned files from a webservice could be hidden behind icons in the monitor window that, when clicked, pop up their corresponding data\r
-      }\r
-\r
-      if (result.getAligfile() != null)\r
-      {\r
-        OutputHeader += ("\n" + result.getAligfile());\r
-      }\r
-\r
-      wsInfo.setProgressText(OutputHeader+"Parsing...");\r
-\r
-      try\r
-      {\r
-        jalview.bin.Cache.log.debug("Parsing output from JNet job.");\r
-        // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", "File");\r
-        jalview.io.JPredFile prediction = new jalview.io.JPredFile(result.\r
-            getPredfile(),\r
-            "Paste");\r
-        SequenceI[] preds = prediction.getSeqsAsArray();\r
-        jalview.bin.Cache.log.debug("Got prediction profile.");\r
-        Alignment al;\r
-        int FirstSeq; // the position of the query sequence in Alignment al\r
-        boolean noMsa = true; // set if no MSA has been returned by JPred\r
-\r
-        if ( (this.msa != null) && (result.getAligfile() != null))\r
-        {\r
-          jalview.bin.Cache.log.debug("Getting associated alignment.");\r
-          // we ignore the returned alignment if we only predicted on a single sequence\r
-          String format = new jalview.io.IdentifyFile().Identify(result.getAligfile(),\r
-              "Paste");\r
-\r
-          if (jalview.io.FormatAdapter.formats.contains(format))\r
-          {\r
-            al = new Alignment(new FormatAdapter().readFile(\r
-                result.getAligfile(), "Paste", format));\r
-            SequenceI sqs[] = new SequenceI[al.getHeight()];\r
-            for (int i=0, j=al.getHeight(); i<j; i++) {\r
-              sqs[i] = al.getSequenceAt(i);\r
-            }\r
-            if (!jalview.analysis.SeqsetUtils.deuniquify(\r
-                  (Hashtable) SequenceInfo,sqs))\r
-              {\r
-                throw (new Exception(\r
-                    "Couldn't recover sequence properties for alignment."));\r
-              }\r
-\r
-            noMsa = false;\r
-            FirstSeq = 0;\r
-          }\r
-          else\r
-          {\r
-            throw (new Exception(\r
-                "Unknown format 'format' for file : \n" +\r
-                result.getAligfile()));\r
-          }\r
-        }\r
-        else\r
-        {\r
-          al = new Alignment(preds);\r
-          FirstSeq = prediction.getQuerySeqPosition();\r
-          if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(\r
-              al.getSequenceAt(FirstSeq), SequenceInfo))\r
-          {\r
-            throw (new Exception(\r
-                "Couldn't recover sequence properties for JNet Query sequence!"));\r
-          }\r
-        }\r
-\r
-        al.setDataset(null);\r
-\r
-        AlignmentAnnotation annot;\r
-        Annotation[] annotations = null;\r
-        int i = 0;\r
-        int width = preds[0].getSequence().length();\r
-\r
-        int[] gapmap = al.getSequenceAt(FirstSeq).gapMap();\r
-\r
-        if (gapmap.length != width)\r
-        {\r
-          throw (new Exception(\r
-              "Jnet Client Error\nNumber of residues in supposed query sequence :\n" +\r
-              al.getSequenceAt(FirstSeq).getName() + "\n" +\r
-              al.getSequenceAt(FirstSeq).getSequence() +\r
-              "\nDiffer from number of prediction sites in \n" +\r
-              result.getPredfile() + "\n"));\r
-        }\r
-\r
-        // JBPNote Should also rename the query sequence sometime...\r
-        i = 0;\r
-\r
-        SequenceI seqRef = al.getSequenceAt(FirstSeq);\r
-\r
-        while (i < preds.length)\r
-        {\r
-          String id = preds[i].getName().toUpperCase();\r
-\r
-          if (id.startsWith("LUPAS") || id.startsWith("JNET") ||\r
-              id.startsWith("JPRED"))\r
-          {\r
-            annotations = new Annotation[al.getWidth()];\r
-\r
-            if (id.equals("JNETPRED") || id.equals("JNETPSSM") ||\r
-                id.equals("JNETFREQ") || id.equals("JNETHMM") ||\r
-                id.equals("JNETALIGN") || id.equals("JPRED"))\r
-            {\r
-              for (int j = 0; j < width; j++)\r
-              {\r
-                annotations[gapmap[j]] = new Annotation("", "",\r
-                    preds[i].getCharAt(j), 0);\r
-              }\r
-            }\r
-            else if (id.equals("JNETCONF"))\r
-            {\r
-              for (int j = 0; j < width; j++)\r
-              {\r
-                float value = Float.parseFloat(preds[i].getCharAt(\r
-                    j) + "");\r
-                annotations[gapmap[j]] = new Annotation(preds[i].getCharAt(\r
-                    j) + "", "", preds[i].getCharAt(j),\r
-                    value);\r
-              }\r
-            }\r
-            else\r
-            {\r
-              for (int j = 0; j < width; j++)\r
-              {\r
-                annotations[gapmap[j]] = new Annotation(preds[i].getCharAt(\r
-                    j) + "", "", ' ', 0);\r
-              }\r
-            }\r
-\r
-            if (id.equals("JNETCONF"))\r
-            {\r
-              annot = new AlignmentAnnotation(preds[i].getName(),\r
-                                              "JNet Output", annotations, 0f,\r
-                                              10f,\r
-                                              AlignmentAnnotation.BAR_GRAPH);\r
-            }\r
-            else\r
-            {\r
-              annot = new AlignmentAnnotation(preds[i].getName(),\r
-                                              "JNet Output", annotations);\r
-            }\r
-\r
-            al.addAnnotation(annot, seqRef);\r
-\r
-            if (noMsa)\r
-            {\r
-              al.deleteSequence(preds[i]);\r
-            }\r
-          }\r
-\r
-          i++;\r
-        }\r
-\r
-        //Hashtable scores = prediction.getScores();\r
-\r
-        /*  addFloatAnnotations(al, gapmap,  (Vector)scores.get("JNETPROPH"),\r
-                              "JnetpropH", "Jnet Helix Propensity", 0f,1f,1);\r
-\r
-          addFloatAnnotations(al, gapmap,  (Vector)scores.get("JNETPROPB"),\r
-         "JnetpropB", "Jnet Beta Sheet Propensity", 0f,1f,1);\r
-\r
-          addFloatAnnotations(al, gapmap,  (Vector)scores.get("JNETPROPC"),\r
-                              "JnetpropC", "Jnet Coil Propensity", 0f,1f,1);\r
-         */\r
-\r
-        wsInfo.setProgressText(OutputHeader);\r
-        jalview.bin.Cache.log.debug("Finished parsing output.");\r
-        AlignFrame af = new AlignFrame(al);\r
-\r
-        Desktop.addInternalFrame(af, altitle,\r
-                                 AlignFrame.NEW_WINDOW_WIDTH,\r
-                                 AlignFrame.NEW_WINDOW_HEIGHT);\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        jalview.bin.Cache.log.warn("Exception whilst parsing JNet style secondary structure prediction.",ex);\r
-      }\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.ws;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import ext.vamsas.*;
+import jalview.analysis.*;
+import jalview.bin.*;
+import jalview.datamodel.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentView;
+import jalview.gui.*;
+import jalview.io.*;
+import jalview.util.*;
+import jalview.ws.WSThread.*;
+import vamsas.objects.simple.*;
+
+public class JPredClient
+    extends WSClient
+{
+    /**
+     * crate a new GUI JPred Job
+     * @param sh ServiceHandle
+     * @param title String
+     * @param msa boolean - true - submit alignment as a sequence profile
+     * @param alview AlignmentView
+     */
+    public JPredClient(ext.vamsas.ServiceHandle sh, String title, boolean msa, AlignmentView alview, AlignFrame parentFrame) {
+    super();
+    wsInfo=setWebService(sh);
+    startJPredClient(title, msa, alview, parentFrame);
+
+  }
+  /**
+   * startJPredClient
+   * TODO: refine submission to cope with local prediction of visible regions or multiple single sequence jobs
+   * TODO: sequence representative support - could submit alignment of representatives as msa.
+   * TODO:  msa hidden region prediction - submit each chunk for prediction. concatenate results of each.
+   * TODO:  single seq prediction - submit each contig of each sequence for prediction (but must cope with flanking regions and short seqs)
+   * @param title String
+   * @param msa boolean
+   * @param alview AlignmentView
+   */
+  private void startJPredClient(String title, boolean msa,
+                                jalview.datamodel.AlignmentView alview, AlignFrame parentFrame)
+  {
+    AlignmentView input = alview;
+    if (wsInfo == null)
+    {
+      wsInfo = setWebService();
+    }
+    Jpred server = locateWebService();
+    if (server == null)
+    {
+      Cache.log.warn("Couldn't find a Jpred webservice to invoke!");
+      return;
+    }
+
+    SeqCigar[] msf = input.getSequences();
+    SequenceI seq = msf[0].getSeq('-');
+    if (msa && msf.length > 1)
+    {
+
+      String altitle = "JNet prediction on " + seq.getName() +
+          " using alignment from " + title;
+
+      wsInfo.setProgressText("Job details for MSA based prediction (" +
+                             title + ") on sequence :\n>" + seq.getName() +
+                             "\n" +
+                             AlignSeq.extractGaps("-. ", seq.getSequence()) +
+                             "\n");
+      SequenceI aln[] = new SequenceI[msf.length];
+      for (int i = 0, j = msf.length; i < j; i++)
+      {
+        aln[i] = msf[i].getSeq('-');
+      }
+
+      Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln, true);
+
+      JPredThread jthread = new JPredThread(wsInfo, altitle, server,
+                                            SequenceInfo, aln, alview, parentFrame);
+      wsInfo.setthisService(jthread);
+      jthread.start();
+    }
+    else
+    {
+      if (!msa && msf.length>1)
+        throw new Error("Implementation Error! Multiple single sequence prediction jobs are not yet supported.");
+      wsInfo.setProgressText("Job details for prediction on sequence :\n>" +
+                             seq.getName() + "\n" +
+                             AlignSeq.extractGaps("-. ", seq.getSequence()) +
+                             "\n");
+      String altitle = "JNet prediction for sequence " + seq.getName() +
+          " from " +
+          title;
+
+      Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(
+          seq);
+
+      JPredThread jthread = new JPredThread(wsInfo, altitle, server,
+                                            SequenceInfo, seq, alview, parentFrame);
+      wsInfo.setthisService(jthread);
+      jthread.start();
+    }
+  }
+  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI seq, AlignFrame parentFrame)
+  {
+    super();
+    wsInfo = setWebService(sh);
+    startJPredClient(title, seq, parentFrame);
+  }
+
+  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI[] msa, AlignFrame parentFrame)
+  {
+    wsInfo = setWebService(sh);
+    startJPredClient(title, msa, parentFrame);
+  }
+
+  public JPredClient(String title, SequenceI[] msf)
+  {
+    startJPredClient(title, msf, null);
+  }
+
+  public JPredClient(String title, SequenceI seq)
+  {
+    startJPredClient(title, seq, null);
+  }
+
+  private void startJPredClient(String title, SequenceI[] msf, AlignFrame parentFrame)
+  {
+    if (wsInfo == null)
+    {
+      wsInfo = setWebService();
+    }
+
+    SequenceI seq = msf[0];
+
+    String altitle = "JNet prediction on " + seq.getName() +
+        " using alignment from " + title;
+
+    wsInfo.setProgressText("Job details for MSA based prediction (" +
+                           title + ") on sequence :\n>" + seq.getName() + "\n" +
+                           AlignSeq.extractGaps("-. ", seq.getSequence()) +
+                           "\n");
+    SequenceI aln[] = new SequenceI[msf.length];
+    for (int i = 0, j = msf.length; i < j; i++)
+    {
+      aln[i] = new jalview.datamodel.Sequence(msf[i]);
+    }
+
+    Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln, true);
+
+    Jpred server = locateWebService();
+    if (server==null)
+    {
+      return;
+    }
+
+    JPredThread jthread = new JPredThread(wsInfo, altitle, server, SequenceInfo, aln,null, parentFrame);
+    wsInfo.setthisService(jthread);
+    jthread.start();
+  }
+
+  public void startJPredClient(String title, SequenceI seq, AlignFrame parentFrame)
+  {
+    if (wsInfo == null)
+    {
+      wsInfo = setWebService();
+    }
+    wsInfo.setProgressText("Job details for prediction on sequence :\n>" +
+                           seq.getName() + "\n" +
+                           AlignSeq.extractGaps("-. ", seq.getSequence()) +
+                           "\n");
+    String altitle = "JNet prediction for sequence " + seq.getName() + " from " +
+        title;
+
+    Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(seq);
+
+    Jpred server = locateWebService();
+    if (server==null)
+    {
+      return;
+    }
+
+    JPredThread jthread = new JPredThread(wsInfo, altitle, server, SequenceInfo, seq,null, parentFrame);
+    wsInfo.setthisService(jthread);
+    jthread.start();
+  }
+
+  private WebserviceInfo setWebService()
+  {
+    WebServiceName = "JNetWS";
+    WebServiceJobTitle = "JNet secondary structure prediction";
+    WebServiceReference =
+        "\"Cuff J. A and Barton G.J (2000) Application of " +
+        "multiple sequence alignment profiles to improve protein secondary structure prediction, " +
+        "Proteins 40:502-511\".";
+    WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";
+
+    WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,
+                                               WebServiceReference);
+
+    return wsInfo;
+  }
+
+  private ext.vamsas.Jpred locateWebService()
+  {
+    ext.vamsas.JpredServiceLocator loc = new JpredServiceLocator(); // Default
+    ext.vamsas.Jpred server=null;
+    try
+    {
+      server = loc.getjpred(new java.net.URL(WsURL)); // JBPNote will be set from properties
+      ( (JpredSoapBindingStub)server).setTimeout(60000); // one minute stub
+      //((JpredSoapBindingStub)this.server)._setProperty(org.apache.axis.encoding.C, Boolean.TRUE);
+
+    }
+    catch (Exception ex)
+    {
+      JOptionPane.showMessageDialog(Desktop.desktop,
+                                    "The Secondary Structure Prediction Service named " +
+                                    WebServiceName + " at " + WsURL +
+                                    " couldn't be located.",
+                                    "Internal Jalview Error",
+                                    JOptionPane.WARNING_MESSAGE);
+      wsInfo.setProgressText("Serious! " + WebServiceName +
+                             " Service location failed\nfor URL :" + WsURL +
+                             "\n" +
+                             ex.getMessage());
+      wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
+
+    }
+
+    return server;
+  }
+
+  class JPredThread
+      extends WSThread
+      implements WSClientI
+  {
+    class JPredJob
+        extends WSThread.WSJob
+    {
+
+      vamsas.objects.simple.Sequence sequence;
+      vamsas.objects.simple.Msfalignment msa;
+      java.util.Hashtable SequenceInfo = null;
+      /**
+       *
+       * @return true if getResultSet will return a valid alignment and prediction result.
+       */
+      public boolean hasResults()
+      {
+        if (subjobComplete && result != null && result.isFinished()
+            && ( (JpredResult) result).getPredfile() != null &&
+            ( (JpredResult) result).getAligfile() != null)
+        {
+          return true;
+        }
+        return false;
+      }
+
+      boolean hasValidInput()
+      {
+        if (sequence != null)
+        {
+          return true;
+        }
+        return false;
+      }
+
+      public Alignment getResultSet()
+          throws Exception
+      {
+        if (result == null || !result.isFinished())
+        {
+          return null;
+        }
+        Alignment al = null;
+        int FirstSeq = -1; // the position of the query sequence in Alignment al
+
+        JpredResult result = (JpredResult)this.result;
+
+        jalview.bin.Cache.log.debug("Parsing output from JNet job.");
+        // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", "File");
+        jalview.io.JPredFile prediction = new jalview.io.JPredFile(result.
+            getPredfile(),
+            "Paste");
+        SequenceI[] preds = prediction.getSeqsAsArray();
+        jalview.bin.Cache.log.debug("Got prediction profile.");
+
+        if ( (this.msa != null) && (result.getAligfile() != null))
+        {
+          jalview.bin.Cache.log.debug("Getting associated alignment.");
+          // we ignore the returned alignment if we only predicted on a single sequence
+          String format = new jalview.io.IdentifyFile().Identify(result.
+              getAligfile(),
+              "Paste");
+
+          if (jalview.io.FormatAdapter.isValidFormat(format))
+          {
+            al = new Alignment(new FormatAdapter().readFile(result.getAligfile(),
+                "Paste", format));
+            SequenceI sqs[] = new SequenceI[al.getHeight()];
+            for (int i = 0, j = al.getHeight(); i < j; i++)
+            {
+              sqs[i] = al.getSequenceAt(i);
+            }
+            if (!jalview.analysis.SeqsetUtils.deuniquify( (Hashtable)
+                SequenceInfo, sqs))
+            {
+              throw (new Exception(
+                  "Couldn't recover sequence properties for alignment."));
+            }
+
+            FirstSeq = 0;
+            al.setDataset(null);
+
+            jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq,
+                                                          false);
+
+          }
+          else
+          {
+            throw (new Exception(
+                "Unknown format "+format+" for file : \n" +
+                result.getAligfile()));
+          }
+        }
+        else
+        {
+          al = new Alignment(preds);
+          FirstSeq = prediction.getQuerySeqPosition();
+          if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(
+              al.getSequenceAt(FirstSeq), SequenceInfo))
+          {
+            throw (new Exception(
+                "Couldn't recover sequence properties for JNet Query sequence!"));
+          } else {
+            al.setDataset(null);
+            jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq,
+                true);
+          }
+        }
+
+        return al; // , FirstSeq, noMsa};
+      }
+      public JPredJob(Hashtable SequenceInfo, SequenceI seq)
+      {
+        super();
+        String sq = AlignSeq.extractGaps(Comparison.GapChars, seq.getSequence());
+        if (sq.length() >= 20)
+        {
+          this.SequenceInfo = SequenceInfo;
+          sequence = new vamsas.objects.simple.Sequence();
+          sequence.setId(seq.getName());
+          sequence.setSeq(sq);
+        }
+      }
+
+      public JPredJob(Hashtable SequenceInfo, SequenceI[] msf)
+      {
+        this(SequenceInfo, msf[0]);
+        if (sequence != null)
+        {
+          if (msf.length > 1)
+          {
+            msa = new vamsas.objects.simple.Msfalignment();
+            jalview.io.PileUpfile pileup = new jalview.io.PileUpfile();
+            msa.setMsf(pileup.print(msf));
+          }
+        }
+      }
+    }
+    ext.vamsas.Jpred server;
+    String altitle = "";
+    JPredThread(WebserviceInfo wsinfo, String altitle, ext.vamsas.Jpred server, AlignmentView alview, AlignFrame alframe) {
+      this.altitle = altitle;
+      this.server = server;
+      this.wsInfo = wsinfo;
+      this.input = alview;
+      this.alignFrame = alframe;
+    }
+
+//    String OutputHeader;
+//    vamsas.objects.simple.JpredResult result;
+
+    JPredThread(WebserviceInfo wsinfo, String altitle, ext.vamsas.Jpred server, Hashtable SequenceInfo,SequenceI seq, AlignmentView alview, AlignFrame alframe)
+    {
+      this(wsinfo, altitle, server,alview, alframe);
+      JPredJob job = new JPredJob(SequenceInfo, seq);
+      if (job.hasValidInput())
+      {
+        OutputHeader = wsInfo.getProgressText();
+        jobs = new WSJob[]
+            {
+            job};
+        job.jobnum = 0;
+      }
+    }
+
+    JPredThread(WebserviceInfo wsinfo, String altitle, ext.vamsas.Jpred server, Hashtable SequenceInfo, SequenceI[] msf, AlignmentView alview, AlignFrame alframe)
+    {
+      this(wsinfo, altitle, server,alview, alframe);
+      JPredJob job = new JPredJob(SequenceInfo, msf);
+      if (job.hasValidInput())
+      {
+        jobs = new WSJob[]
+            {
+            job};
+        OutputHeader = wsInfo.getProgressText();
+        job.jobnum = 0;
+      }
+    }
+
+    /*
+        public void run()
+        {
+          StartJob();
+
+          while (!jobComplete && (allowedServerExceptions > 0))
+          {
+            try
+            {
+              if ( (result = server.getresult(jobId)) == null)
+              {
+                throw (new Exception(
+     "Timed out when communicating with server\nTry again later.\n"));
+              }
+              if (result.getState()==0)
+                jalview.bin.Cache.log.debug("Finished "+jobId);
+              if (result.isRunning())
+              {
+                wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);
+              }
+              if (result.isQueued())
+              {
+                wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);
+              }
+
+              wsInfo.setProgressText(OutputHeader + "\n" +
+                                     result.getStatus());
+
+              if (result.isFinished())
+              {
+
+                parseResult();
+                jobComplete = true;
+                jobsRunning--;
+              } else {
+                // catch exceptions
+                if (! (result.isJobFailed() || result.isServerError()))
+                {
+                  try
+                  {
+                    Thread.sleep(5000);
+                  }
+                  catch (InterruptedException ex1)
+                  {
+                  }
+
+                  //  System.out.println("I'm alive "+seqid+" "+jobid);
+                }
+                else
+                {
+                  wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+                  jobsRunning--;
+                  jobComplete = true;
+                }
+              }
+            }
+            catch (Exception ex)
+            {
+              allowedServerExceptions--;
+
+              wsInfo.appendProgressText("\nJPredWS Server exception!\n" +
+                                        ex.getMessage());
+
+              try
+              {
+                if (allowedServerExceptions > 0)
+                {
+                  Thread.sleep(5000);
+                }
+              }
+              catch (InterruptedException ex1)
+              {
+              }
+            }
+            catch (OutOfMemoryError er)
+            {
+              jobComplete = true;
+              wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+              JOptionPane.showInternalMessageDialog(Desktop.desktop,
+     "Out of memory handling result!!"
+                                                    +
+     "\nSee help files for increasing Java Virtual Machine memory."
+                                                    , "Out of memory",
+     JOptionPane.WARNING_MESSAGE);
+              System.out.println("JPredClient: "+er);
+              System.gc();
+            }
+          }
+          if (result!=null)
+            if (! (result.isJobFailed() || result.isServerError()))
+            {
+              wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);
+            }
+            else
+            {
+              wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+            }
+        }
+     */
+    void StartJob(WSJob j)
+    {
+      if (! (j instanceof JPredJob))
+      {
+        throw new Error("Implementation error - StartJob(JpredJob) called on " +
+                        j.getClass());
+      }
+      try
+      {
+        JPredJob job = (JPredJob) j;
+        if (job.msa != null)
+        {
+          job.jobId = server.predictOnMsa(job.msa);
+        }
+        else
+          if (job.sequence!=null)
+          {
+            job.jobId = server.predict(job.sequence); // debug like : job.jobId = "/jobs/www-jpred/jp_Yatat29";//
+          }
+
+        if (job.jobId != null)
+        {
+          if (job.jobId.startsWith("Broken"))
+          {
+            job.result = (vamsas.objects.simple.Result)new JpredResult();
+            job.result.setInvalid(true);
+            job.result.setStatus("Submission " + job.jobId);
+          }
+          else
+          {
+            job.submitted = true;
+            job.subjobComplete = false;
+            Cache.log.info(WsURL + " Job Id '" + job.jobId + "'");
+          }
+        }
+        else
+        {
+          throw new Exception("Server timed out - try again later\n");
+        }
+      }
+      catch (Exception e)
+      {
+        if (e.getMessage().indexOf("Exception") > -1)
+        {
+          wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_SERVERERROR);
+          wsInfo.setProgressText(j.jobnum,
+                                 "Failed to submit the prediction. (Just close the window)\n"
+                                 +
+                                 "It is most likely that there is a problem with the server.\n");
+          System.err.println(
+              "JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" +
+              e.getMessage() + "\n");
+
+          jalview.bin.Cache.log.warn("Server Exception", e);
+        }
+        else
+        {
+          wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_ERROR);
+          // JBPNote - this could be a popup informing the user of the problem.
+          wsInfo.appendProgressText(j.jobnum,
+                                    "Failed to submit the prediction:\n"
+                                    + e.getMessage() +
+                                    wsInfo.getProgressText());
+
+          jalview.bin.Cache.log.debug("Failed Submission of job " + j.jobnum, e);
+
+        }
+        j.allowedServerExceptions = -1;
+        j.subjobComplete = true;
+      }
+    }
+
+    /*  private void addFloatAnnotations(Alignment al, int[] gapmap,
+                                       Vector values, String Symname,
+                                       String Visname, float min,
+                                       float max, int winLength)
+      {
+        Annotation[] annotations = new Annotation[al.getWidth()];
+
+        for (int j = 0; j < values.size(); j++)
+        {
+          float value = Float.parseFloat(values.get(j).toString());
+          annotations[gapmap[j]] = new Annotation("", value + "", ' ',
+                                                  value);
+        }
+
+        al.addAnnotation(new AlignmentAnnotation(Symname, Visname,
+     annotations, min, max, winLength));
+      }*/
+
+    void parseResult()
+    {
+      int results = 0; // number of result sets received
+      JobStateSummary finalState = new JobStateSummary();
+      try
+      {
+        for (int j = 0; j < jobs.length; j++)
+        {
+          finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]);
+          if (jobs[j].submitted && jobs[j].subjobComplete && jobs[j].hasResults())
+          {
+            results++;
+          }
+        }
+      }
+      catch (Exception ex)
+      {
+
+        Cache.log.error("Unexpected exception when processing results for " +
+                        altitle, ex);
+        wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+      }
+      if (results > 0)
+      {
+        wsInfo.showResultsNewFrame
+            .addActionListener(new java.awt.event.ActionListener()
+        {
+          public void actionPerformed(
+              java.awt.event.ActionEvent evt)
+          {
+            displayResults(true);
+          }
+        });
+        wsInfo.mergeResults
+            .addActionListener(new java.awt.event.ActionListener()
+        {
+          public void actionPerformed(
+              java.awt.event.ActionEvent evt)
+          {
+            displayResults(false);
+          }
+        });
+        wsInfo.setResultsReady();
+      }
+      else
+      {
+        wsInfo.setFinishedNoResults();
+      }
+    }
+
+    void displayResults(boolean newWindow)
+    {
+      // TODO: cope with multiple subjobs.
+      if (jobs != null)
+      {
+        Alignment res = null;
+        boolean msa=false;
+        for (int jn = 0; jn < jobs.length; jn++)
+        {
+          Alignment jobres = null;
+          JPredJob j = (JPredJob) jobs[jn];
+
+          if (j.hasResults())
+          {
+            // hack - we only deal with all single seuqence predictions or all profile predictions
+            msa = (j.msa!=null) ? true : msa;
+            try
+            {
+              jalview.bin.Cache.log.debug("Parsing output of job " + jn);
+              jobres = j.getResultSet();
+              jalview.bin.Cache.log.debug("Finished parsing output.");
+              if (jobs.length==1)
+                res = jobres;
+              else {
+                  // do merge with other job results
+                  throw new Error("Multiple JNet subjob merging not yet implemented.");
+              }
+            }
+            catch (Exception e)
+            {
+              jalview.bin.Cache.log.error(
+                  "JNet Client: JPred Annotation Parse Error",
+                  e);
+              wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_ERROR);
+              wsInfo.appendProgressText(j.jobnum,
+                                        OutputHeader + "\n" +
+                                        j.result.getStatus() +
+                                        "\nInvalid JNet job result data!\n" +
+                                        e.getMessage());
+              j.result.setBroken(true);
+            }
+          }
+        }
+
+        if (res != null)
+        {
+          if (newWindow)
+          {
+            AlignFrame af;
+           if (input==null) {
+             af = new AlignFrame(res);
+           } else {
+             java.lang.Object[] alandcolsel = input.getAlignmentAndColumnSelection(alignFrame.getViewport().getGapCharacter());
+
+             if (((SequenceI[])alandcolsel[0])[0].getLength()!=res.getWidth()) {
+               if (msa) {
+                 throw new Error("Implementation Error! ColumnSelection from input alignment will not map to result alignment!");
+               } else {
+                 // test this.
+                 ((ColumnSelection) alandcolsel[1]).pruneDeletions(ShiftList.parseMap(((SequenceI[]) alandcolsel[0])[0].gapMap()));//gapMap returns insert list, interpreted as delete list by pruneDeletions
+               }
+             }
+             af = new AlignFrame(res, (ColumnSelection) alandcolsel[1]);
+           }
+            Desktop.addInternalFrame(af, altitle,
+                                     AlignFrame.NEW_WINDOW_WIDTH,
+                                     AlignFrame.NEW_WINDOW_HEIGHT);
+          }
+          else
+          {
+            Cache.log.info("Append results onto existing alignment.");
+          }
+        }
+      }
+    }
+    void pollJob(WSJob job)
+        throws Exception
+    {
+      job.result = server.getresult(job.jobId);
+    }
+    public boolean isCancellable()
+    {
+      return false;
+    }
+
+    public void cancelJob()
+    {
+      throw new Error("Implementation error!");
+    }
+
+    public boolean canMergeResults()
+    {
+      return false;
+    }
+
+  }
+}
+
index 479f22f..61fb4b6 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-package jalview.ws;\r
-\r
-import ext.vamsas.*;\r
-\r
-import jalview.analysis.AlignSeq;\r
-\r
-import jalview.datamodel.*;\r
-\r
-import jalview.gui.*;\r
-\r
-import java.util.*;\r
-\r
-import javax.swing.*;\r
-\r
-/**\r
- * DOCUMENT ME!\r
- *\r
- * @author $author$\r
- * @version $Revision$\r
- */\r
-public class MsaWSClient\r
-    extends WSClient\r
-{\r
-  /**\r
-   * server is a WSDL2Java generated stub for an archetypal MsaWSI service.\r
-   */\r
-  ext.vamsas.MuscleWS server;\r
-\r
-\r
-  /**\r
-   * Creates a new MsaWSClient object that uses a service\r
-   * given by an externally retrieved ServiceHandle\r
-   *\r
-   * @param sh service handle of type AbstractName(MsaWS)\r
-   * @param altitle DOCUMENT ME!\r
-   * @param msa DOCUMENT ME!\r
-   * @param submitGaps DOCUMENT ME!\r
-   * @param preserveOrder DOCUMENT ME!\r
-   */\r
-\r
-  public MsaWSClient(ext.vamsas.ServiceHandle sh, String altitle, SequenceI[] msa,\r
-                     boolean submitGaps, boolean preserveOrder, Alignment seqdataset)\r
-  {\r
-\r
-    if (!sh.getAbstractName().equals("MsaWS"))\r
-    {\r
-      JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                    "The Service called \n" + sh.getName() +\r
-          "\nis not a \nMultiple Sequence Alignment Service !",\r
-                                    "Internal Jalview Error",\r
-                                    JOptionPane.WARNING_MESSAGE);\r
-\r
-      return;\r
-    }\r
-\r
-    if ((wsInfo = this.setWebService(sh))==null)\r
-     {\r
-       JOptionPane.showMessageDialog(Desktop.desktop,\r
-                                     "The Multiple Sequence Alignment Service named " +\r
-                                     sh.getName() +\r
-                                     " is unknown", "Internal Jalview Error",\r
-                                     JOptionPane.WARNING_MESSAGE);\r
-\r
-       return;\r
-     }\r
-    startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);\r
-\r
-  }\r
-\r
-\r
-  private void startMsaWSClient(String altitle, SequenceI[] msa,\r
-                     boolean submitGaps, boolean preserveOrder, Alignment seqdataset)\r
-  {\r
-    if (!locateWebService())\r
-    {\r
-      return;\r
-    }\r
-\r
-    wsInfo.setProgressText( ( (submitGaps) ? "Re-alignment" : "Alignment") +\r
-                           " of " + altitle + "\nJob details\n");\r
-\r
-    MsaWSThread musclethread = new MsaWSThread(WebServiceName +\r
-                                               " alignment of " + altitle, msa,\r
-                                               submitGaps, preserveOrder, seqdataset);\r
-    wsInfo.setthisService(musclethread);\r
-    musclethread.start();\r
-  }\r
-\r
-  /**\r
-   * Initializes the server field with a valid service implementation.\r
-   *\r
-   * @return true if service was located.\r
-   */\r
-  private boolean locateWebService()\r
-  {\r
-    // TODO: MuscleWS transmuted to generic MsaWS client\r
-    MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default\r
-\r
-    try\r
-    {\r
-      this.server = (MuscleWS) loc.getMuscleWS(new java.net.URL(WsURL));\r
-      ( (MuscleWSSoapBindingStub)this.server).setTimeout(60000); // One minute timeout\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      wsInfo.setProgressText("Serious! " + WebServiceName +\r
-                             " Service location failed\nfor URL :" + WsURL +\r
-                             "\n" +\r
-                             ex.getMessage());\r
-      wsInfo.setStatus(WebserviceInfo.ERROR);\r
-      ex.printStackTrace();\r
-\r
-      return false;\r
-    }\r
-\r
-    loc.getEngine().setOption("axis", "1");\r
-\r
-    return true;\r
-  }\r
-\r
-  protected class MsaWSThread\r
-      extends Thread implements WSClientI\r
-  {\r
-    String ServiceName = WebServiceName;\r
-    String OutputHeader;\r
-    vamsas.objects.simple.MsaResult result = null;\r
-    vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.\r
-        SequenceSet();\r
-    Hashtable SeqNames = null;\r
-    boolean submitGaps = false; // pass sequences including gaps to alignment service\r
-    boolean preserveOrder = true; // and always store and recover sequence order\r
-    String jobId;\r
-    String alTitle; // name which will be used to form new alignment window.\r
-    int allowedServerExceptions = 3; // thread dies if too many exceptions.\r
-    boolean jobComplete = false;\r
-\r
-    Alignment dataset; // dataset to which the new alignment will be associated.\r
-\r
-    MsaWSThread(String title, SequenceI[] msa, boolean subgaps,\r
-                boolean presorder, Alignment seqset)\r
-    {\r
-      alTitle = title;\r
-      submitGaps = subgaps;\r
-      preserveOrder = presorder;\r
-      dataset = seqset;\r
-      OutputHeader = wsInfo.getProgressText();\r
-      SeqNames = new Hashtable();\r
-\r
-      vamsas.objects.simple.Sequence[] seqarray = new vamsas.objects.simple.\r
-          Sequence[msa.length];\r
-\r
-      for (int i = 0; i < msa.length; i++)\r
-      {\r
-        String newname = jalview.analysis.SeqsetUtils.unique_name(i);\r
-\r
-        // uniquify as we go\r
-        // TODO: JBPNote: this is a ubiquitous transformation - set of jalview seq objects to vamsas sequences with name preservation\r
-        SeqNames.put(newname,\r
-                     jalview.analysis.SeqsetUtils.SeqCharacterHash(msa[i]));\r
-        seqarray[i] = new vamsas.objects.simple.Sequence();\r
-        seqarray[i].setId(newname);\r
-        seqarray[i].setSeq( (submitGaps) ? msa[i].getSequence()\r
-                           : AlignSeq.extractGaps(\r
-                               jalview.util.Comparison.GapChars,\r
-                               msa[i].getSequence()));\r
-      }\r
-\r
-      this.seqs = new vamsas.objects.simple.SequenceSet();\r
-      this.seqs.setSeqs(seqarray);\r
-    }\r
-\r
-    public boolean isCancellable()\r
-    {\r
-      return true;\r
-    }\r
-\r
-    public void cancelJob()\r
-    {\r
-      if ( (jobId != null) && !jobId.equals("") && !jobComplete)\r
-      {\r
-        String cancelledMessage = "";\r
-\r
-        try\r
-        {\r
-          vamsas.objects.simple.WsJobId cancelledJob = server.cancel(jobId);\r
-\r
-          if (cancelledJob.getStatus() == 2)\r
-          {\r
-            // CANCELLED_JOB\r
-            cancelledMessage = "Job cancelled.";\r
-            wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK);\r
-            jobComplete = true;\r
-            jobsRunning--;\r
-            result = null;\r
-          }\r
-          else if (cancelledJob.getStatus() == 3)\r
-          {\r
-            // VALID UNSTOPPABLE JOB\r
-            cancelledMessage +=\r
-                "Server cannot cancel this job. just close the window.\n";\r
-          }\r
-\r
-          if (cancelledJob.getJobId() != null)\r
-          {\r
-            cancelledMessage += ("[" + cancelledJob.getJobId() +\r
-                                 "]");\r
-          }\r
-\r
-          cancelledMessage += "\n";\r
-        }\r
-        catch (Exception exc)\r
-        {\r
-          cancelledMessage +=\r
-              ("\nProblems cancelling the job : Exception received...\n" +\r
-               exc + "\n");\r
-          exc.printStackTrace();\r
-        }\r
-\r
-        wsInfo.setProgressText(OutputHeader + cancelledMessage + "\n");\r
-      }\r
-      else\r
-      {\r
-        if (!jobComplete)\r
-        {\r
-          wsInfo.setProgressText(OutputHeader +\r
-                                 "Server cannot cancel this job because it has not been submitted properly. just close the window.\n");\r
-        }\r
-      }\r
-    }\r
-\r
-    public void run()\r
-    {\r
-      StartJob();\r
-\r
-      while (!jobComplete && (allowedServerExceptions > 0))\r
-      {\r
-        try\r
-        {\r
-          if ( (result = server.getResult(jobId)) == null)\r
-          {\r
-            throw (new Exception(\r
-                "Timed out when communicating with server\nTry again later.\n"));\r
-          }\r
-          jalview.bin.Cache.log.debug("Result state " + result.getState() +\r
-                                        "(ServerError=" + result.isServerError() +\r
-                                        ")");\r
-          if (result.isRunning())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);\r
-          }\r
-          else if (result.isQueued())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);\r
-          }\r
-\r
-          if (result.isFinished())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
-            parseResult();\r
-            jobComplete = true;\r
-            jobsRunning--;\r
-          }\r
-          else\r
-          {\r
-            if (result.getStatus() != null)\r
-            {\r
-              wsInfo.setProgressText(OutputHeader + "\n"+   result.getStatus());\r
-            }\r
-            if (result.isServerError())\r
-            {\r
-              jobComplete = true;\r
-              jobsRunning--;\r
-\r
-              break;\r
-            }\r
-            if (! (result.isJobFailed() || result.isServerError() ||\r
-                   result.isBroken() || result.isFailed()))\r
-            {\r
-              Thread.sleep(5000);\r
-\r
-              //  System.out.println("I'm alive "+seqid+" "+jobid);\r
-            }\r
-            else\r
-            {\r
-              jobComplete = true;\r
-              jobsRunning--;\r
-              break;\r
-            }\r
-          }\r
-        }\r
-        catch (Exception ex)\r
-        {\r
-          allowedServerExceptions--;\r
-          wsInfo.appendProgressText("\n" + ServiceName +\r
-                                    " Server exception!\n" + ex.getMessage());\r
-          System.err.println(ServiceName + " Server exception: " +\r
-                             ex.getMessage());\r
-\r
-          //          ex.printStackTrace(); JBPNote Debug\r
-          try\r
-          {\r
-            if (allowedServerExceptions > 0)\r
-            {\r
-              Thread.sleep(5000);\r
-            }\r
-          }\r
-          catch (InterruptedException ex1)\r
-          {\r
-          }\r
-        }\r
-        catch(OutOfMemoryError er)\r
-        {\r
-          jobComplete = true;\r
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
-          JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-              "Out of memory handling result!!"\r
-             +"\nSee help files for increasing Java Virtual Machine memory."\r
-             ,"Out of memory", JOptionPane.WARNING_MESSAGE );\r
-          System.out.println("MsaWSClient: "+er);\r
-          System.gc();\r
-        }\r
-      }\r
-\r
-      if (allowedServerExceptions == 0)\r
-      {\r
-        wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);\r
-      }\r
-      else\r
-      {\r
-        if (result != null)\r
-        {\r
-          if ( !(result.isJobFailed() || result.isServerError()))\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
-          }\r
-\r
-          if (result.isBroken() || result.isFailed())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
-          }\r
-\r
-          if (result.isServerError())\r
-          {\r
-            wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    void StartJob()\r
-    {\r
-      try\r
-      {\r
-        vamsas.objects.simple.WsJobId jobsubmit = server.align(seqs);\r
-\r
-        if ( (jobsubmit != null) && (jobsubmit.getStatus() == 1))\r
-        {\r
-          jobId = jobsubmit.getJobId();\r
-          System.out.println(WsURL + " Job Id '" + jobId + "'");\r
-        }\r
-        else\r
-        {\r
-          if (jobsubmit == null)\r
-          {\r
-            throw new Exception("Server at " + WsURL +\r
-                                " returned null object, it probably cannot be contacted. Try again later ?");\r
-          }\r
-\r
-          throw new Exception(jobsubmit.getJobId());\r
-        }\r
-      }\r
-      catch (Exception e)\r
-      {\r
-        // TODO: JBPNote catch timeout or other fault types explicitly\r
-        // For unexpected errors\r
-        System.err.println(WebServiceName +\r
-                           "Client: Failed to submit the sequences for alignment (probably a server side problem)\n" +\r
-                           "When contacting Server:" + WsURL + "\n" +\r
-                           e.toString() +\r
-                           "\n");\r
-        this.allowedServerExceptions = 0;\r
-        wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);\r
-        wsInfo.appendProgressText(\r
-            "Failed to submit sequences for alignment.\n" +\r
-            "It is most likely that there is a problem with the server.\n" +\r
-            "Just close the window\n");\r
-\r
-        // e.printStackTrace(); // TODO: JBPNote DEBUG\r
-      }\r
-    }\r
-\r
-    private jalview.datamodel.Sequence[] getVamsasAlignment(\r
-        vamsas.objects.simple.Alignment valign)\r
-    {\r
-      vamsas.objects.simple.Sequence[] seqs = valign.getSeqs().getSeqs();\r
-      jalview.datamodel.Sequence[] msa = new jalview.datamodel.Sequence[seqs.\r
-          length];\r
-\r
-      for (int i = 0, j = seqs.length; i < j; i++)\r
-      {\r
-        msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(),\r
-                                                seqs[i].getSeq());\r
-      }\r
-\r
-      return msa;\r
-    }\r
-\r
-    void parseResult()\r
-    {\r
-      SequenceI[] seqs = null;\r
-\r
-      try\r
-      {\r
-        // OutputHeader = output.getText();\r
-        if (result.isFailed())\r
-        {\r
-          OutputHeader += "Job failed.\n";\r
-        }\r
-\r
-        if (result.getStatus() != null)\r
-        {\r
-          OutputHeader += ("\n" + result.getStatus());\r
-        }\r
-\r
-        if (result.getMsa() != null)\r
-        {\r
-          OutputHeader += "\nAlignment Object Method Notes\n";\r
-\r
-          String[] lines = result.getMsa().getMethod();\r
-\r
-          for (int line = 0; line < lines.length; line++)\r
-          {\r
-            OutputHeader += (lines[line] + "\n");\r
-          }\r
-\r
-          // JBPNote The returned files from a webservice could be hidden behind icons in the monitor window that, when clicked, pop up their corresponding data\r
-          seqs = getVamsasAlignment(result.getMsa());\r
-        }\r
-\r
-        wsInfo.setProgressText(OutputHeader);\r
-\r
-        if (seqs != null)\r
-        {\r
-          AlignmentOrder msaorder = new AlignmentOrder(seqs);\r
-\r
-          if (preserveOrder)\r
-          {\r
-            jalview.analysis.AlignmentSorter.recoverOrder(seqs);\r
-          }\r
-\r
-          jalview.analysis.SeqsetUtils.deuniquify(SeqNames, seqs);\r
-\r
-          Alignment al = new Alignment(seqs);\r
-          if (dataset!=null) {\r
-            al.setDataset(dataset);\r
-          }\r
-          // TODO: JBPNote Should also rename the query sequence sometime...\r
-          AlignFrame af = new AlignFrame(al);\r
-          af.addSortByOrderMenuItem(ServiceName + " Ordering",\r
-                                    msaorder);\r
-\r
-          Desktop.addInternalFrame(af, alTitle,\r
-                                   AlignFrame.NEW_WINDOW_WIDTH,\r
-                                   AlignFrame.NEW_WINDOW_HEIGHT);\r
-        }\r
-      }\r
-      catch (Exception ex)\r
-      {\r
-        ex.printStackTrace();\r
-      }\r
-    }\r
-  }\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.ws;
+
+import ext.vamsas.*;
+
+import jalview.analysis.AlignSeq;
+
+import jalview.datamodel.*;
+
+import jalview.gui.*;
+
+import java.util.*;
+
+import javax.swing.*;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class MsaWSClient
+    extends WSClient
+{
+  /**
+   * server is a WSDL2Java generated stub for an archetypal MsaWSI service.
+   */
+  ext.vamsas.MuscleWS server;
+  AlignFrame alignFrame;
+
+
+  /**
+   * Creates a new MsaWSClient object that uses a service
+   * given by an externally retrieved ServiceHandle
+   *
+   * @param sh service handle of type AbstractName(MsaWS)
+   * @param altitle DOCUMENT ME!
+   * @param msa DOCUMENT ME!
+   * @param submitGaps DOCUMENT ME!
+   * @param preserveOrder DOCUMENT ME!
+   */
+
+  public MsaWSClient(ext.vamsas.ServiceHandle sh, String altitle,
+                     jalview.datamodel.AlignmentView msa,
+                     boolean submitGaps, boolean preserveOrder,
+                     Alignment seqdataset,
+                     AlignFrame _alignFrame)
+  {
+    super();
+    alignFrame = _alignFrame;
+    if (!sh.getAbstractName().equals("MsaWS"))
+    {
+      JOptionPane.showMessageDialog(Desktop.desktop,
+                                    "The Service called \n" + sh.getName() +
+          "\nis not a \nMultiple Sequence Alignment Service !",
+                                    "Internal Jalview Error",
+                                    JOptionPane.WARNING_MESSAGE);
+
+      return;
+    }
+
+    if ((wsInfo = setWebService(sh))==null)
+     {
+       JOptionPane.showMessageDialog(Desktop.desktop,
+                                     "The Multiple Sequence Alignment Service named " +
+                                     sh.getName() +
+                                     " is unknown", "Internal Jalview Error",
+                                     JOptionPane.WARNING_MESSAGE);
+
+       return;
+     }
+    startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
+
+  }
+
+
+  private void startMsaWSClient(String altitle, AlignmentView msa,
+                     boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
+  {
+    if (!locateWebService())
+    {
+      return;
+    }
+
+    wsInfo.setProgressText( ( (submitGaps) ? "Re-alignment" : "Alignment") +
+                           " of " + altitle + "\nJob details\n");
+
+    MsaWSThread musclethread = new MsaWSThread(server, WsURL, wsInfo, alignFrame,
+                                               WebServiceName,
+                                               WebServiceName+" alignment of " + altitle,
+                                               msa,
+                                               submitGaps, preserveOrder, seqdataset);
+    wsInfo.setthisService(musclethread);
+    musclethread.start();
+  }
+
+  /**
+   * Initializes the server field with a valid service implementation.
+   *
+   * @return true if service was located.
+   */
+  private boolean locateWebService()
+  {
+    // TODO: MuscleWS transmuted to generic MsaWS client
+    MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default
+
+    try
+    {
+      this.server = (MuscleWS) loc.getMuscleWS(new java.net.URL(WsURL));
+      ( (MuscleWSSoapBindingStub)this.server).setTimeout(60000); // One minute timeout
+    }
+    catch (Exception ex)
+    {
+      wsInfo.setProgressText("Serious! " + WebServiceName +
+                             " Service location failed\nfor URL :" + WsURL +
+                             "\n" +
+                             ex.getMessage());
+      wsInfo.setStatus(WebserviceInfo.ERROR);
+      ex.printStackTrace();
+
+      return false;
+    }
+
+    loc.getEngine().setOption("axis", "1");
+
+    return true;
+  }
+
+  protected String getServiceActionKey()
+  {
+    return "MsaWS";
+  }
+
+  protected String getServiceActionDescription()
+  {
+    return "Multiple Sequence Alignment";
+  }
+}
index 02b513c..17f51c0 100755 (executable)
@@ -1,6 +1,6 @@
 /*
  * Jalview - A Sequence Alignment Editor and Viewer
 /*
  * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
index 97eaa7f..452072e 100755 (executable)
@@ -1,6 +1,6 @@
 /*
  * Jalview - A Sequence Alignment Editor and Viewer
 /*
  * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -20,7 +20,15 @@ package jalview.ws;
 
 public interface WSClientI
 {
 
 public interface WSClientI
 {
-  boolean isCancellable();
-
+    /**
+     *
+     * @return boolean true if job is cancellable
+     */
+    boolean isCancellable();
+    /**
+     *
+     * @return boolean true if results can be merged into the source of input data
+     */
+  boolean canMergeResults();
   void cancelJob();
 }
   void cancelJob();
 }
index ed31920..bd0fdbb 100755 (executable)
@@ -1,6 +1,6 @@
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
index 574a1e9..76229cc 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class Alignment extends vamsas.objects.simple.Object\r
-    implements java.io.Serializable {\r
-    private java.lang.String gapchar;\r
-    private java.lang.String[] method;\r
-    private vamsas.objects.simple.SequenceSet seqs;\r
-    private java.lang.Object __equalsCalc = null;\r
-    private boolean __hashCodeCalc = false;\r
-\r
-    public Alignment() {\r
-    }\r
-\r
-    public Alignment(java.lang.String gapchar, java.lang.String[] method,\r
-        vamsas.objects.simple.SequenceSet seqs) {\r
-        this.gapchar = gapchar;\r
-        this.method = method;\r
-        this.seqs = seqs;\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class Alignment extends vamsas.objects.simple.Object
+    implements java.io.Serializable {
+    private java.lang.String gapchar;
+    private java.lang.String[] method;
+    private vamsas.objects.simple.SequenceSet seqs;
+    private java.lang.Object __equalsCalc = null;
+    private boolean __hashCodeCalc = false;
+
+    public Alignment() {
+    }
+
+    public Alignment(java.lang.String gapchar, java.lang.String[] method,
+        vamsas.objects.simple.SequenceSet seqs) {
+        this.gapchar = gapchar;
+        this.method = method;
+        this.seqs = seqs;
+    }
+
     /**
  * Gets the gapchar value for this Alignment.
  *
  * @return gapchar
     /**
  * Gets the gapchar value for this Alignment.
  *
  * @return gapchar
- */\r
-    public java.lang.String getGapchar() {\r
-        return gapchar;\r
-    }\r
-\r
+ */
+    public java.lang.String getGapchar() {
+        return gapchar;
+    }
+
     /**
  * Sets the gapchar value for this Alignment.
  *
  * @param gapchar
     /**
  * Sets the gapchar value for this Alignment.
  *
  * @param gapchar
- */\r
-    public void setGapchar(java.lang.String gapchar) {\r
-        this.gapchar = gapchar;\r
-    }\r
-\r
+ */
+    public void setGapchar(java.lang.String gapchar) {
+        this.gapchar = gapchar;
+    }
+
     /**
  * Gets the method value for this Alignment.
  *
  * @return method
     /**
  * Gets the method value for this Alignment.
  *
  * @return method
- */\r
-    public java.lang.String[] getMethod() {\r
-        return method;\r
-    }\r
-\r
+ */
+    public java.lang.String[] getMethod() {
+        return method;
+    }
+
     /**
  * Sets the method value for this Alignment.
  *
  * @param method
     /**
  * Sets the method value for this Alignment.
  *
  * @param method
- */\r
-    public void setMethod(java.lang.String[] method) {\r
-        this.method = method;\r
-    }\r
-\r
+ */
+    public void setMethod(java.lang.String[] method) {
+        this.method = method;
+    }
+
     /**
  * Gets the seqs value for this Alignment.
  *
  * @return seqs
     /**
  * Gets the seqs value for this Alignment.
  *
  * @return seqs
- */\r
-    public vamsas.objects.simple.SequenceSet getSeqs() {\r
-        return seqs;\r
-    }\r
-\r
+ */
+    public vamsas.objects.simple.SequenceSet getSeqs() {
+        return seqs;
+    }
+
     /**
  * Sets the seqs value for this Alignment.
  *
  * @param seqs
     /**
  * Sets the seqs value for this Alignment.
  *
  * @param seqs
- */\r
-    public void setSeqs(vamsas.objects.simple.SequenceSet seqs) {\r
-        this.seqs = seqs;\r
-    }\r
-\r
-    public synchronized boolean equals(java.lang.Object obj) {\r
-        if (!(obj instanceof Alignment)) {\r
-            return false;\r
-        }\r
-\r
-        Alignment other = (Alignment) obj;\r
-\r
-        if (obj == null) {\r
-            return false;\r
-        }\r
-\r
-        if (this == obj) {\r
-            return true;\r
-        }\r
-\r
-        if (__equalsCalc != null) {\r
-            return (__equalsCalc == obj);\r
-        }\r
-\r
-        __equalsCalc = obj;\r
-\r
-        boolean _equals;\r
-        _equals = super.equals(obj) &&\r
-            (((this.gapchar == null) && (other.getGapchar() == null)) ||\r
-            ((this.gapchar != null) && this.gapchar.equals(other.getGapchar()))) &&\r
-            (((this.method == null) && (other.getMethod() == null)) ||\r
-            ((this.method != null) &&\r
-            java.util.Arrays.equals(this.method, other.getMethod()))) &&\r
-            (((this.seqs == null) && (other.getSeqs() == null)) ||\r
-            ((this.seqs != null) && this.seqs.equals(other.getSeqs())));\r
-        __equalsCalc = null;\r
-\r
-        return _equals;\r
-    }\r
-\r
-    public synchronized int hashCode() {\r
-        if (__hashCodeCalc) {\r
-            return 0;\r
-        }\r
-\r
-        __hashCodeCalc = true;\r
-\r
-        int _hashCode = super.hashCode();\r
-\r
-        if (getGapchar() != null) {\r
-            _hashCode += getGapchar().hashCode();\r
-        }\r
-\r
-        if (getMethod() != null) {\r
-            for (int i = 0; i < java.lang.reflect.Array.getLength(getMethod());\r
-                    i++) {\r
-                java.lang.Object obj = java.lang.reflect.Array.get(getMethod(),\r
-                        i);\r
-\r
-                if ((obj != null) && !obj.getClass().isArray()) {\r
-                    _hashCode += obj.hashCode();\r
-                }\r
-            }\r
-        }\r
-\r
-        if (getSeqs() != null) {\r
-            _hashCode += getSeqs().hashCode();\r
-        }\r
-\r
-        __hashCodeCalc = false;\r
-\r
-        return _hashCode;\r
-    }\r
-}\r
+ */
+    public void setSeqs(vamsas.objects.simple.SequenceSet seqs) {
+        this.seqs = seqs;
+    }
+
+    public synchronized boolean equals(java.lang.Object obj) {
+        if (!(obj instanceof Alignment)) {
+            return false;
+        }
+
+        Alignment other = (Alignment) obj;
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (__equalsCalc != null) {
+            return (__equalsCalc == obj);
+        }
+
+        __equalsCalc = obj;
+
+        boolean _equals;
+        _equals = super.equals(obj) &&
+            (((this.gapchar == null) && (other.getGapchar() == null)) ||
+            ((this.gapchar != null) && this.gapchar.equals(other.getGapchar()))) &&
+            (((this.method == null) && (other.getMethod() == null)) ||
+            ((this.method != null) &&
+            java.util.Arrays.equals(this.method, other.getMethod()))) &&
+            (((this.seqs == null) && (other.getSeqs() == null)) ||
+            ((this.seqs != null) && this.seqs.equals(other.getSeqs())));
+        __equalsCalc = null;
+
+        return _equals;
+    }
+
+    public synchronized int hashCode() {
+        if (__hashCodeCalc) {
+            return 0;
+        }
+
+        __hashCodeCalc = true;
+
+        int _hashCode = super.hashCode();
+
+        if (getGapchar() != null) {
+            _hashCode += getGapchar().hashCode();
+        }
+
+        if (getMethod() != null) {
+            for (int i = 0; i < java.lang.reflect.Array.getLength(getMethod());
+                    i++) {
+                java.lang.Object obj = java.lang.reflect.Array.get(getMethod(),
+                        i);
+
+                if ((obj != null) && !obj.getClass().isArray()) {
+                    _hashCode += obj.hashCode();
+                }
+            }
+        }
+
+        if (getSeqs() != null) {
+            _hashCode += getSeqs().hashCode();
+        }
+
+        __hashCodeCalc = false;
+
+        return _hashCode;
+    }
+}
index 3f57064..12c4846 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class Alignment_Helper {\r
-    // Type metadata\r
-    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(Alignment.class,\r
-            true);\r
-\r
-    static {\r
-        typeDesc.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "Alignment"));\r
-\r
-        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("gapchar");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "gapchar"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "http://schemas.xmlsoap.org/soap/encoding/", "string"));\r
-        typeDesc.addFieldDesc(elemField);\r
-        elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("method");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "method"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "http://schemas.xmlsoap.org/soap/encoding/", "string"));\r
-        typeDesc.addFieldDesc(elemField);\r
-        elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("seqs");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "seqs"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "SequenceSet"));\r
-        typeDesc.addFieldDesc(elemField);\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class Alignment_Helper {
+    // Type metadata
+    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(Alignment.class,
+            true);
+
+    static {
+        typeDesc.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "Alignment"));
+
+        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("gapchar");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "gapchar"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "http://schemas.xmlsoap.org/soap/encoding/", "string"));
+        typeDesc.addFieldDesc(elemField);
+        elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("method");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "method"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "http://schemas.xmlsoap.org/soap/encoding/", "string"));
+        typeDesc.addFieldDesc(elemField);
+        elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("seqs");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "seqs"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "SequenceSet"));
+        typeDesc.addFieldDesc(elemField);
+    }
+
     /**
  * Return type metadata object
     /**
  * Return type metadata object
- */\r
-    public static org.apache.axis.description.TypeDesc getTypeDesc() {\r
-        return typeDesc;\r
-    }\r
-\r
+ */
+    public static org.apache.axis.description.TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
     /**
  * Get Custom Serializer
     /**
  * Get Custom Serializer
- */\r
-    public static org.apache.axis.encoding.Serializer getSerializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-\r
+ */
+    public static org.apache.axis.encoding.Serializer getSerializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,
+            _xmlType, typeDesc);
+    }
+
     /**
  * Get Custom Deserializer
     /**
  * Get Custom Deserializer
- */\r
-    public static org.apache.axis.encoding.Deserializer getDeserializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-}\r
+ */
+    public static org.apache.axis.encoding.Deserializer getDeserializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,
+            _xmlType, typeDesc);
+    }
+}
index 43a8c6e..3dbb767 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class MsaResult extends vamsas.objects.simple.Result\r
-    implements java.io.Serializable {\r
-    private vamsas.objects.simple.Alignment msa;\r
-    private java.lang.Object __equalsCalc = null;\r
-    private boolean __hashCodeCalc = false;\r
-\r
-    public MsaResult() {\r
-    }\r
-\r
-    public MsaResult(vamsas.objects.simple.Alignment msa) {\r
-        this.msa = msa;\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class MsaResult extends vamsas.objects.simple.Result
+    implements java.io.Serializable {
+    private vamsas.objects.simple.Alignment msa;
+    private java.lang.Object __equalsCalc = null;
+    private boolean __hashCodeCalc = false;
+
+    public MsaResult() {
+    }
+
+    public MsaResult(vamsas.objects.simple.Alignment msa) {
+        this.msa = msa;
+    }
+
     /**
  * Gets the msa value for this MsaResult.
  *
  * @return msa
     /**
  * Gets the msa value for this MsaResult.
  *
  * @return msa
- */\r
-    public vamsas.objects.simple.Alignment getMsa() {\r
-        return msa;\r
-    }\r
-\r
+ */
+    public vamsas.objects.simple.Alignment getMsa() {
+        return msa;
+    }
+
     /**
  * Sets the msa value for this MsaResult.
  *
  * @param msa
     /**
  * Sets the msa value for this MsaResult.
  *
  * @param msa
- */\r
-    public void setMsa(vamsas.objects.simple.Alignment msa) {\r
-        this.msa = msa;\r
-    }\r
-\r
-    public synchronized boolean equals(java.lang.Object obj) {\r
-        if (!(obj instanceof MsaResult)) {\r
-            return false;\r
-        }\r
-\r
-        MsaResult other = (MsaResult) obj;\r
-\r
-        if (obj == null) {\r
-            return false;\r
-        }\r
-\r
-        if (this == obj) {\r
-            return true;\r
-        }\r
-\r
-        if (__equalsCalc != null) {\r
-            return (__equalsCalc == obj);\r
-        }\r
-\r
-        __equalsCalc = obj;\r
-\r
-        boolean _equals;\r
-        _equals = super.equals(obj) &&\r
-            (((this.msa == null) && (other.getMsa() == null)) ||\r
-            ((this.msa != null) && this.msa.equals(other.getMsa())));\r
-        __equalsCalc = null;\r
-\r
-        return _equals;\r
-    }\r
-\r
-    public synchronized int hashCode() {\r
-        if (__hashCodeCalc) {\r
-            return 0;\r
-        }\r
-\r
-        __hashCodeCalc = true;\r
-\r
-        int _hashCode = super.hashCode();\r
-\r
-        if (getMsa() != null) {\r
-            _hashCode += getMsa().hashCode();\r
-        }\r
-\r
-        __hashCodeCalc = false;\r
-\r
-        return _hashCode;\r
-    }\r
-}\r
+ */
+    public void setMsa(vamsas.objects.simple.Alignment msa) {
+        this.msa = msa;
+    }
+
+    public synchronized boolean equals(java.lang.Object obj) {
+        if (!(obj instanceof MsaResult)) {
+            return false;
+        }
+
+        MsaResult other = (MsaResult) obj;
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (__equalsCalc != null) {
+            return (__equalsCalc == obj);
+        }
+
+        __equalsCalc = obj;
+
+        boolean _equals;
+        _equals = super.equals(obj) &&
+            (((this.msa == null) && (other.getMsa() == null)) ||
+            ((this.msa != null) && this.msa.equals(other.getMsa())));
+        __equalsCalc = null;
+
+        return _equals;
+    }
+
+    public synchronized int hashCode() {
+        if (__hashCodeCalc) {
+            return 0;
+        }
+
+        __hashCodeCalc = true;
+
+        int _hashCode = super.hashCode();
+
+        if (getMsa() != null) {
+            _hashCode += getMsa().hashCode();
+        }
+
+        __hashCodeCalc = false;
+
+        return _hashCode;
+    }
+}
index 87db2d2..dc240b4 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class MsaResult_Helper {\r
-    // Type metadata\r
-    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(MsaResult.class,\r
-            true);\r
-\r
-    static {\r
-        typeDesc.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "MsaResult"));\r
-\r
-        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("msa");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "msa"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "Alignment"));\r
-        typeDesc.addFieldDesc(elemField);\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class MsaResult_Helper {
+    // Type metadata
+    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(MsaResult.class,
+            true);
+
+    static {
+        typeDesc.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "MsaResult"));
+
+        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("msa");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "msa"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "Alignment"));
+        typeDesc.addFieldDesc(elemField);
+    }
+
     /**
  * Return type metadata object
     /**
  * Return type metadata object
- */\r
-    public static org.apache.axis.description.TypeDesc getTypeDesc() {\r
-        return typeDesc;\r
-    }\r
-\r
+ */
+    public static org.apache.axis.description.TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
     /**
  * Get Custom Serializer
     /**
  * Get Custom Serializer
- */\r
-    public static org.apache.axis.encoding.Serializer getSerializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-\r
+ */
+    public static org.apache.axis.encoding.Serializer getSerializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,
+            _xmlType, typeDesc);
+    }
+
     /**
  * Get Custom Deserializer
     /**
  * Get Custom Deserializer
- */\r
-    public static org.apache.axis.encoding.Deserializer getDeserializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-}\r
+ */
+    public static org.apache.axis.encoding.Deserializer getDeserializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,
+            _xmlType, typeDesc);
+    }
+}
index ae1b515..5dbfc98 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public abstract class Object implements java.io.Serializable {\r
-    private java.lang.Object __equalsCalc = null;\r
-    private boolean __hashCodeCalc = false;\r
-\r
-    public Object() {\r
-    }\r
-\r
-    public synchronized boolean equals(java.lang.Object obj) {\r
-        if (!(obj instanceof Object)) {\r
-            return false;\r
-        }\r
-\r
-        Object other = (Object) obj;\r
-\r
-        if (obj == null) {\r
-            return false;\r
-        }\r
-\r
-        if (this == obj) {\r
-            return true;\r
-        }\r
-\r
-        if (__equalsCalc != null) {\r
-            return (__equalsCalc == obj);\r
-        }\r
-\r
-        __equalsCalc = obj;\r
-\r
-        boolean _equals;\r
-        _equals = true;\r
-        __equalsCalc = null;\r
-\r
-        return _equals;\r
-    }\r
-\r
-    public synchronized int hashCode() {\r
-        if (__hashCodeCalc) {\r
-            return 0;\r
-        }\r
-\r
-        __hashCodeCalc = true;\r
-\r
-        int _hashCode = 1;\r
-        __hashCodeCalc = false;\r
-\r
-        return _hashCode;\r
-    }\r
-}\r
+*/
+package vamsas.objects.simple;
+
+public abstract class Object implements java.io.Serializable {
+    private java.lang.Object __equalsCalc = null;
+    private boolean __hashCodeCalc = false;
+
+    public Object() {
+    }
+
+    public synchronized boolean equals(java.lang.Object obj) {
+        if (!(obj instanceof Object)) {
+            return false;
+        }
+
+        //Object other = (Object) obj;
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (__equalsCalc != null) {
+            return (__equalsCalc == obj);
+        }
+
+        __equalsCalc = obj;
+
+        boolean _equals;
+        _equals = true;
+        __equalsCalc = null;
+
+        return _equals;
+    }
+
+    public synchronized int hashCode() {
+        if (__hashCodeCalc) {
+            return 0;
+        }
+
+        __hashCodeCalc = true;
+
+        int _hashCode = 1;
+        __hashCodeCalc = false;
+
+        return _hashCode;
+    }
+}
index f31c945..533b59e 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class Object_Helper {\r
-    // Type metadata\r
-    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(Object.class,\r
-            true);\r
-\r
-    static {\r
-        typeDesc.setXmlType(new javax.xml.namespace.QName(\r
-                "http://simple.objects.vamsas", "Object"));\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class Object_Helper {
+    // Type metadata
+    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(Object.class,
+            true);
+
+    static {
+        typeDesc.setXmlType(new javax.xml.namespace.QName(
+                "http://simple.objects.vamsas", "Object"));
+    }
+
     /**
  * Return type metadata object
     /**
  * Return type metadata object
- */\r
-    public static org.apache.axis.description.TypeDesc getTypeDesc() {\r
-        return typeDesc;\r
-    }\r
-\r
+ */
+    public static org.apache.axis.description.TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
     /**
  * Get Custom Serializer
     /**
  * Get Custom Serializer
- */\r
-    public static org.apache.axis.encoding.Serializer getSerializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-\r
+ */
+    public static org.apache.axis.encoding.Serializer getSerializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,
+            _xmlType, typeDesc);
+    }
+
     /**
  * Get Custom Deserializer
     /**
  * Get Custom Deserializer
- */\r
-    public static org.apache.axis.encoding.Deserializer getDeserializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-}\r
+ */
+    public static org.apache.axis.encoding.Deserializer getDeserializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,
+            _xmlType, typeDesc);
+    }
+}
index afecdb9..1de01f9 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class SequenceSet implements java.io.Serializable {\r
-    private vamsas.objects.simple.Sequence[] seqs;\r
-    private java.lang.Object __equalsCalc = null;\r
-    private boolean __hashCodeCalc = false;\r
-\r
-    public SequenceSet() {\r
-    }\r
-\r
-    public SequenceSet(vamsas.objects.simple.Sequence[] seqs) {\r
-        this.seqs = seqs;\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class SequenceSet implements java.io.Serializable {
+    private vamsas.objects.simple.Sequence[] seqs;
+    private java.lang.Object __equalsCalc = null;
+    private boolean __hashCodeCalc = false;
+
+    public SequenceSet() {
+    }
+
+    public SequenceSet(vamsas.objects.simple.Sequence[] seqs) {
+        this.seqs = seqs;
+    }
+
     /**
  * Gets the seqs value for this SequenceSet.
  *
  * @return seqs
     /**
  * Gets the seqs value for this SequenceSet.
  *
  * @return seqs
- */\r
-    public vamsas.objects.simple.Sequence[] getSeqs() {\r
-        return seqs;\r
-    }\r
-\r
+ */
+    public vamsas.objects.simple.Sequence[] getSeqs() {
+        return seqs;
+    }
+
     /**
  * Sets the seqs value for this SequenceSet.
  *
  * @param seqs
     /**
  * Sets the seqs value for this SequenceSet.
  *
  * @param seqs
- */\r
-    public void setSeqs(vamsas.objects.simple.Sequence[] seqs) {\r
-        this.seqs = seqs;\r
-    }\r
-\r
-    public synchronized boolean equals(java.lang.Object obj) {\r
-        if (!(obj instanceof SequenceSet)) {\r
-            return false;\r
-        }\r
-\r
-        SequenceSet other = (SequenceSet) obj;\r
-\r
-        if (obj == null) {\r
-            return false;\r
-        }\r
-\r
-        if (this == obj) {\r
-            return true;\r
-        }\r
-\r
-        if (__equalsCalc != null) {\r
-            return (__equalsCalc == obj);\r
-        }\r
-\r
-        __equalsCalc = obj;\r
-\r
-        boolean _equals;\r
-        _equals = true &&\r
-            (((this.seqs == null) && (other.getSeqs() == null)) ||\r
-            ((this.seqs != null) &&\r
-            java.util.Arrays.equals(this.seqs, other.getSeqs())));\r
-        __equalsCalc = null;\r
-\r
-        return _equals;\r
-    }\r
-\r
-    public synchronized int hashCode() {\r
-        if (__hashCodeCalc) {\r
-            return 0;\r
-        }\r
-\r
-        __hashCodeCalc = true;\r
-\r
-        int _hashCode = 1;\r
-\r
-        if (getSeqs() != null) {\r
-            for (int i = 0; i < java.lang.reflect.Array.getLength(getSeqs());\r
-                    i++) {\r
-                java.lang.Object obj = java.lang.reflect.Array.get(getSeqs(), i);\r
-\r
-                if ((obj != null) && !obj.getClass().isArray()) {\r
-                    _hashCode += obj.hashCode();\r
-                }\r
-            }\r
-        }\r
-\r
-        __hashCodeCalc = false;\r
-\r
-        return _hashCode;\r
-    }\r
-}\r
+ */
+    public void setSeqs(vamsas.objects.simple.Sequence[] seqs) {
+        this.seqs = seqs;
+    }
+
+    public synchronized boolean equals(java.lang.Object obj) {
+        if (!(obj instanceof SequenceSet)) {
+            return false;
+        }
+
+        SequenceSet other = (SequenceSet) obj;
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (__equalsCalc != null) {
+            return (__equalsCalc == obj);
+        }
+
+        __equalsCalc = obj;
+
+        boolean _equals;
+        _equals = true &&
+            (((this.seqs == null) && (other.getSeqs() == null)) ||
+            ((this.seqs != null) &&
+            java.util.Arrays.equals(this.seqs, other.getSeqs())));
+        __equalsCalc = null;
+
+        return _equals;
+    }
+
+    public synchronized int hashCode() {
+        if (__hashCodeCalc) {
+            return 0;
+        }
+
+        __hashCodeCalc = true;
+
+        int _hashCode = 1;
+
+        if (getSeqs() != null) {
+            for (int i = 0; i < java.lang.reflect.Array.getLength(getSeqs());
+                    i++) {
+                java.lang.Object obj = java.lang.reflect.Array.get(getSeqs(), i);
+
+                if ((obj != null) && !obj.getClass().isArray()) {
+                    _hashCode += obj.hashCode();
+                }
+            }
+        }
+
+        __hashCodeCalc = false;
+
+        return _hashCode;
+    }
+}
index ec56cb2..632cbca 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class SequenceSet_Helper {\r
-    // Type metadata\r
-    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(SequenceSet.class,\r
-            true);\r
-\r
-    static {\r
-        typeDesc.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "SequenceSet"));\r
-\r
-        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("seqs");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "seqs"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "Sequence"));\r
-        typeDesc.addFieldDesc(elemField);\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class SequenceSet_Helper {
+    // Type metadata
+    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(SequenceSet.class,
+            true);
+
+    static {
+        typeDesc.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "SequenceSet"));
+
+        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("seqs");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "seqs"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "Sequence"));
+        typeDesc.addFieldDesc(elemField);
+    }
+
     /**
  * Return type metadata object
     /**
  * Return type metadata object
- */\r
-    public static org.apache.axis.description.TypeDesc getTypeDesc() {\r
-        return typeDesc;\r
-    }\r
-\r
+ */
+    public static org.apache.axis.description.TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
     /**
  * Get Custom Serializer
     /**
  * Get Custom Serializer
- */\r
-    public static org.apache.axis.encoding.Serializer getSerializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-\r
+ */
+    public static org.apache.axis.encoding.Serializer getSerializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,
+            _xmlType, typeDesc);
+    }
+
     /**
  * Get Custom Deserializer
     /**
  * Get Custom Deserializer
- */\r
-    public static org.apache.axis.encoding.Deserializer getDeserializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-}\r
+ */
+    public static org.apache.axis.encoding.Deserializer getDeserializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,
+            _xmlType, typeDesc);
+    }
+}
index fb882db..1c3ab01 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class WsJobId implements java.io.Serializable {\r
-    private java.lang.String jobId;\r
-    private int status;\r
-    private java.lang.Object __equalsCalc = null;\r
-    private boolean __hashCodeCalc = false;\r
-\r
-    public WsJobId() {\r
-    }\r
-\r
-    public WsJobId(java.lang.String jobId, int status) {\r
-        this.jobId = jobId;\r
-        this.status = status;\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class WsJobId implements java.io.Serializable {
+    private java.lang.String jobId;
+    private int status;
+    private java.lang.Object __equalsCalc = null;
+    private boolean __hashCodeCalc = false;
+
+    public WsJobId() {
+    }
+
+    public WsJobId(java.lang.String jobId, int status) {
+        this.jobId = jobId;
+        this.status = status;
+    }
+
     /**
  * Gets the jobId value for this WsJobId.
  *
  * @return jobId
     /**
  * Gets the jobId value for this WsJobId.
  *
  * @return jobId
- */\r
-    public java.lang.String getJobId() {\r
-        return jobId;\r
-    }\r
-\r
+ */
+    public java.lang.String getJobId() {
+        return jobId;
+    }
+
     /**
  * Sets the jobId value for this WsJobId.
  *
  * @param jobId
     /**
  * Sets the jobId value for this WsJobId.
  *
  * @param jobId
- */\r
-    public void setJobId(java.lang.String jobId) {\r
-        this.jobId = jobId;\r
-    }\r
-\r
+ */
+    public void setJobId(java.lang.String jobId) {
+        this.jobId = jobId;
+    }
+
     /**
  * Gets the status value for this WsJobId.
  *
  * @return status
     /**
  * Gets the status value for this WsJobId.
  *
  * @return status
- */\r
-    public int getStatus() {\r
-        return status;\r
-    }\r
-\r
+ */
+    public int getStatus() {
+        return status;
+    }
+
     /**
  * Sets the status value for this WsJobId.
  *
  * @param status
     /**
  * Sets the status value for this WsJobId.
  *
  * @param status
- */\r
-    public void setStatus(int status) {\r
-        this.status = status;\r
-    }\r
-\r
-    public synchronized boolean equals(java.lang.Object obj) {\r
-        if (!(obj instanceof WsJobId)) {\r
-            return false;\r
-        }\r
-\r
-        WsJobId other = (WsJobId) obj;\r
-\r
-        if (obj == null) {\r
-            return false;\r
-        }\r
-\r
-        if (this == obj) {\r
-            return true;\r
-        }\r
-\r
-        if (__equalsCalc != null) {\r
-            return (__equalsCalc == obj);\r
-        }\r
-\r
-        __equalsCalc = obj;\r
-\r
-        boolean _equals;\r
-        _equals = true &&\r
-            (((this.jobId == null) && (other.getJobId() == null)) ||\r
-            ((this.jobId != null) && this.jobId.equals(other.getJobId()))) &&\r
-            (this.status == other.getStatus());\r
-        __equalsCalc = null;\r
-\r
-        return _equals;\r
-    }\r
-\r
-    public synchronized int hashCode() {\r
-        if (__hashCodeCalc) {\r
-            return 0;\r
-        }\r
-\r
-        __hashCodeCalc = true;\r
-\r
-        int _hashCode = 1;\r
-\r
-        if (getJobId() != null) {\r
-            _hashCode += getJobId().hashCode();\r
-        }\r
-\r
-        _hashCode += getStatus();\r
-        __hashCodeCalc = false;\r
-\r
-        return _hashCode;\r
-    }\r
-}\r
+ */
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public synchronized boolean equals(java.lang.Object obj) {
+        if (!(obj instanceof WsJobId)) {
+            return false;
+        }
+
+        WsJobId other = (WsJobId) obj;
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (__equalsCalc != null) {
+            return (__equalsCalc == obj);
+        }
+
+        __equalsCalc = obj;
+
+        boolean _equals;
+        _equals = true &&
+            (((this.jobId == null) && (other.getJobId() == null)) ||
+            ((this.jobId != null) && this.jobId.equals(other.getJobId()))) &&
+            (this.status == other.getStatus());
+        __equalsCalc = null;
+
+        return _equals;
+    }
+
+    public synchronized int hashCode() {
+        if (__hashCodeCalc) {
+            return 0;
+        }
+
+        __hashCodeCalc = true;
+
+        int _hashCode = 1;
+
+        if (getJobId() != null) {
+            _hashCode += getJobId().hashCode();
+        }
+
+        _hashCode += getStatus();
+        __hashCodeCalc = false;
+
+        return _hashCode;
+    }
+}
index 75418c4..d2a2483 100755 (executable)
@@ -3,11 +3,11 @@
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
  *
  * This file was auto-generated from WSDL
  * by the Apache Axis 1.2RC2 Nov 16, 2004 (12:19:44 EST) WSDL2Java emitter.
- */\r
-\r
+ */
+
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
 /*
 * Jalview - A Sequence Alignment Editor and Viewer
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-*/\r
-package vamsas.objects.simple;\r
-\r
-public class WsJobId_Helper {\r
-    // Type metadata\r
-    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(WsJobId.class,\r
-            true);\r
-\r
-    static {\r
-        typeDesc.setXmlType(new javax.xml.namespace.QName(\r
-                "simple.objects.vamsas", "WsJobId"));\r
-\r
-        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("jobId");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "jobId"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "http://schemas.xmlsoap.org/soap/encoding/", "string"));\r
-        typeDesc.addFieldDesc(elemField);\r
-        elemField = new org.apache.axis.description.ElementDesc();\r
-        elemField.setFieldName("status");\r
-        elemField.setXmlName(new javax.xml.namespace.QName("", "status"));\r
-        elemField.setXmlType(new javax.xml.namespace.QName(\r
-                "http://www.w3.org/2001/XMLSchema", "int"));\r
-        typeDesc.addFieldDesc(elemField);\r
-    }\r
-\r
+*/
+package vamsas.objects.simple;
+
+public class WsJobId_Helper {
+    // Type metadata
+    private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(WsJobId.class,
+            true);
+
+    static {
+        typeDesc.setXmlType(new javax.xml.namespace.QName(
+                "simple.objects.vamsas", "WsJobId"));
+
+        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("jobId");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "jobId"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "http://schemas.xmlsoap.org/soap/encoding/", "string"));
+        typeDesc.addFieldDesc(elemField);
+        elemField = new org.apache.axis.description.ElementDesc();
+        elemField.setFieldName("status");
+        elemField.setXmlName(new javax.xml.namespace.QName("", "status"));
+        elemField.setXmlType(new javax.xml.namespace.QName(
+                "http://www.w3.org/2001/XMLSchema", "int"));
+        typeDesc.addFieldDesc(elemField);
+    }
+
     /**
  * Return type metadata object
     /**
  * Return type metadata object
- */\r
-    public static org.apache.axis.description.TypeDesc getTypeDesc() {\r
-        return typeDesc;\r
-    }\r
-\r
+ */
+    public static org.apache.axis.description.TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
     /**
  * Get Custom Serializer
     /**
  * Get Custom Serializer
- */\r
-    public static org.apache.axis.encoding.Serializer getSerializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-\r
+ */
+    public static org.apache.axis.encoding.Serializer getSerializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanSerializer(_javaType,
+            _xmlType, typeDesc);
+    }
+
     /**
  * Get Custom Deserializer
     /**
  * Get Custom Deserializer
- */\r
-    public static org.apache.axis.encoding.Deserializer getDeserializer(\r
-        java.lang.String mechType, java.lang.Class _javaType,\r
-        javax.xml.namespace.QName _xmlType) {\r
-        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,\r
-            _xmlType, typeDesc);\r
-    }\r
-}\r
+ */
+    public static org.apache.axis.encoding.Deserializer getDeserializer(
+        java.lang.String mechType, java.lang.Class _javaType,
+        javax.xml.namespace.QName _xmlType) {
+        return new org.apache.axis.encoding.ser.BeanDeserializer(_javaType,
+            _xmlType, typeDesc);
+    }
+}