header updated
[jalview.git] / src / jalview / gui / AlignViewport.java
index 44330fa..dd01647 100755 (executable)
@@ -1,6 +1,6 @@
  /*\r
  * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * Copyright (C) 2006 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
@@ -61,8 +61,9 @@ public class AlignViewport
     SequenceGroup selectionGroup;\r
     int charHeight;\r
     int charWidth;\r
+    boolean validCharWidth;\r
     int wrappedWidth;\r
-    Font font = new Font("SansSerif", Font.PLAIN, 10);\r
+    Font font;\r
     AlignmentI alignment;\r
     ColumnSelection colSel = new ColumnSelection();\r
     int threshold;\r
@@ -71,12 +72,23 @@ public class AlignViewport
     boolean scaleAboveWrapped = false;\r
     boolean scaleLeftWrapped = true;\r
     boolean scaleRightWrapped = true;\r
+    boolean hasHiddenColumns = false;\r
+    boolean hasHiddenRows = false;\r
+    boolean showHiddenMarkers = true;\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
+    boolean autoCalculateConsensus = true;\r
 \r
     /** DOCUMENT ME!! */\r
     public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
@@ -88,6 +100,10 @@ public class AlignViewport
 \r
     boolean isDataset = false;\r
 \r
+    boolean antiAlias = false;\r
+\r
+    boolean padGaps = false;\r
+\r
 \r
     public AlignViewport(AlignmentI al, boolean dataset)\r
     {\r
@@ -105,6 +121,20 @@ public class AlignViewport
         setAlignment(al);\r
         init();\r
     }\r
+    /**\r
+     * Create a new AlignViewport with hidden regions\r
+     * @param al AlignmentI\r
+     * @param hiddenColumns ColumnSelection\r
+     */\r
+    public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) {\r
+      setAlignment(al);\r
+      if (hiddenColumns!=null) {\r
+        this.colSel = hiddenColumns;\r
+        if (hiddenColumns.getHiddenColumns() != null)\r
+          hasHiddenColumns = true;\r
+      }\r
+      init();\r
+    }\r
 \r
     void init()\r
     {\r
@@ -113,6 +143,8 @@ public class AlignViewport
         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
@@ -120,6 +152,10 @@ public class AlignViewport
       showQuality = Cache.getDefault("SHOW_QUALITY", true);\r
       showIdentity = Cache.getDefault("SHOW_IDENTITY", true);\r
 \r
+      autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);\r
+\r
+      padGaps = Cache.getDefault("PAD_GAPS", false);\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
@@ -174,11 +210,16 @@ public class AlignViewport
      *\r
      * @param b DOCUMENT ME!\r
      */\r
-    public void showSequenceFeatures(boolean b)\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
@@ -292,12 +333,19 @@ public class AlignViewport
       }\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
+        javax.swing.SwingUtilities.invokeLater(new Runnable()\r
+        {\r
+          public void run()\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
+          }\r
+        });\r
+\r
         System.out.println("Conservation calculation: " + error);\r
         System.gc();\r
 \r
@@ -377,12 +425,20 @@ public class AlignViewport
 \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
+        javax.swing.SwingUtilities.invokeLater(new Runnable()\r
+        {\r
+          public void run()\r
+          {\r
+            javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
+                "Out of memory calc45ulating consensus!!"\r
+                +\r
+                "\nSee help files for increasing Java Virtual Machine memory."\r
+                , "Out of memory",\r
+                javax.swing.JOptionPane.WARNING_MESSAGE);\r
+          }\r
+        });\r
+\r
+\r
         System.out.println("Consensus calculation: " + error);\r
         System.gc();\r
       }\r
@@ -584,6 +640,7 @@ public class AlignViewport
         java.awt.FontMetrics fm = c.getFontMetrics(font);\r
         setCharHeight(fm.getHeight());\r
         setCharWidth(fm.charWidth('M'));\r
