Merge branch 'JAL-986_idwidthprefs' into develop
authorjprocter <jprocter@compbio.dundee.ac.uk>
Wed, 9 Nov 2011 15:21:10 +0000 (15:21 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Wed, 9 Nov 2011 15:21:10 +0000 (15:21 +0000)
Conflicts:
.classpath

1  2 
.classpath
help/html/features/preferences.html
src/jalview/bin/Cache.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/Preferences.java
src/jalview/jbgui/GPreferences.java

diff --combined .classpath
@@@ -1,7 -1,6 +1,7 @@@
  <?xml version="1.0" encoding="UTF-8"?>
  <classpath>
        <classpathentry kind="src" path="src"/>
 +      <classpathentry kind="src" path="utils"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="lib" path="lib/activation.jar"/>
        <classpathentry kind="lib" path="lib/axis.jar" sourcepath="D:/axis-1_2RC2-src/axis-1_2RC2"/>
        </classpathentry>
        <classpathentry kind="lib" path="lib/miglayout-4.0-swing.jar"/>
        <classpathentry kind="lib" path="lib/jswingreader-0.3.jar" sourcepath="/jswingreader"/>
 -      <classpathentry kind="lib" path="lib/min-jaba-client.jar"/>
        <classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
 +      <classpathentry kind="lib" path="lib/min-jaba-client-2.0.jar" sourcepath="/clustengine2"/>
+       <classpathentry kind="lib" path="lib/Jmol-12.2.4.jar"/>
        <classpathentry kind="lib" path="appletlib/JmolApplet-12.2.4.jar"/>
        <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
 +<!--  <classpathentry exported="true" kind="var" path="GROOVY_ECLIPSE_HOME/groovy-all-1.0.jar"/> -->
 +      <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.java"/>
 +      <classpathentry kind="lib" path="lib/VARNAv3-9.jar"/>
-       <classpathentry kind="lib" path="lib/Jmol-12.2.4.jar"/>
        <classpathentry kind="output" path="classes"/>
  </classpath>
@@@ -1,7 -1,7 +1,7 @@@
  <html>
  <!--
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -143,6 -143,11 +143,11 @@@ style for EPS export
        make an EPS file.</li>
  </ul>
  </p>
+ <p><em>Automatically set ID width</em><br>
+ When enabled, the column containing sequence and annotation labels at the left hand side of an exported figure will be made large enough to display each sequence ID and annotation label in its own line. Enable this if you have particularly long sequence IDs and need to generate EPS or PNG figures or web pages.</p>
+ <p><em>Figure ID column width</em><br>
+ Manually specify the width of the left hand column where sequence IDs and annotation labels will be rendered in exported alignment figures. This setting will be ignored if <em>&quot;Automatically set ID width&quot;</em> is set.
+ </p>
  <p><em>Sequence//Start-End Numbering</em><br>
  The output tab also has a group of checkboxes for each file format. If
  these are ticked, then Jalview will write files with the start and end
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -124,8 -124,6 +124,8 @@@ import org.biojava.dasobert.dasregistry
   * histogram.</li>
   * <li>SHOW_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
   * logo.</li>
 + * <li>NORMALISE_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
 + * logo normalised to row height rather than histogram height.</li>
   * <li>FOLLOW_SELECTIONS (true) Controls whether a new alignment view should
   * respond to selections made in other alignments containing the same sequences.
   * </li>
   * <li>ANNOTATIONCOLOUR_MAX (red) Shade used for maximum value of annotation when shading by annotation</li>
   * <li>www.jalview.org (http://www.jalview.org) a property enabling all HTTP requests to be redirected to a mirror of http://www.jalview.org</li>
   * 
+  * <li>FIGURE_AUTOIDWIDTH (false) Expand the left hand column of an exported alignment figure to accommodate even the longest sequence ID or annotation label.</li>
+  * <li>FIGURE_FIXEDIDWIDTH Specifies the width to use for the left-hand column when exporting an alignment as a figure (setting FIGURE_AUTOIDWIDTH to true will override this).</li>
   * <li></li>
   * 
   * </ul>
@@@ -280,26 -280,6 +282,26 @@@ public class Cach
        System.setProperty("http.proxyPort", getDefault("PROXY_PORT", null));
      }
  
 +    // LOAD THE AUTHORS FROM THE authors.props file
 +    try
 +    {
 +      String authorDetails = "jar:".concat(Cache.class.getProtectionDomain()
 +              .getCodeSource().getLocation().toString()
 +              .concat("!/authors.props"));
 +
 +      java.net.URL localJarFileURL = new java.net.URL(authorDetails);
 +
 +      InputStream in = localJarFileURL.openStream();
 +      applicationProperties.load(in);
 +      in.close();
 +    } catch (Exception ex)
 +    {
 +      System.out.println("Error reading author details: " + ex);
 +      applicationProperties.remove("AUTHORS");
 +      applicationProperties.remove("AUTHORFNAMES");
 +      applicationProperties.remove("YEAR");
 +    }
 +
      // 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
      }
      return null;
    }
