H key updates
[jalview.git] / src / jalview / gui / AlignmentPanel.java
index af24c9f..a4a38f9 100755 (executable)
@@ -81,9 +81,7 @@ public class AlignmentPanel extends GAlignmentPanel
     annotationPanel = new AnnotationPanel(this);\r
     alabels = new AnnotationLabels(this);\r
 \r
-    annotationSpaceFillerHolder.setPreferredSize(annotationPanel.\r
-                                                 getPreferredSize());\r
-    annotationScroller.setPreferredSize(annotationPanel.getPreferredSize());\r
+\r
     annotationScroller.setViewportView(annotationPanel);\r
     annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
 \r
@@ -94,11 +92,8 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
     setScrollValues(0, 0);\r
 \r
-    annotationPanel.adjustPanelHeight();\r
-    annotationSpaceFillerHolder.setPreferredSize(annotationPanel.\r
-                                                 getPreferredSize());\r
-    annotationScroller.setPreferredSize(annotationPanel.\r
-                                        getPreferredSize());\r
+    adjustAnnotationHeight();\r
+\r
     setAnnotationVisible(av.getShowAnnotation());\r
 \r
     hscroll.addAdjustmentListener(this);\r
@@ -108,35 +103,171 @@ public class AlignmentPanel extends GAlignmentPanel
     {\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
+            alignFrame.deselectAllSequenceMenuItem_actionPerformed(null);\r
 \r
             break;\r
 \r
           case KeyEvent.VK_DOWN:\r
-            alignFrame.moveSelectedSequences(false);\r
-\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
-            alignFrame.moveSelectedSequences(true);\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() || evt.isShiftDown());\r
+            }\r
             break;\r
 \r
-          case KeyEvent.VK_BACK_SPACE:\r
           case KeyEvent.VK_DELETE:\r
-            alignFrame.cut_actionPerformed(null);\r
+          case KeyEvent.VK_BACK_SPACE:\r
+            if(!av.cursorMode)\r
+            {\r
+              alignFrame.cut_actionPerformed(null);\r
+            }\r
+            else\r
+              seqPanel.deleteGapAtCursor(evt.isControlDown() || evt.isShiftDown());\r
+\r
             break;\r
 \r
+          case KeyEvent.VK_S:\r
+            if(av.cursorMode)\r
+            {\r
+              seqPanel.setCursorRow();\r
+            }\r
+            break;\r
+          case KeyEvent.VK_C:\r
+            if(av.cursorMode && !evt.isControlDown())\r
+            {\r
+              seqPanel.setCursorColumn();\r
+            }\r
+            break;\r
           case KeyEvent.VK_P:\r
-            seqPanel.seqCanvas.increaseAARatio();\r
+            if(av.cursorMode)\r
+            {\r
+              seqPanel.setCursorPosition();\r
+            }\r
+            break;\r
+\r
+          case KeyEvent.VK_ENTER:\r
+          case KeyEvent.VK_COMMA:\r
+            if(av.cursorMode)\r
+            {\r
+              seqPanel.setCursorRowAndColumn();\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
-          case KeyEvent.VK_L:\r
-            seqPanel.seqCanvas.decreaseAARation();\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
+          case KeyEvent.VK_H:\r
+          {\r
+            boolean toggleSeqs = !evt.isControlDown();\r
+            boolean toggleCols = !evt.isShiftDown();\r
+\r
+            boolean hide = false;\r
+\r
+            SequenceGroup sg = av.getSelectionGroup();\r
+            if(toggleSeqs)\r
+             {\r
+               if(sg != null && sg.getSize(false) != av.alignment.getHeight())\r
+               {\r
+                 alignFrame.hideSelSequences_actionPerformed(null);\r
+                 hide = true;\r
+               }\r
+               else if (!(toggleCols && av.colSel.getSelected().size() > 0))\r
+                 alignFrame.showAllSeqs_actionPerformed(null);\r
+             }\r
+\r
+             if (toggleCols)\r
+             {\r
+               if(av.colSel.getSelected().size() > 0)\r
+               {\r
+                 alignFrame.hideSelColumns_actionPerformed(null);\r
+                 if(!toggleSeqs)\r
+                   av.selectionGroup = sg;\r
+               }\r
+               else if(!hide)\r
+                 alignFrame.showAllColumns_actionPerformed(null);\r
+             }\r
             break;\r
+          }\r
+\r
         }\r
       }\r
     });\r
@@ -242,26 +373,43 @@ public class AlignmentPanel extends GAlignmentPanel
    *\r
    * @param results DOCUMENT ME!\r
    */\r
