Merge branch 'bug/JAL-2277_refactorPrintUnwrapped' into develop
authortcofoegbu <tcnofoegbu@dundee.ac.uk>
Tue, 22 Nov 2016 17:21:16 +0000 (17:21 +0000)
committertcofoegbu <tcnofoegbu@dundee.ac.uk>
Tue, 22 Nov 2016 17:21:16 +0000 (17:21 +0000)
1  2 
src/jalview/gui/AlignmentPanel.java
src/jalview/io/HtmlSvgOutput.java

@@@ -25,7 -25,7 +25,7 @@@ import jalview.api.AlignViewportI
  import jalview.api.AlignmentViewPanel;
  import jalview.bin.Cache;
  import jalview.datamodel.AlignmentI;
 -import jalview.datamodel.SearchResults;
 +import jalview.datamodel.SearchResultsI;
  import jalview.datamodel.SequenceFeature;
  import jalview.datamodel.SequenceGroup;
  import jalview.datamodel.SequenceI;
@@@ -297,7 -297,7 +297,7 @@@ public class AlignmentPanel extends GAl
     * Highlight the given results on the alignment.
     * 
     */
 -  public void highlightSearchResults(SearchResults results)
 +  public void highlightSearchResults(SearchResultsI results)
    {
      scrollToPosition(results);
      getSeqPanel().seqCanvas.highlightSearchResults(results);
     * 
     * @param results
     */
 -  public boolean scrollToPosition(SearchResults results)
 +  public boolean scrollToPosition(SearchResultsI results)
    {
      return scrollToPosition(results, 0, true, false);
    }
     * @param redrawOverview
     * @return
     */
 -  public boolean scrollToPosition(SearchResults searchResults,
 +  public boolean scrollToPosition(SearchResultsI searchResults,
            boolean redrawOverview)
    {
      return scrollToPosition(searchResults, 0, redrawOverview, false);
     *          if true, try to centre the search results horizontally in the view
     * @return false if results were not found
     */
 -  public boolean scrollToPosition(SearchResults results,
 +  public boolean scrollToPosition(SearchResultsI results,
            int verticalOffset, boolean redrawOverview, boolean centre)
    {
      int startv, endv, starts, ends;
      }
      else
      {
-       return printUnwrapped(pwidth, pheight, pi, pg);
+       return printUnwrapped(pwidth, pheight, pi, pg, pg);
      }
    }
  
     * @throws PrinterException
     *           DOCUMENT ME!
     */
-   public int printUnwrapped(int pwidth, int pheight, int pi,
-           Graphics... pg)
+   /**
+    * Draws the alignment image, including sequence ids, sequences, and
+    * annotation labels and annotations if shown, on either one or two Graphics
+    * context.
+    * 
+    * @param pageWidth
+    * @param pageHeight
+    * @param pi
+    * @param idGraphics
+    *          the graphics context for sequence ids and annotation labels
+    * @param alignmentGraphics
+    *          the graphics context for sequences and annotations (may or may not
+    *          be the same context as idGraphics)
+    * @return
+    * @throws PrinterException
+    */
+   public int printUnwrapped(int pageWidth, int pageHeight, int pi,
+           Graphics idGraphics, Graphics alignmentGraphics)
            throws PrinterException
    {
-     boolean isMultiGraphics = pg.length > 1;
-     int G0 = 0; // Graphic index of idPanel graphics in multi-graphics mode or
-                 // entire graphics for non mulit-graphics mode
-     int G1 = 0; // Graphic index of alignmentPanel graphics for multi-graphics
-                 // mode
-     if (isMultiGraphics)
-     {
-       G0 = 0;
-       G1 = 1;
-     }
-     int idWidth = getVisibleIdWidth(false);
-     FontMetrics fm = getFontMetrics(av.getFont());
-     int scaleHeight = av.getCharHeight() + fm.getDescent();
-     pg[G0].setColor(Color.white);
-     pg[G0].fillRect(0, 0, pwidth, pheight);
-     pg[G0].setFont(av.getFont());
+     final int idWidth = getVisibleIdWidth(false);
  
-     // //////////////////////////////////
-     // / How many sequences and residues can we fit on a printable page?
-     int totalRes = (pwidth - idWidth) / av.getCharWidth();
+     /*
+      * Get the horizontal offset to where we draw the sequences.
+      * This is idWidth if using a single Graphics context, else zero.
+      */
+     final int alignmentGraphicsOffset = idGraphics != alignmentGraphics ? 0 : idWidth;
  
-     int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
+     FontMetrics fm = getFontMetrics(av.getFont());
+     int charHeight = av.getCharHeight();
+     int scaleHeight = charHeight + fm.getDescent();
  
-     int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
+     idGraphics.setColor(Color.white);
+     idGraphics.fillRect(0, 0, pageWidth, pageHeight);
+     idGraphics.setFont(av.getFont());
  
-     // ///////////////////////////
-     // / Only print these sequences and residues on this page
-     int startRes;
+     /*
+      * How many sequences and residues can we fit on a printable page?
+      */
+     int totalRes = (pageWidth - idWidth) / av.getCharWidth();
  
-     // ///////////////////////////
-     // / Only print these sequences and residues on this page
-     int endRes;
+     int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
  
-     // ///////////////////////////
-     // / Only print these sequences and residues on this page
-     int startSeq;
+     int alignmentWidth = av.getAlignment().getWidth();
+     int pagesWide = (alignmentWidth / totalRes) + 1;
  
-     // ///////////////////////////
-     // / Only print these sequences and residues on this page
-     int endSeq;
-     startRes = (pi % pagesWide) * totalRes;
-     endRes = (startRes + totalRes) - 1;
+     final int startRes = (pi % pagesWide) * totalRes;
+     int endRes = (startRes + totalRes) - 1;
  
-     if (endRes > (av.getAlignment().getWidth() - 1))
+     if (endRes > (alignmentWidth - 1))
      {
-       endRes = av.getAlignment().getWidth() - 1;
+       endRes = alignmentWidth - 1;
      }
  
-     startSeq = (pi / pagesWide) * totalSeq;
-     endSeq = startSeq + totalSeq;
+     final int startSeq = (pi / pagesWide) * totalSeq;
+     int endSeq = startSeq + totalSeq;
  
-     if (endSeq > av.getAlignment().getHeight())
+     int alignmentHeight = av.getAlignment().getHeight();
+     if (endSeq > alignmentHeight)
      {
-       endSeq = av.getAlignment().getHeight();
+       endSeq = alignmentHeight;
      }
  
-     int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1)
-             * pheight;
+     int pagesHigh = ((alignmentHeight / totalSeq) + 1)
+             * pageHeight;
  
      if (av.isShowAnnotation())
      {
        pagesHigh += getAnnotationPanel().adjustPanelHeight() + 3;
      }
  
-     pagesHigh /= pheight;
+     pagesHigh /= pageHeight;
  
      if (pi >= (pagesWide * pagesHigh))
      {
        return Printable.NO_SUCH_PAGE;
      }
+     final int alignmentDrawnHeight = (endSeq - startSeq) * charHeight
+             + 3;
  
-     // draw Scale
-     if (isMultiGraphics)
-     {
-       pg[G1].translate(0, 0);
-       getScalePanel().drawScale(pg[G1], startRes, endRes,
-               pwidth - idWidth, scaleHeight);
-       pg[G1].translate(-idWidth, scaleHeight);
-     }
-     else
-     {
-       pg[G0].translate(idWidth, 0);
-       getScalePanel().drawScale(pg[G0], startRes, endRes, pwidth - idWidth,
-               scaleHeight);
-       pg[G0].translate(-idWidth, scaleHeight);
-     }
+     /*
+      * draw the Scale at horizontal offset, then reset to top left (0, 0)
+      */
+     alignmentGraphics.translate(alignmentGraphicsOffset, 0);
+     getScalePanel().drawScale(alignmentGraphics, startRes, endRes,
+             pageWidth - idWidth, scaleHeight);
+     alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
  
-     // //////////////
-     // Draw the ids
+     /*
+      * Draw the sequence ids, offset for scale height,
+      * then reset to top left (0, 0)
+      */
+     idGraphics.translate(0, scaleHeight);
+     idGraphics.setFont(getIdPanel().getIdCanvas().getIdfont());
      Color currentColor = null;
      Color currentTextColor = null;
  
-     if (isMultiGraphics)
-     {
-       pg[G0].translate(0, scaleHeight);
-     }
-     pg[G0].setFont(getIdPanel().getIdCanvas().getIdfont());
      SequenceI seq;
      for (int i = startSeq; i < endSeq; i++)
      {
        if ((av.getSelectionGroup() != null)
                && av.getSelectionGroup().getSequences(null).contains(seq))
        {
+         /*
+          * gray out ids of sequences in selection group (if any)
+          */
          currentColor = Color.gray;
          currentTextColor = Color.black;
        }
          currentTextColor = Color.black;
        }
  
-       pg[G0].setColor(currentColor);
-       pg[G0].fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth,
-               av.getCharHeight());
+       idGraphics.setColor(currentColor);
+       idGraphics.fillRect(0, (i - startSeq) * charHeight, idWidth,
+               charHeight);
  
-       pg[G0].setColor(currentTextColor);
+       idGraphics.setColor(currentTextColor);
  
        int xPos = 0;
+       String displayId = seq.getDisplayId(av.getShowJVSuffix());
        if (av.isRightAlignIds())
        {
-         fm = pg[G0].getFontMetrics();
+         fm = idGraphics.getFontMetrics();
          xPos = idWidth
-                 - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix()))
+                 - fm.stringWidth(displayId)
                  - 4;
        }
  