+   /**
+    * get and parse a property as an integer. send any parsing problems to System.err
+    * @param property
+    * @return null or Integer
+    */
+   public static Integer getIntegerProperty(String property)
+   {
+     String val=getProperty(property);
+     if (val!=null && (val=val.trim()).length()>0)
+     {
+       try {
+         return Integer.valueOf(val);
+       } catch (NumberFormatException x)
+       {
+         System.err.println("Invalid integer in property '"+property+"' (value was '"+val+"')");
+       }
+     }
+     return null;
+   }
  }
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -32,6 -32,7 +32,6 @@@ import jalview.bin.Cache
  import jalview.datamodel.*;
  import jalview.jbgui.*;
  import jalview.schemes.*;
 -import jalview.structure.SelectionSource;
  import jalview.structure.StructureSelectionManager;
  
  /**
@@@ -173,15 -174,28 +173,28 @@@ public class AlignmentPanel extends GAl
     */
    public Dimension calculateIdWidth()
    {
+     // calculate sensible default width when no preference is available
+     
+     int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
+     int maxwidth = Math.max(20,
+             Math.min(afwidth - 200, (int) 2 * afwidth / 3));
+     return calculateIdWidth(maxwidth);
+   }
+   /**
+    * Calculate the width of the alignment labels based on the displayed names
+    * and any bounds on label width set in preferences.
+    * @param maxwidth -1 or maximum width allowed for IdWidth
+    * @return Dimension giving the maximum width of the alignment label panel
+    *         that should be used.
+    */
+   public Dimension calculateIdWidth(int maxwidth)
+   {
      Container c = new Container();
  
      FontMetrics fm = c.getFontMetrics(new Font(av.font.getName(),
              Font.ITALIC, av.font.getSize()));
  
      AlignmentI al = av.getAlignment();
-     int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
-     int maxwidth = Math.max(20,
-             Math.min(afwidth - 200, (int) 2 * afwidth / 3));
      int i = 0;
      int idWidth = 0;
      String id;
        }
      }
  