-  public void highlightSearchResults(int[] results)\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 = av.alignment.getSequenceAt(results[0]);\r
-      int start = seq.findIndex(results[1]) - 1;\r
-      int end = seq.findIndex(results[2]) - 1;\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.getStartRes() > start) || (av.getEndRes() < end) ||\r
-          ( (av.getStartSeq() > results[0]) ||\r
-           (av.getEndSeq() < results[0])))\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
-        setScrollValues(start, results[0]);\r
+        scrollToWrappedVisible(start);\r
       }\r
     }\r
   }\r
 \r
+  void scrollToWrappedVisible(int res)\r
+  {\r
+    int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
+    if( res<=av.getStartRes() || res>=(av.getStartRes()+cwidth) )\r
+    {\r
+      vscroll.setValue(res / cwidth);\r
+      av.startRes = vscroll.getValue() * cwidth;\r
+    }\r
+  }\r
+\r
   /**\r
    * DOCUMENT ME!\r
    *\r
@@ -297,6 +445,37 @@ public class AlignmentPanel extends GAlignmentPanel
     repaint();\r
   }\r
 \r
+  public void adjustAnnotationHeight()\r
+  {\r
+    javax.swing.SwingUtilities.invokeLater(new Runnable()\r
+    {\r
+      public void run()\r
+      {\r
+          while(alignFrame.getHeight()==0)\r
+          {\r
+            Thread.yield();\r
+          }\r
+\r
+        int height = annotationPanel.adjustPanelHeight();\r
+\r
+        if (height > alignFrame.getHeight() / 2)\r
+        {\r
+          height = alignFrame.getHeight() / 2;\r
+        }\r
+\r
+        annotationScroller.setPreferredSize(\r
+            new Dimension(annotationScroller.getWidth(),\r
+                          height));\r
+\r
+        annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
+            annotationSpaceFillerHolder.getWidth(),\r
+            height));\r
+\r
+        annotationPanel.repaint();\r
+      }\r
+    });\r
+  }\r
+\r
   /**\r
    * DOCUMENT ME!\r
    *\r
@@ -363,7 +542,7 @@ public class AlignmentPanel extends GAlignmentPanel
    */\r
   public boolean scrollRight(boolean right)\r
   {\r
-    if (right)\r
+    if (!right)\r
     {\r
       if (hscroll.getValue() < 1)\r
       {\r
@@ -397,30 +576,36 @@ public class AlignmentPanel extends GAlignmentPanel
    */\r
   public void setScrollValues(int x, int y)\r
   {\r
-    av.setEndRes( (x + (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) -\r
-                 1);\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 > av.alignment.getWidth())\r
+    if (hextent > width)\r
     {\r
-      hextent = av.alignment.getWidth();\r
+      hextent = width;\r
     }\r
 \r
-    if (vextent > av.alignment.getHeight())\r
+    if (vextent > height)\r
     {\r
-      vextent = av.alignment.getHeight();\r
+      vextent = height;\r
     }\r
 \r
-    if ( (hextent + x) > av.getAlignment().getWidth())\r
+    if ( (hextent + x) > width)\r
     {\r
-      x = av.getAlignment().getWidth() - hextent;\r
+      x = width - hextent;\r
     }\r
 \r
-    if ( (vextent + y) > av.getAlignment().getHeight())\r
+    if ( (vextent + y) > height)\r
     {\r
-      y = av.getAlignment().getHeight() - vextent;\r
+      y = height - vextent;\r
     }\r
 \r
     if (y < 0)\r
@@ -433,8 +618,8 @@ public class AlignmentPanel extends GAlignmentPanel
       x = 0;\r
     }\r
 \r
-    hscroll.setValues(x, hextent, 0, av.getAlignment().getWidth());\r
-    vscroll.setValues(y, vextent, 0, av.getAlignment().getHeight());\r
+    hscroll.setValues(x, hextent, 0, width);\r
+    vscroll.setValues(y, vextent, 0, height);\r
   }\r
 \r
   /**\r
@@ -462,10 +647,26 @@ public class AlignmentPanel extends GAlignmentPanel
 \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
+        if(offy>-1)\r
+        {\r
+          int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.\r
+              seqCanvas.getWidth());\r
+          av.setStartRes(offy * rowSize);\r
+          av.setEndRes( (offy + 1) * rowSize);\r
+        }\r
+        else\r
+        {\r
+          //This is only called if file loaded is a jar file that\r
+          //was wrapped when saved and user has wrap alignment true\r
+          //as preference setting\r
+          SwingUtilities.invokeLater(new Runnable()\r
+              {\r
+                public void run()\r
+                {\r
+                  setScrollValues(av.getStartRes(), av.getStartSeq());\r
+                }\r
+              });\r
+        }\r
       }\r
       else\r
       {\r
@@ -480,28 +681,33 @@ public class AlignmentPanel extends GAlignmentPanel
       overviewPanel.setBoxPosition();\r
     }\r
 \r
-    int xShift = av.getStartRes() - oldX;\r
-    int yShift = av.getStartSeq() - oldY;\r
+    int scrollX = av.startRes - oldX;\r
+    int scrollY = av.startSeq - oldY;\r
 \r
-    if ( (xShift != 0 && yShift != 0) ||\r
-        (Math.abs(xShift) > av.getEndRes() - av.getStartRes()\r
-         || Math.abs(yShift) > av.getEndSeq() - av.getStartSeq())\r
-        || av.getWrapAlignment()\r
-        || !fastPaint)\r
+    if (av.getWrapAlignment() || !fastPaint)\r
     {\r
-      // Either no shift at all, or shift greater than visible amount\r
       repaint();\r
     }\r
     else\r
     {\r
-      idPanel.idCanvas.fastPaint(yShift);\r
-      seqPanel.seqCanvas.fastPaint(xShift, yShift);\r
-\r
-      scalePanel.repaint();\r
-\r
-      if (av.getShowAnnotation())\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
-        annotationPanel.fastPaint(xShift);\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
@@ -522,8 +728,16 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
     if (av.getWrapAlignment())\r
     {\r
-      int max = av.alignment.getWidth() /\r
-          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth()) +1;\r
+      int maxwidth = av.alignment.getWidth();\r
+\r
+      if (av.hasHiddenColumns)\r
+        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
+\r
+      int max = maxwidth /\r
+          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth()) +\r
+          1;\r
+\r
+\r
       vscroll.setMaximum(max);\r
       vscroll.setUnitIncrement(1);\r
       vscroll.setVisibleAmount(1);\r
@@ -533,12 +747,10 @@ public class AlignmentPanel extends GAlignmentPanel
       setScrollValues(av.getStartRes(), av.getStartSeq());\r
     }\r
 \r
-\r
-    if( this.getVisibleRect().getBounds() == g.getClipBounds() )\r
-    {\r
-      if (overviewPanel != null)\r
+    if( this.getVisibleRect().getBounds() == g.getClipBounds()\r
+        && overviewPanel != null)\r
         overviewPanel.updateOverviewImage();\r
-    }\r
+\r
   }\r
 \r
   /**\r
@@ -657,10 +869,13 @@ public class AlignmentPanel extends GAlignmentPanel
     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.getSelectionGroup().getSequences(false).contains(\r
               av.getAlignment().getSequenceAt(i)))\r
       {\r
         currentColor = Color.gray;\r
@@ -686,16 +901,17 @@ public class AlignmentPanel extends GAlignmentPanel
                     (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,\r
-                                 startRes, startSeq, 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, (endSeq - startSeq) * av.charHeight + 3);\r
+      pg.translate( -idWidth-3, (endSeq - startSeq) * av.charHeight + 3);\r
       alabels.drawComponent( (Graphics2D) pg, idWidth);\r
-      pg.translate(idWidth, 0);\r
+      pg.translate(idWidth+3, 0);\r
       annotationPanel.drawComponent( (Graphics2D) pg, startRes, endRes +\r
                                     1);\r
     }\r
@@ -738,10 +954,15 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
     int idWidth = calculateIdWidth().width + 4;\r
 \r
+    int maxwidth = av.alignment.getWidth();\r
+    if (av.hasHiddenColumns)\r
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
+\r
+\r
     int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth -\r
         idWidth);\r
 \r
-    int totalHeight = cHeight * (av.alignment.getWidth() / resWidth + 1);\r
+    int totalHeight = cHeight * (maxwidth / resWidth + 1);\r
 \r
     pg.setColor(Color.white);\r
     pg.fillRect(0, 0, pwidth, pheight);\r
@@ -773,14 +994,14 @@ public class AlignmentPanel extends GAlignmentPanel
       }\r
       if (labels != null)\r
       {\r
-        pg.translate(0,\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(0,\r
+        pg.translate(+3,\r
                      -ypos -\r
                      (av.getAlignment().getHeight() * av.charHeight));\r
       }\r
@@ -806,9 +1027,12 @@ public class AlignmentPanel extends GAlignmentPanel
 \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
+    int maxwidth = av.alignment.getWidth();\r
+    if (av.hasHiddenColumns)\r
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);\r
 \r
+    int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
+    int width = idPanel.getWidth() + (maxwidth * av.charWidth);\r
     if (idPanel.getWidth() == 0)\r
     {\r
       width += calculateIdWidth().getWidth() + 4;\r
@@ -817,7 +1041,14 @@ public class AlignmentPanel extends GAlignmentPanel
     if (av.getWrapAlignment())\r
     {\r
       height = getWrappedHeight();\r
-      width = seqPanel.getWidth() + idPanel.getWidth();\r
+      if (System.getProperty("java.awt.headless") != null\r
+          && System.getProperty("java.awt.headless").equals("true"))\r
+      {\r
+        width = alignFrame.getWidth() - 22;\r
+      }\r
+      else\r
+        width = seqPanel.getWidth() + idPanel.getWidth();\r
+\r
     }\r
     else if (av.getShowAnnotation())\r
     {\r
@@ -841,15 +1072,19 @@ public class AlignmentPanel extends GAlignmentPanel
       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
-      im.writeImage();\r
     }\r
     catch (OutOfMemoryError err)\r
     {\r
@@ -916,7 +1151,7 @@ public class AlignmentPanel extends GAlignmentPanel
           sy = s * av.charHeight + scaleHeight;\r
 \r
           SequenceI seq = av.alignment.getSequenceAt(s);\r
-          java.util.Vector features = seq.getDatasetSequence().getSequenceFeatures();\r
+          SequenceFeature [] features = seq.getDatasetSequence().getSequenceFeatures();\r
           SequenceGroup[] groups = av.alignment.findAllGroups(seq);\r
           for(res =0; res<alwidth; res++)\r
           {\r
@@ -963,33 +1198,32 @@ public class AlignmentPanel extends GAlignmentPanel
                   + " onMouseOver=\"toolTip('"\r
                   + alIndex + " " + triplet );\r
               }\r
-                fSize = features.size();\r
+                fSize = features.length;\r
                 for (f = 0; f < fSize; f++)\r
                 {\r
-                  SequenceFeature sf = (SequenceFeature) features.elementAt(f);\r
 \r
-                  if ( (sf.getBegin() <= seq.findPosition(res)) &&\r
-                      (sf.getEnd() >= seq.findPosition(res)))\r
+                  if ( (features[f].getBegin() <= seq.findPosition(res)) &&\r
+                      (features[f].getEnd() >= seq.findPosition(res)))\r
                   {\r
-                    if (sf.getType().equals("disulfide bond"))\r
+                    if (features[f].getType().equals("disulfide bond"))\r
                     {\r
-                      if (sf.getBegin() == seq.findPosition(res)\r
-                          || sf.getEnd() == seq.findPosition(res))\r
+                      if (features[f].getBegin() == seq.findPosition(res)\r
+                          || features[f].getEnd() == seq.findPosition(res))\r
                       {\r
-                        text.append("<br>disulfide bond " + sf.getBegin() + ":" +\r
-                                       sf.getEnd());\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(sf.getType());\r
-                      if (sf.getDescription() != null && !sf.getType().equals(sf.getDescription()))\r
-                        text.append(" " + sf.getDescription());\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 (sf.getStatus() != null && sf.getStatus().length()>0)\r
+                      if (features[f].getValue("status") != null )\r
                       {\r
-                        text.append(" (" + sf.getStatus() + ")");\r
+                        text.append(" (" + features[f].getValue("status") + ")");\r
                       }\r
                     }\r
                   }\r
@@ -1017,9 +1251,19 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
   int getWrappedHeight()\r
   {\r
+    int seqPanelWidth = seqPanel.seqCanvas.getWidth();\r
+\r
+    //If headless, seqPanel will have 0 width\r
+    if (System.getProperty("java.awt.headless") != null\r
+              && System.getProperty("java.awt.headless").equals("true"))\r
+    {\r
+      int idWidth = calculateIdWidth().width + 4;\r
+      seqPanelWidth = alignFrame.getWidth() - idWidth;\r
+    }\r
 \r
     int chunkWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(\r
-        seqPanel.seqCanvas.getWidth());\r
+        seqPanelWidth\r
+          );\r
 \r
     int hgap = av.charHeight;\r
     if (av.scaleAboveWrapped)\r
@@ -1035,7 +1279,12 @@ public class AlignmentPanel extends GAlignmentPanel
         + hgap\r
         + annotationHeight;\r
 \r
-    int height = ( (av.alignment.getWidth() / chunkWidth) + 1) * cHeight;\r
+    int maxwidth = av.alignment.getWidth();\r
+    if (av.hasHiddenColumns)\r
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
+\r
+\r
+    int height = ( (maxwidth / chunkWidth) + 1) * cHeight;\r
 \r
     return height;\r
   }\r