-       pg[G0].drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos,
-               (((i - startSeq) * av.getCharHeight()) + av.getCharHeight())
-                       - (av.getCharHeight() / 5));
+       idGraphics.drawString(displayId, xPos,
+               (((i - startSeq) * charHeight) + charHeight)
+                       - (charHeight / 5));
      }
+     idGraphics.setFont(av.getFont());
+     idGraphics.translate(0, -scaleHeight);
  
-     pg[G0].setFont(av.getFont());
+     /*
+      * draw the sequences, offset for scale height, and id width (if using a
+      * single graphics context), then reset to (0, scale height)
+      */
+     alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
+     getSeqPanel().seqCanvas.drawPanel(alignmentGraphics, startRes, endRes,
+             startSeq, endSeq, 0);
+     alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
  
-     // draw main sequence panel
-     pg[G0].translate(idWidth, 0);
-     if (isMultiGraphics)
+     if (av.isShowAnnotation() && (endSeq == alignmentHeight))
      {
-       pg[G1].translate(idWidth, 0);
-       getSeqPanel().seqCanvas.drawPanel(pg[G1], startRes, endRes,
-               startSeq, endSeq, 0);
-     }
-     else
-     {
-       getSeqPanel().seqCanvas.drawPanel(pg[G0], startRes, endRes, startSeq,
-               endSeq, 0);
-     }
+       /*
+        * draw annotation labels; drawComponent() translates by
+        * getScrollOffset(), so compensate for that first;
+        * then reset to (0, scale height)
+        */
+       int offset = getAlabels().getScrollOffset();
+       idGraphics.translate(0, -offset);
+       idGraphics.translate(0, alignmentDrawnHeight);
+       getAlabels().drawComponent(idGraphics, idWidth);
+       idGraphics.translate(0, -alignmentDrawnHeight);
  
