JAL-3377 include seq-annotation spacing in getWrappedHeight()
[jalview.git] / src / jalview / gui / AlignmentPanel.java
index f2fdad3..97a0a4e 100644 (file)
  */
 package jalview.gui;
 
+import static jalview.util.ImageMaker.TYPE.EPS;
+import static jalview.util.ImageMaker.TYPE.PNG;
+import static jalview.util.ImageMaker.TYPE.SVG;
+
 import jalview.analysis.AnnotationSorter;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
@@ -36,6 +40,7 @@ import jalview.math.AlignmentDimension;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.Comparison;
+import jalview.util.ImageMaker;
 import jalview.util.MessageManager;
 import jalview.viewmodel.ViewportListenerI;
 import jalview.viewmodel.ViewportRanges;
@@ -871,19 +876,18 @@ public class AlignmentPanel extends GAlignmentPanel implements
   }
 
   /**
-   * DOCUMENT ME!
+   * Provides the implementation of Printable.print
    * 
    * @param pg
-   *          DOCUMENT ME!
+   *             DOCUMENT ME!
    * @param pf
-   *          DOCUMENT ME!
+   *             DOCUMENT ME!
    * @param pi
-   *          DOCUMENT ME!
+   *             DOCUMENT ME!
    * 
    * @return DOCUMENT ME!
    * 
    * @throws PrinterException
-   *           DOCUMENT ME!
    */
   @Override
   public int print(Graphics pg, PageFormat pf, int pi)
@@ -896,7 +900,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
     if (av.getWrapAlignment())
     {
-      return printWrappedAlignment(pwidth, pheight, pi, pg);
+      return printWrappedAlignment(pwidth, pheight, pi, pg, true);
     }
     else
     {
@@ -1029,6 +1033,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
               alignmentDrawnHeight);
       getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av,
               alignmentGraphics, -1, startRes, endRes + 1);
+
+      /*
+       * reset to left margin
+       */
+      alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
     }
 
     return Printable.PAGE_EXISTS;
@@ -1038,19 +1047,25 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * Prints one page of an alignment in wrapped mode. Returns
    * Printable.PAGE_EXISTS (0) if a page was drawn, or Printable.NO_SUCH_PAGE if
    * no page could be drawn (page number out of range).
+   * <p>
+   * The method is to write the whole alignment, but set a clip region such that
+   * only the specified page is written. This allows specified page(s) to be
+   * printed from the print dialog. The whole image may be written simply by
+   * making the page size match the image size. In this case, parameter
+   * {@code clipToPage} should be set to {@code false}, so that more output (for
+   * example the second panel of a split frame) can be written if wanted.
    * 
    * @param pageWidth
    * @param pageHeight
    * @param pageNumber
-   *          (0, 1, ...)
+   *                     (0, 1, ...)
    * @param g
+   * @param clipToPage
    * 
    * @return
-   * 
-   * @throws PrinterException
    */
   public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