+        validCharWidth = true;\r
     }\r
 \r
     /**\r
@@ -830,41 +887,6 @@ public class AlignViewport
         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
@@ -1060,7 +1082,6 @@ public class AlignViewport
       {\r
         globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation);\r
       }\r
-\r
     }\r
 \r
     public boolean getIgnoreGapsConsensus()\r
@@ -1077,4 +1098,334 @@ public class AlignViewport
     {\r
       return isDataset;\r
     }\r
+\r
+\r
+    public void hideSelectedColumns()\r
+    {\r
+      if (colSel.size() < 1)\r
+        return;\r
+\r
+      colSel.hideSelectedColumns();\r
+      setSelectionGroup(null);\r
+\r
+      hasHiddenColumns = true;\r
+    }\r
+\r
+\r
+    public void hideColumns(int start, int end)\r
+    {\r
+      if(start==end)\r
+        colSel.hideColumns(start);\r
+      else\r
+        colSel.hideColumns(start, end);\r
+\r
+      hasHiddenColumns = true;\r
+    }\r
+\r
+    public void hideAllSelectedSeqs()\r
+    {\r
+      if (selectionGroup == null)\r
+        return;\r
+\r
+      SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);\r
+\r
+      for (int i = 0; i < seqs.length; i++)\r
+      {\r
+        alignment.getHiddenSequences().hideSequence(seqs[i]);\r
+      }\r
+      firePropertyChange("alignment", null, alignment.getSequences());\r
+      hasHiddenRows = true;\r
+      setSelectionGroup(null);\r
+    }\r
+\r
+    public void hideSequence(SequenceI seq)\r
+    {\r
+      if(seq!=null)\r
+      {\r
+        alignment.getHiddenSequences().hideSequence(seq);\r
+        hasHiddenRows = true;\r
+        firePropertyChange("alignment", null, alignment.getSequences());\r
+      }\r
+    }\r
+\r
+    public void showSequence(int index)\r
+    {\r
+      Vector tmp = alignment.getHiddenSequences().showSequence(index);\r
+      if(tmp.size()>0)\r
+      {\r
+        if(selectionGroup==null)\r
+        {\r
+          selectionGroup = new SequenceGroup();\r
+          selectionGroup.setEndRes(alignment.getWidth()-1);\r
+        }\r
+\r
+        for (int t = 0; t < tmp.size(); t++)\r
+        {\r
+          selectionGroup.addSequence(\r
+              (SequenceI) tmp.elementAt(t), false\r
+              );\r
+        }\r
+        firePropertyChange("alignment", null, alignment.getSequences());\r
+      }\r
+\r
+      if(alignment.getHiddenSequences().getSize()<1)\r
+        hasHiddenRows = false;\r
+    }\r
+\r
+    public void showColumn(int col)\r
+    {\r
+      colSel.revealHiddenColumns(col);\r
+      if(colSel.getHiddenColumns()==null)\r
+        hasHiddenColumns = false;\r
+    }\r
+\r
+    public void showAllHiddenColumns()\r
+    {\r
+      colSel.revealAllHiddenColumns();\r
+      hasHiddenColumns = false;\r
+    }\r
+\r
+    public void showAllHiddenSeqs()\r
+    {\r
+      if(alignment.getHiddenSequences().getSize()>0)\r
+      {\r
+        if(selectionGroup==null)\r
+        {\r
+          selectionGroup = new SequenceGroup();\r
+          selectionGroup.setEndRes(alignment.getWidth()-1);\r
+        }\r
+        Vector tmp = alignment.getHiddenSequences().showAll();\r
+        for(int t=0; t<tmp.size(); t++)\r
+        {\r
+          selectionGroup.addSequence(\r
+              (SequenceI)tmp.elementAt(t), false\r
+              );\r
+        }\r
+        firePropertyChange("alignment", null, alignment.getSequences());\r
+        hasHiddenRows = false;\r
+      }\r
+    }\r
+\r
+    public void invertColumnSelection()\r
+    {\r
+      int column;\r
+      for(int i=0; i<alignment.getWidth(); i++)\r
+      {\r
+        column = i;\r
+\r
+        if(colSel.contains(column))\r
+          colSel.removeElement(column);\r
+        else\r
+          colSel.addElement(column);\r
+\r
+      }\r
+\r
+    }\r
+\r
+    public int adjustForHiddenSeqs(int alignmentIndex)\r
+    {\r
+      return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);\r
+    }\r
+\r
+    /**\r
+     * This method returns the a new SequenceI [] with\r
+     * the selection sequence and start and end points adjusted\r
+     * @return String[]\r
+     */\r
+    public SequenceI[] getSelectionAsNewSequence()\r
+    {\r
+      SequenceI[] sequences;\r
+\r
+      if (selectionGroup == null)\r
+        sequences = alignment.getSequencesArray();\r
+      else\r
+        sequences = selectionGroup.getSelectionAsNewSequences(alignment);\r
+\r
+      return sequences;\r
+    }\r
+\r
+    /**\r
+     * This method returns the visible alignment as text, as\r
+     * seen on the GUI, ie if columns are hidden they will not\r
+     * be returned in the result.\r
+     * Use this for calculating trees, PCA, redundancy etc on views\r
+     * which contain hidden columns.\r
+     * @return String[]\r
+     */\r
+    public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)\r
+    {\r
+      CigarArray selection=null;\r
+      SequenceI [] seqs= null;\r
+      int i, iSize;\r
+      int start = 0, end = 0;\r
+      if(selectedRegionOnly && selectionGroup!=null)\r
+      {\r
+        iSize = selectionGroup.getSize(false);\r
+        seqs = selectionGroup.getSequencesInOrder(alignment);\r
+        start = selectionGroup.getStartRes();\r
+        end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor\r
+      }\r
+      else\r
+      {\r
+        iSize = alignment.getHeight();\r
+        seqs = alignment.getSequencesArray();\r
+        end = alignment.getWidth()-1;\r
+      }\r
+      SeqCigar[] selseqs = new SeqCigar[iSize];\r
+      for(i=0; i<iSize; i++)\r
+      {\r
+        selseqs[i] = new SeqCigar(seqs[i], start, end);\r
+      }\r
+      selection=new CigarArray(selseqs);\r
+      // now construct the CigarArray operations\r
+      if (hasHiddenColumns) {\r
+        Vector regions = colSel.getHiddenColumns();\r
+        int [] region;\r
+        int hideStart, hideEnd;\r
+        int last=start;\r
+        for (int j = 0; last<end & j < regions.size(); j++)\r
+        {\r
+          region = (int[]) regions.elementAt(j);\r
+          hideStart = region[0];\r
+          hideEnd = region[1];\r
+          // edit hidden regions to selection range\r
+          if(hideStart<last) {\r
+            if (hideEnd > last)\r
+            {\r
+              hideStart = last;\r
+            } else\r
+              continue;\r
+          }\r
+\r
+          if (hideStart>end)\r
+            break;\r
+\r
+          if (hideEnd>end)\r
+            hideEnd=end;\r
+\r
+          if (hideStart>hideEnd)\r
+            break;\r
+          /**\r
+           * form operations...\r
+           */\r
+          if (last<hideStart)\r
+            selection.addOperation(CigarArray.M, hideStart-last);\r
+          selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);\r
+          last = hideEnd+1;\r
+        }\r
+        // Final match if necessary.\r
+        if (last<end)\r
+          selection.addOperation(CigarArray.M, end-last);\r
+      } else {\r
+        selection.addOperation(CigarArray.M, end-start);\r
+      }\r
+      return selection;\r
+    }\r
+    /**\r
+     * return a compact representation of the current alignment selection to\r
+     * pass to an analysis function\r
+     * @param selectedOnly boolean true to just return the selected view\r
+     * @return AlignmentView\r
+     */\r
+    jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {\r
+      // JBPNote:\r
+      // this is here because the AlignmentView constructor modifies the CigarArray\r
+      // object. Refactoring of Cigar and alignment view representation should\r
+      // be done to remove redundancy.\r
+      CigarArray aligview = getViewAsCigars(selectedOnly);\r
+      if (aligview!=null)\r
+        return new AlignmentView(aligview);\r
+      return null;\r
+    }\r
+    /**\r
+     * This method returns the visible alignment as text, as\r
+     * seen on the GUI, ie if columns are hidden they will not\r
+     * be returned in the result.\r
+     * Use this for calculating trees, PCA, redundancy etc on views\r
+     * which contain hidden columns.\r
+     * @return String[]\r
+     */\r
+    public String [] getViewAsString(boolean selectedRegionOnly)\r
+    {\r
+      String [] selection = null;\r
+      SequenceI [] seqs= null;\r
+      int i, iSize;\r
+      int start = 0, end = 0;\r
+      if(selectedRegionOnly && selectionGroup!=null)\r
+      {\r
+        iSize = selectionGroup.getSize(false);\r
+        seqs = selectionGroup.getSequencesInOrder(alignment);\r
+        start = selectionGroup.getStartRes();\r
+        end = selectionGroup.getEndRes()+1;\r
+      }\r
+      else\r
+      {\r
+        iSize = alignment.getHeight();\r
+        seqs = alignment.getSequencesArray();\r
+        end = alignment.getWidth();\r
+      }\r
+\r
+      selection = new String[iSize];\r
+\r
+\r
+      for(i=0; i<iSize; i++)\r
+      {\r
+        if (hasHiddenColumns)\r
+        {\r
+             StringBuffer visibleSeq = new StringBuffer();\r
+             Vector regions = colSel.getHiddenColumns();\r
+\r
+             int blockStart = start, blockEnd=end;\r
+             int [] region;\r
+             int hideStart, hideEnd;\r
+\r
+             for (int j = 0; j < regions.size(); j++)\r
+             {\r
+               region = (int[]) regions.elementAt(j);\r
+               hideStart = region[0];\r
+               hideEnd = region[1];\r
+\r
+               if(hideStart < start)\r
+               {\r
+                 continue;\r
+               }\r
+\r
+               blockStart = Math.min(blockStart, hideEnd+1);\r
+               blockEnd = Math.min(blockEnd, hideStart);\r
+\r
+               if(blockStart>blockEnd)\r
+               {\r
+                  break;\r
+               }\r
+\r
+\r
+               visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));\r
+\r
+               blockStart = hideEnd+1;\r
+               blockEnd = end;\r
+             }\r
+\r
+             if(end>blockStart)\r
+               visibleSeq.append(seqs[i].getSequence(blockStart, end));\r
+\r
+             selection[i] = visibleSeq.toString();\r
+        }\r
+        else\r
+        {\r
+          selection[i] = seqs[i].getSequence(start, end);\r
+        }\r
+      }\r
+\r
+      return selection;\r
+    }\r
+\r
+    public boolean getShowHiddenMarkers()\r
+    {\r
+      return showHiddenMarkers;\r
+    }\r
+\r
+    public void setShowHiddenMarkers(boolean show)\r
+    {\r
+      showHiddenMarkers = show;\r
+    }\r
 }\r