-     if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight()))
-     {
-       // draw annotation label - need to offset for current scroll position
-       int offset = -getAlabels().getScrollOffset();
-       pg[G0].translate(0, offset);
-       pg[G0].translate(-idWidth - 3,
-               (endSeq - startSeq) * av.getCharHeight() + 3);
-       getAlabels().drawComponent(pg[G0], idWidth);
-       pg[G0].translate(idWidth + 3, 0);
-       pg[G0].translate(0, -offset);
-       if (isMultiGraphics)
-       {
-         // draw annotation - need to offset for current scroll position
-         // pg[G1].translate(0, offset);
-         pg[G1].translate(-idWidth - 3,
-                 (endSeq - startSeq) * av.getCharHeight() + 3);
-         pg[G1].translate(idWidth + 3, 0);
-         getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(),
-                 av, pg[G1], -1, startRes, endRes + 1);
-         pg[G1].translate(0, -offset);
-       }
-       else
-       {
-         getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(),
-                 av, pg[G0], -1, startRes, endRes + 1);
-         pg[G0].translate(0, -offset);
-       }
+       /*
+        * draw the annotations starting at 
+        * (idOffset, alignmentHeight) from (0, scaleHeight)
+        */
+       alignmentGraphics.translate(alignmentGraphicsOffset, alignmentDrawnHeight);
+       getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av,
+               alignmentGraphics, -1, startRes, endRes + 1);
      }
  
      return Printable.PAGE_EXISTS;
                  aDimension.getWidth(), aDimension.getHeight()
                          + boarderBottomOffset, file, imageTitle,
                  alignFrame, pSessionId, headless);