-     return new Dimension(Math.min(maxwidth, idWidth), 12);
+     return new Dimension(maxwidth<0 ? idWidth : Math.min(maxwidth, idWidth), 12);
    }
  
    /**
      // do we need to scroll the panel?
      // TODO: tons of nullpointereexceptions raised here.
      if (results != null && results.getSize() > 0 && av != null
 -            && av.alignment != null)
 +            && av.getAlignment() != null)
      {
 -      int seqIndex = av.alignment.findIndex(results);
 +      int seqIndex = av.getAlignment().findIndex(results);
        if (seqIndex == -1)
        {
          return false;
        }
 -      SequenceI seq = av.alignment.getSequenceAt(seqIndex);
 +      SequenceI seq = av.getAlignment().getSequenceAt(seqIndex);
        
 -      int[] r=results.getResults(seq, 0, av.alignment.getWidth());
 +      int[] r=results.getResults(seq, 0, av.getAlignment().getWidth());
        if (r == null)
        {
          return false;
        {
          return false;
        }
 -      if (av.hasHiddenColumns)
 +      if (av.hasHiddenColumns())
        {
          start = av.getColumnSelection().findColumnPosition(start);
          end = av.getColumnSelection().findColumnPosition(end);
          if (start==end)
          {
 -          if (!av.colSel.isVisible(r[0]))
 +          if (!av.getColumnSelection().isVisible(r[0]))
            {
              // don't scroll - position isn't visible
              return false;
    public void setScrollValues(int x, int y)
    {
      // System.err.println("Scroll to "+x+","+y);
 -    if (av == null || av.alignment == null)
 +    if (av == null || av.getAlignment() == null)
      {
        return;
      }
 -    int width = av.alignment.getWidth();
 -    int height = av.alignment.getHeight();
 +    int width = av.getAlignment().getWidth();
 +    int height = av.getAlignment().getHeight();
  
 -    if (av.hasHiddenColumns)
 +    if (av.hasHiddenColumns())
      {
        width = av.getColumnSelection().findColumnPosition(width);
      }
  
      if (av.getWrapAlignment())
      {
 -      int maxwidth = av.alignment.getWidth();
 +      int maxwidth = av.getAlignment().getWidth();
  
 -      if (av.hasHiddenColumns)
 +      if (av.hasHiddenColumns())
        {
          maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
        }
    public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)
            throws PrinterException
    {
-     int idWidth = getVisibleIdWidth();
+     int idWidth = getVisibleIdWidth(false);
      FontMetrics fm = getFontMetrics(av.getFont());
      int scaleHeight = av.charHeight + fm.getDescent();
  
        endSeq = av.getAlignment().getHeight();
      }
  
 -    int pagesHigh = ((av.alignment.getHeight() / totalSeq) + 1) * pheight;
 +    int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1) * pheight;
  
      if (av.showAnnotation)
      {
      pg.translate(idWidth, 0);
      seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq, 0);
  
 -    if (av.showAnnotation && (endSeq == av.alignment.getHeight()))
 +    if (av.showAnnotation && (endSeq == av.getAlignment().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);
 +      annotationPanel.renderer.drawComponent(annotationPanel, av, (Graphics2D) pg, -1, startRes, endRes + 1);
      }
  
      return Printable.PAGE_EXISTS;
      int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap
              + annotationHeight;
  
-     int idWidth = getVisibleIdWidth();
+     int idWidth = getVisibleIdWidth(false);
  
 -    int maxwidth = av.alignment.getWidth();
 -    if (av.hasHiddenColumns)
 +    int maxwidth = av.getAlignment().getWidth();
 +    if (av.hasHiddenColumns())
      {
        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
      }
  
      do
      {
 -      for (int i = 0; i < av.alignment.getHeight(); i++)
 +      for (int i = 0; i < av.getAlignment().getHeight(); i++)
        {
          pg.setFont(idPanel.idCanvas.idfont);
 -        SequenceI s = av.alignment.getSequenceAt(i);
 +        SequenceI s = av.getAlignment().getSequenceAt(i);
          String string = s.getDisplayId(av.getShowJVSuffix());
          int xPos = 0;
          if (av.rightAlignIds)
        return Printable.NO_SUCH_PAGE;
      }
    }
+   /**
+    * get current sequence ID panel width, or nominal value if panel were to be displayed using default settings
+    * @return
+    */
    int getVisibleIdWidth()
    {
-     return idPanel.getWidth() > 0 ? idPanel.getWidth()
-             : calculateIdWidth().width + 4;
+     return getVisibleIdWidth(true);
+   }
+   /**
+    * get current sequence ID panel width, or nominal value if panel were to be displayed using default settings
+    * @param onscreen indicate if the Id width for onscreen or offscreen display should be returned
+    * @return
+    */
+   int getVisibleIdWidth(boolean onscreen)
+   {
+     // see if rendering offscreen - check preferences and calc width accordingly
+     if (!onscreen && Cache.getDefault("FIGURE_AUTOIDWIDTH", false))
+     {
+       return calculateIdWidth(-1).width+4;
+     }
+     Integer idwidth=null;
+     if (onscreen || (idwidth=Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH"))==null) {
+       return (idPanel.getWidth() > 0 ? idPanel.getWidth()
+             : calculateIdWidth().width + 4);
+     }
+     return idwidth.intValue()+4;
    }
  
    void makeAlignmentImage(int type, File file)
    {
 -    int maxwidth = av.alignment.getWidth();
 -    if (av.hasHiddenColumns)
 +    int maxwidth = av.getAlignment().getWidth();
 +    if (av.hasHiddenColumns())
      {
        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);
      }
  
 -    int height = ((av.alignment.getHeight() + 1) * av.charHeight)
 +    int height = ((av.getAlignment().getHeight() + 1) * av.charHeight)
              + scalePanel.getHeight();
-     int width = getVisibleIdWidth() + (maxwidth * av.charWidth);
+     int width = getVisibleIdWidth(false) + (maxwidth * av.charWidth);
  
      if (av.getWrapAlignment())
      {
        if (System.getProperty("java.awt.headless") != null
                && System.getProperty("java.awt.headless").equals("true"))
        {
-         // TODO: JAL-244
+         // need to obtain default alignment width and then add in any additional allowance for id margin
+         // this duplicates the calculation in getWrappedHeight but adjusts for offscreen idWith
          width = alignFrame.getWidth() - vscroll.getPreferredSize().width
                  - alignFrame.getInsets().left
-                 - alignFrame.getInsets().right;
+                 - alignFrame.getInsets().right
+                 - getVisibleIdWidth()+getVisibleIdWidth(false);
        }
        else
        {
-         width = seqPanel.getWidth() + getVisibleIdWidth();
+         width = seqPanel.getWidth() + getVisibleIdWidth(false);
        }
  
      }
    {
      // /////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS
      // ////////////////////////////////////////////
-     int idWidth = getVisibleIdWidth();
+     int idWidth = getVisibleIdWidth(true);
      FontMetrics fm = getFontMetrics(av.getFont());
      int scaleHeight = av.charHeight + fm.getDescent();
  
      {
        try
        {
 -        int s, sSize = av.alignment.getHeight(), res, alwidth = av.alignment
 +        int s, sSize = av.getAlignment().getHeight(), res, alwidth = av.getAlignment()
                  .getWidth(), g, gSize, f, fSize, sy;
          StringBuffer text = new StringBuffer();
          PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
          {
            sy = s * av.charHeight + scaleHeight;
  
 -          SequenceI seq = av.alignment.getSequenceAt(s);
 +          SequenceI seq = av.getAlignment().getSequenceAt(s);
            SequenceFeature[] features = seq.getDatasetSequence()
                    .getSequenceFeatures();
 -          SequenceGroup[] groups = av.alignment.findAllGroups(seq);
 +          SequenceGroup[] groups = av.getAlignment().findAllGroups(seq);
            for (res = 0; res < alwidth; res++)
            {
              text = new StringBuffer();
              Object obj = null;
 -            if (av.alignment.isNucleotide())
 +            if (av.getAlignment().isNucleotide())
              {
                obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res)
                        + "");
      int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap
              + annotationHeight;
  
 -    int maxwidth = av.alignment.getWidth();
 -    if (av.hasHiddenColumns)
 +    int maxwidth = av.getAlignment().getWidth();
 +    if (av.hasHiddenColumns())
      {
        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
      }
        jalview.structure.StructureSelectionManager ssm = av.getStructureSelectionManager();
        ssm.removeStructureViewerListener(seqPanel, null);
        ssm.removeSelectionListener(seqPanel);
 -      av.alignment = null;
 +      av.setAlignment(null);
        av = null;
      }
      else
      boolean cons = av.isShowGroupConsensus();
      boolean showprf = av.isShowSequenceLogo();
      boolean showConsHist = av.isShowConsensusHistogram();
 +    boolean normLogo = av.isNormaliseSequenceLogo();
  
      boolean sortg = true;
  
      // remove old automatic annotation
      // add any new annotation
  
 -    Vector gr = av.alignment.getGroups(); // OrderedBy(av.alignment.getSequencesArray());
 +    Vector gr = av.getAlignment().getGroups(); // OrderedBy(av.getAlignment().getSequencesArray());
      // intersect alignment annotation with alignment groups
  
 -    AlignmentAnnotation[] aan = av.alignment.getAlignmentAnnotation();
 +    AlignmentAnnotation[] aan = av.getAlignment().getAlignmentAnnotation();
      Hashtable oldrfs = new Hashtable();
      if (aan != null)
      {
          if (aan[an].autoCalculated && aan[an].groupRef != null)
          {
            oldrfs.put(aan[an].groupRef, aan[an].groupRef);
 -          av.alignment.deleteAnnotation(aan[an]);
 +          av.getAlignment().deleteAnnotation(aan[an]);
            aan[an] = null;
          }
        }
            // set defaults for this group's conservation/consensus
            sg.setshowSequenceLogo(showprf);
            sg.setShowConsensusHistogram(showConsHist);
 +          sg.setNormaliseSequenceLogo(normLogo);
          }
          if (conv)
          {
            updateCalcs = true;
 -          av.alignment.addAnnotation(sg.getConservationRow(), 0);
 +          av.getAlignment().addAnnotation(sg.getConservationRow(), 0);
          }
          if (cons)
          {
            updateCalcs = true;
 -          av.alignment.addAnnotation(sg.getConsensus(), 0);
 +          av.getAlignment().addAnnotation(sg.getConsensus(), 0);
          }
          // refresh the annotation rows
          if (updateCalcs)
    @Override
    public AlignmentI getAlignment()
    {
 -    return av.alignment;
 +    return av.getAlignment();
    }
  
    /**
    {
      return av.getStructureSelectionManager();
    }
 +
 +  @Override
 +  public void raiseOOMWarning(String string, OutOfMemoryError error)
 +  {
 +    new OOMWarning(string,  error, this);
 +  }
  }
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -201,7 -201,11 +201,11 @@@ public class Preferences extends GPrefe
      epsRendering.addItem("Text");
      epsRendering.setSelectedItem(Cache.getDefault("EPS_RENDERING",
              "Prompt each time"));
+     autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
+     userIdWidth.setEnabled(autoIdWidth.isSelected());
+     userIdWidthlabel.setEnabled(autoIdWidth.isSelected());
+     Integer wi = Cache.getIntegerProperty("FIGURE_USERIDWIDTH");
+     userIdWidth.setText(wi == null ? "" : wi.toString());
      blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
      clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
      fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
              Boolean.toString(modellerOutput.isSelected()));
      jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
  
+     Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
+             Boolean.toString(autoIdWidth.isSelected()));
+     userIdWidth_actionPerformed();
+     Cache.applicationProperties.setProperty("FIGURE_USERIDWIDTH",
+                 userIdWidth.getText());
      Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
              Boolean.toString(autoCalculateConsCheck.isSelected()));
      Cache.applicationProperties.setProperty("SORT_BY_TREE",
      maxColour.repaint();
    }
  
+   @Override
+   protected void userIdWidth_actionPerformed()
+   {
+     try
+     {
+       String val = userIdWidth.getText().trim();
+       if (val.length() > 0)
+       {
+         Integer iw = Integer.parseInt(val);
+         if (iw.intValue() < 12)
+         {
+           throw new NumberFormatException();
+         }
+         userIdWidth.setText(iw.toString());
+       }
+     } catch (NumberFormatException x)
+     {
+       JOptionPane
+               .showInternalMessageDialog(
+                       Desktop.desktop,
+                       "The user defined width for the\nannotation and sequence ID columns\nin exported figures must be\nat least 12 pixels wide.",
+                       "Invalid ID Column width",
+                       JOptionPane.WARNING_MESSAGE);
+       userIdWidth.setText("");
+     }
+   }
+   @Override
+   protected void autoIdWidth_actionPerformed()
+   {
+     userIdWidth.setEnabled(!autoIdWidth.isSelected());
+     userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
+   }
  }
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -160,6 -160,11 +160,11 @@@ public class GPreferences extends JPane
    JLabel epsLabel = new JLabel();
  
    protected JComboBox epsRendering = new JComboBox();
+   
+   protected JLabel userIdWidthlabel = new JLabel();
+   protected JCheckBox autoIdWidth = new JCheckBox();
+   protected JTextField userIdWidth = new JTextField();
  
    JLabel jLabel1 = new JLabel();
  
      sortByTree.setText("Sort With New Tree");
      sortByTree.setToolTipText("When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment.");
      sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
+     
+     autoIdWidth.setFont(JvSwingUtils.getLabelFont());
+     autoIdWidth.setText("Automatically set ID width");
+     autoIdWidth.setToolTipText("<html>"+JvSwingUtils.wrapTooltip("Adjusts the width of the generated EPS or PNG file to ensure even the longest sequence ID or annotation label is displayed")+"</html>");
+     autoIdWidth.setBounds(new Rectangle(228, 96,188,23));
+     autoIdWidth.addActionListener(new ActionListener()
+     {
+       
+       @Override
+       public void actionPerformed(ActionEvent e)
+       {
+         autoIdWidth_actionPerformed();
+       }
+     });
+     userIdWidthlabel.setFont(JvSwingUtils.getLabelFont());
+     userIdWidthlabel.setText("Figure ID column width");
+     userIdWidth
+             .setToolTipText("<html>"+JvSwingUtils
+                     .wrapTooltip("Manually specify the width of the left hand column where sequence IDs and annotation labels will be rendered in exported alignment figures. This setting will be ignored if 'Automatically set ID width' is set")+"</html>");
+     userIdWidthlabel
+             .setToolTipText("<html>"+JvSwingUtils
+                     .wrapTooltip("Manually specify the width of the left hand column where sequence IDs and annotation labels will be rendered in exported alignment figures. This setting will be ignored if 'Automatically set ID width' is set")+"</html>");
+     userIdWidthlabel.setBounds(new Rectangle(236, 120,168,23));
+     userIdWidth.setFont(JvSwingUtils.getTextAreaFont());
+     userIdWidth.setText("");
+     userIdWidth.setBounds(new Rectangle(232,144,84,23));
+     userIdWidth.addActionListener(new ActionListener()
+     {
+       
+       @Override
+       public void actionPerformed(ActionEvent e)
+       {
+         userIdWidth_actionPerformed();
+       }
+     });
      modellerOutput.setFont(JvSwingUtils.getLabelFont());
      modellerOutput.setText("Use Modeller Output");
      modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
      dasPanel.setLayout(borderLayout4);
      wsPanel.setLayout(borderLayout5);
      wrap.setFont(JvSwingUtils.getLabelFont());
      jPanel11.add(pfamjv);
      jPanel11.add(pileupjv);
      jPanel11.add(pirjv);
+     exportTab.add(autoIdWidth);
+     exportTab.add(userIdWidth);
+     exportTab.add(userIdWidthlabel);
      exportTab.add(modellerOutput);
      tabbedPane.add(calcTab, "Editing");
      calcTab.add(autoCalculateConsCheck);
      exportTab.add(jPanel11);
    }
  
+   protected void autoIdWidth_actionPerformed()
+   {
+     // TODO Auto-generated method stub
+     
+   }
+   protected void userIdWidth_actionPerformed()
+   {
+     // TODO Auto-generated method stub
+     
+   }
    protected void maxColour_actionPerformed()
    {
      // TODO Auto-generated method stub