-          Graphics g) throws PrinterException
+          Graphics g, boolean clipToPage)
   {
     int annotationHeight = 0;
     if (av.isShowAnnotation())
@@ -1089,7 +1104,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
      */
     g.translate(0, -pageNumber * pageHeight);
 
-    g.setClip(0, pageNumber * pageHeight, pageWidth, pageHeight);
+    if (clipToPage)
+    {
+      g.setClip(0, pageNumber * pageHeight, pageWidth, pageHeight);
+    }
 
     /*
      * draw sequence ids and annotation labels (if shown)
@@ -1098,9 +1116,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
     idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight);
 
     g.translate(idWidth, 0);
-
     getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth,
             totalHeight, 0);
+    g.translate(-idWidth, 0);
 
     if ((pageNumber * pageHeight) < totalHeight)
     {
@@ -1149,7 +1167,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
     return idwidth.intValue() + 4;
   }
 
-  void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file)
+  /**
+   * Generates an image of the alignment panel of the specified type. If
+   * {@code type} is not null, the image is written to the file, otherwise the
+   * user is prompted to specify the output file before writing to it.
+   * 
+   * @param type
+   * @param file
+   * @param forSplitFrame
+   */
+  void makeAlignmentImage(ImageMaker.TYPE type, File file,
+          boolean forSplitFrame)
   {
     int borderBottomOffset = 5;
     long pSessionId = System.currentTimeMillis();
@@ -1166,39 +1194,30 @@ public class AlignmentPanel extends GAlignmentPanel implements
     }
     try
     {
-      // todo splitFrame a parameter (optional menu item choice)
-      boolean splitFrame = av.getCodingComplement() != null;
+      /*
+       * if exporting a split frame image, the graphics object has 
+       * width: maximum of the top and bottom image widths
+       * height: sum of the top and bottom image heights
+       */
+      AlignmentPanel comp = null;
       AlignmentDimension dim1 = getAlignmentDimension();
       AlignmentDimension dim2 = new AlignmentDimension(0, 0);
-      if (splitFrame)
+      if (forSplitFrame)
       {
-        AlignmentPanel comp = ((AlignViewport) av.getCodingComplement())
+        comp = ((AlignViewport) av.getCodingComplement())
                 .getAlignPanel();
         dim2 = comp.getAlignmentDimension();
       }
-      final int graphicsHeight = dim1.height + dim2.height;
+      final int graphicsHeight = dim1.height + dim2.height
+              + borderBottomOffset;
       final int graphicsWidth = Math.max(dim1.width, dim2.width);
 
-      jalview.util.ImageMaker im;
-      final String imageAction, imageTitle;
-      if (type == jalview.util.ImageMaker.TYPE.PNG)
-      {
-        imageAction = "Create PNG image from alignment";
-        imageTitle = null;
-      }
-      else if (type == jalview.util.ImageMaker.TYPE.EPS)
-      {
-        imageAction = "Create EPS file from alignment";
-        imageTitle = alignFrame.getTitle();
-      }
-      else
-      {
-        imageAction = "Create SVG file from alignment";
-        imageTitle = alignFrame.getTitle();
-      }
+      final String dialogTitle = MessageManager
+              .formatMessage("label.make_alignment_image", type.getName());
+      String imageTitle = type == PNG ? null : alignFrame.getTitle();
 
-      im = new jalview.util.ImageMaker(this, type, imageAction,
-              graphicsWidth, graphicsHeight + borderBottomOffset, file,
+      ImageMaker im = new ImageMaker(this, type, dialogTitle,
+              graphicsWidth, graphicsHeight, file,
               imageTitle, alignFrame, pSessionId, headless);
       Graphics graphics = im.getGraphics();
       if (graphics == null)
@@ -1210,26 +1229,32 @@ public class AlignmentPanel extends GAlignmentPanel implements
       if (av.getWrapAlignment())
       {
         printWrappedAlignment(dim1.width, dim1.height + borderBottomOffset,
-                0, graphics);
+                0, graphics, false);
       }
       else
       {
         printUnwrapped(dim1.width, dim1.height, 0, graphics, graphics);
       }
 
-      if (splitFrame)
+      if (forSplitFrame)
       {
         /*
          * append coding complement image
-         * todo: always write top frame first!
          */
-        graphics.translate(0, dim1.height);
-        AlignmentPanel comp = ((AlignViewport) av.getCodingComplement())
-                .getAlignPanel();
+        boolean test = true;
+        if (test)
+        {
+          /*
+           * debug location of next write to Graphics
+           */
+          graphics.setColor(Color.red);
+          graphics.drawString("Hello world", 0, 0);
+          graphics.setColor(Color.black);
+        }
         if (av.getCodingComplement().getWrapAlignment())
         {
           comp.printWrappedAlignment(dim2.width,
-                  dim2.height + borderBottomOffset, 0, graphics);
+                  dim2.height + borderBottomOffset, 0, graphics, false);
         }
         else
         {
@@ -1259,8 +1284,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * <li>sequence ids</li>
    * <li>scale above, left or right if shown</li>
    * <li>sequences</li>
-   * <li>annotations, if shown</li> The alignment may be in wrapped or unwrapped
-   * mode.
+   * <li>annotations, if shown</li>
+   * </ul>
+   * The alignment may be in wrapped or unwrapped mode.
    * <ul>
    * 
    * @return
@@ -1301,24 +1327,39 @@ public class AlignmentPanel extends GAlignmentPanel implements
   }
 
   /**
-   * DOCUMENT ME!
+   * Creates and writes an EPS image of the alignment, to the given file if
+   * specified, else after prompting for the output file
+   * 
+   * @param epsFile
+   * @param forSplitFrame
    */
-  public void makeEPS(File epsFile)
+  public void makeEPS(File epsFile, boolean forSplitFrame)
   {
-    makeAlignmentImage(jalview.util.ImageMaker.TYPE.EPS, epsFile);
+    makeAlignmentImage(EPS, epsFile, forSplitFrame);
   }
 
   /**
-   * DOCUMENT ME!
+   * Creates and writes a PNG image of the alignment, to the given file if
+   * specified, else after prompting for the output file
+   * 
+   * @param pngFile
+   * @param forSplitFrame
    */
-  public void makePNG(File pngFile)
+  public void makePNG(File pngFile, boolean forSplitFrame)
   {
-    makeAlignmentImage(jalview.util.ImageMaker.TYPE.PNG, pngFile);
+    makeAlignmentImage(PNG, pngFile, forSplitFrame);
   }
 
-  public void makeSVG(File svgFile)
+  /**
+   * Creates and writes an SVG image of the alignment, to the given file if
+   * specified, else after prompting for the output file
+   * 
+   * @param svgFile
+   * @param forSplitFrame
+   */
+  public void makeSVG(File svgFile, boolean forSplitFrame)
   {
-    makeAlignmentImage(jalview.util.ImageMaker.TYPE.SVG, svgFile);
+    makeAlignmentImage(SVG, svgFile, forSplitFrame);
   }
 
   public void makePNGImageMap(File imgMapFile, String imageName)
@@ -1474,6 +1515,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     int annotationHeight = 0;
     if (av.isShowAnnotation())
     {
+      hgap += SeqCanvas.SEQS_ANNOTATION_GAP;
       annotationHeight = getAnnotationPanel().adjustPanelHeight();
     }