+         Graphics graphics = im.getGraphics();
          if (av.getWrapAlignment())
          {
-           if (im.getGraphics() != null)
+           if (graphics != null)
            {
              printWrappedAlignment(aDimension.getWidth(),
                      aDimension.getHeight() + boarderBottomOffset, 0,
-                     im.getGraphics());
+                     graphics);
              im.writeImage();
            }
          }
          else
          {
-           if (im.getGraphics() != null)
+           if (graphics != null)
            {
              printUnwrapped(aDimension.getWidth(), aDimension.getHeight(),
-                     0, im.getGraphics());
+                     0, graphics, graphics);
              im.writeImage();
            }
          }
     * @param verticalOffset
     *          the number of visible sequences to show above the mapped region
     */
 -  public void scrollToCentre(SearchResults sr, int verticalOffset)
 +  public void scrollToCentre(SearchResultsI sr, int verticalOffset)
    {
      /*
       * To avoid jumpy vertical scrolling (if some sequences are gapped or not
       * mapped), we can make the scroll-to location a sequence above the one
       * actually mapped.
       */
 -    SequenceI mappedTo = sr.getResultSequence(0);
 +    SequenceI mappedTo = sr.getResults().get(0).getSequence();
      List<SequenceI> seqs = av.getAlignment().getSequences();
  
      /*
@@@ -20,7 -20,6 +20,7 @@@
   */
  package jalview.io;
  
 +import jalview.exceptions.NoFileSelectedException;
  import jalview.gui.AlignmentPanel;
  import jalview.gui.HTMLOptions;
  import jalview.gui.OOMWarning;
@@@ -39,6 -38,7 +39,6 @@@ import org.jfree.graphics2d.svg.SVGHint
  public class HtmlSvgOutput extends HTMLOutput
  {
  
 -  private File generatedFile;
  
    public HtmlSvgOutput(AlignmentPanel ap)
    {
    }
  
    @Override
 -  public void exportHTML(String file)
 +  public void exportHTML(String outputFile)
    {
      exportStarted();
      try
      {
 -      if (file == null)
 +      if (outputFile == null)
        {
 -        file = getOutputFile();
 +        outputFile = getOutputFile();
        }
 -      generatedFile = new File(file);
 +      generatedFile = new File(outputFile);
 +    } catch (NoFileSelectedException e)
 +    {
 +      setProgressMessage(MessageManager.formatMessage(
 +              "status.cancelled_image_export_operation", "HTML"));
 +      return;
      } catch (Exception e)
      {
        setProgressMessage(MessageManager.formatMessage(
        e.printStackTrace();
        return;
      }
 -    new Thread()
 -    {
 -      @Override
 -      public void run()
 -      {
 -        try
 -        {
 -          setProgressMessage(null);
 -          setProgressMessage(MessageManager.formatMessage(
 -                  "status.exporting_alignment_as_x_file", "HTML"));
 -          AlignmentDimension aDimension = ap.getAlignmentDimension();
 -          SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
 -                  aDimension.getWidth(),
 -                  aDimension.getHeight());
 -          SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
 -                  aDimension.getWidth(),
 -                  aDimension.getHeight());
 -
 -          String renderStyle = jalview.bin.Cache.getDefault(
 -                  "HTML_RENDERING", "Prompt each time");
 -
 -          // If we need to prompt, and if the GUI is visible then
 -          // Prompt for rendering style
 -          if (renderStyle.equalsIgnoreCase("Prompt each time")
 -                  && !isHeadless())
 -          {
 -            HTMLOptions svgOption = new HTMLOptions();
 -            renderStyle = svgOption.getValue();
 -
 -            if (renderStyle == null || svgOption.cancelled)
 -            {
 -              setProgressMessage(MessageManager.formatMessage(
 -                      "status.cancelled_image_export_operation", "HTML"));
 -              return;
 -            }
 -          }
 -
 -          if (renderStyle.equalsIgnoreCase("Lineart"))
 -          {
 -            idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
 -                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
 -            alignPanelGraphics.setRenderingHint(
 -                    SVGHints.KEY_DRAW_STRING_TYPE,
 -                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
 -          }
 -          if (ap.av.getWrapAlignment())
 -          {
 -            printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
 -                    alignPanelGraphics);
 -          }
 -          else
 -          {
 -          printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
 - idPanelGraphics, alignPanelGraphics);
 -          }
 -
 -          String idPanelSvgData = idPanelGraphics.getSVGDocument();
 -          String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
 -          String jsonData = getBioJSONData();
 -          String htmlData = getHtml(idPanelSvgData, alignPanelSvgData, jsonData,
 - ap.av.getWrapAlignment());
 -          FileOutputStream out = new FileOutputStream(generatedFile);
 -          out.write(htmlData.getBytes());
 -          out.flush();
 -          out.close();
 -          exportCompleted();
 -        } catch (OutOfMemoryError err)
 -        {
 -          System.out.println("########################\n"
 -                  + "OUT OF MEMORY " + generatedFile + "\n"
 -                  + "########################");
 -          new OOMWarning("Creating Image for " + generatedFile, err);
 -        } catch (Exception e)
 -        {
 -          e.printStackTrace();
 -          setProgressMessage(MessageManager.formatMessage(
 -                  "info.error_creating_file", "HTML"));
 -        }
 -        setProgressMessage(MessageManager.formatMessage(
 -                "status.export_complete", "HTML"));
 -      }
 -    }.start();
 -
 +    new Thread(this).start();
    }
  
  
              "Hypertext Markup Language");
    }
  
-   public int printUnwrapped(int pwidth, int pheight, int pi, Graphics... pg)
+   public int printUnwrapped(int pwidth, int pheight, int pi,
+           Graphics idGraphics, Graphics alignmentGraphics)
            throws PrinterException
    {
-     return ap.printUnwrapped(pwidth, pheight, pi, pg);
+     return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
+             alignmentGraphics);
    }
  
    public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
                .append(alignmentSvg).append("</div>");
        htmlSvg.append("<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
                + "<script language=\"JavaScript\" type=\"text/javascript\"  src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
      }
  
      // javascript for launching file in Jalview
 -
      htmlSvg.append("<script language=\"JavaScript\">\n");
      htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
      htmlSvg.append("    var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
      htmlSvg.append("    document.body.removeChild(myForm);\n");
      htmlSvg.append("}\n");
  
 -    // jquery facebox for displaying raw BioJSON data");
      if (jsonData != null)
      {
 +      // JQuery FaceBox for displaying raw BioJSON data");
        File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
        try
        {
    {
      return generatedFile;
    }
 +
 +  @Override
 +  public void run()
 +  {
 +    try
 +    {
 +      setProgressMessage(null);
 +      setProgressMessage(MessageManager.formatMessage(
 +              "status.exporting_alignment_as_x_file", "HTML"));
 +      AlignmentDimension aDimension = ap.getAlignmentDimension();
 +      SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
 +              aDimension.getWidth(), aDimension.getHeight());
 +      SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
 +              aDimension.getWidth(), aDimension.getHeight());
 +
 +      String renderStyle = jalview.bin.Cache.getDefault("HTML_RENDERING",
 +              "Prompt each time");
 +
 +      // If we need to prompt, and if the GUI is visible then
 +      // Prompt for rendering style
 +      if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
 +      {
 +        HTMLOptions svgOption = new HTMLOptions();
 +        renderStyle = svgOption.getValue();
 +
 +        if (renderStyle == null || svgOption.cancelled)
 +        {
 +          setProgressMessage(MessageManager.formatMessage(
 +                  "status.cancelled_image_export_operation", "HTML"));
 +          return;
 +        }
 +      }
 +
 +      if (renderStyle.equalsIgnoreCase("Lineart"))
 +      {
 +        idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
 +                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
 +        alignPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
 +                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
 +      }
 +      if (ap.av.getWrapAlignment())
 +      {
 +        printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
 +                alignPanelGraphics);
 +      }
 +      else
 +      {
 +        printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
 +                idPanelGraphics, alignPanelGraphics);
 +      }
 +
 +      String idPanelSvgData = idPanelGraphics.getSVGDocument();
 +      String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
 +      String jsonData = getBioJSONData();
 +      String htmlData = getHtml(idPanelSvgData, alignPanelSvgData,
 +              jsonData, ap.av.getWrapAlignment());
 +      FileOutputStream out = new FileOutputStream(generatedFile);
 +      out.write(htmlData.getBytes());
 +      out.flush();
 +      out.close();
 +      setProgressMessage(MessageManager.formatMessage(
 +              "status.export_complete", "HTML"));
 +      exportCompleted();
 +    } catch (OutOfMemoryError err)
 +    {
 +      System.out.println("########################\n" + "OUT OF MEMORY "
 +              + generatedFile + "\n" + "########################");
 +      new OOMWarning("Creating Image for " + generatedFile, err);
 +    } catch (Exception e)
 +    {
 +      e.printStackTrace();
 +      setProgressMessage(MessageManager.formatMessage(
 +              "info.error_creating_file", "HTML"));
 +    }
 +  }
  }