From a8362b85de4f21440433bc9385bd9b3a24354532 Mon Sep 17 00:00:00 2001 From: tcofoegbu Date: Fri, 11 Nov 2016 17:23:24 +0000 Subject: [PATCH] JAL-2277 Refactored out duplicated method - printUnwrapped() in HtmlSvgOutput, externalised facebox script, and made other minor housekeepings --- THIRDPARTYLIBS | 1 + examples/javascript/facebox-1.3.js | 309 ++++++++++++++++++++++ src/jalview/bin/Jalview.java | 4 +- src/jalview/gui/AlignFrame.java | 3 +- src/jalview/gui/AlignmentPanel.java | 122 ++++++--- src/jalview/io/BioJsHTMLOutput.java | 42 +-- src/jalview/io/HtmlFile.java | 53 ++++ src/jalview/io/HtmlSvgOutput.java | 422 ++---------------------------- test/jalview/io/BioJsHTMLOutputTest.java | 3 +- 9 files changed, 482 insertions(+), 477 deletions(-) create mode 100644 examples/javascript/facebox-1.3.js diff --git a/THIRDPARTYLIBS b/THIRDPARTYLIBS index 31ad2f5..7d12783 100644 --- a/THIRDPARTYLIBS +++ b/THIRDPARTYLIBS @@ -58,4 +58,5 @@ Additional dependencies examples/javascript/deployJava.js : http://java.com/js/deployJava.js examples/javascript/jquery*.js : BSD license examples/javascript/jshashtable-2.1.js : Apache License +examples/javascript/facebox-1.3.js : MTI License - http://www.opensource.org/licenses/mit-license.php diff --git a/examples/javascript/facebox-1.3.js b/examples/javascript/facebox-1.3.js new file mode 100644 index 0000000..ad45310 --- /dev/null +++ b/examples/javascript/facebox-1.3.js @@ -0,0 +1,309 @@ +/* + * Facebox (for jQuery) + * version: 1.2 (05/05/2008) + * @requires jQuery v1.2 or later + * + * Examples at http://famspam.com/facebox/ + * + * Licensed under the MIT: + * http://www.opensource.org/licenses/mit-license.php + * + * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ] + * + * Usage: + * + * jQuery(document).ready(function() { + * jQuery('a[rel*=facebox]').facebox() + * }) + * + * Terms + * Loads the #terms div in the box + * + * Terms + * Loads the terms.html page in the box + * + * Terms + * Loads the terms.png image in the box + * + * + * You can also use it programmatically: + * + * jQuery.facebox('some html') + * jQuery.facebox('some html', 'my-groovy-style') + * + * The above will open a facebox with "some html" as the content. + * + * jQuery.facebox(function($) { + * $.get('blah.html', function(data) { $.facebox(data) }) + * }) + * + * The above will show a loading screen before the passed function is called, + * allowing for a better ajaxy experience. + * + * The facebox function can also display an ajax page, an image, or the contents of a div: + * + * jQuery.facebox({ ajax: 'remote.html' }) + * jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style') + * jQuery.facebox({ image: 'stairs.jpg' }) + * jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style') + * jQuery.facebox({ div: '#box' }) + * jQuery.facebox({ div: '#box' }, 'my-groovy-style') + * + * Want to close the facebox? Trigger the 'close.facebox' document event: + * + * jQuery(document).trigger('close.facebox') + * + * Facebox also has a bunch of other hooks: + * + * loading.facebox + * beforeReveal.facebox + * reveal.facebox (aliased as 'afterReveal.facebox') + * init.facebox + * afterClose.facebox + * + * Simply bind a function to any of these hooks: + * + * $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... }) + * + */ +(function($) { + $.facebox = function(data, klass) { + $.facebox.loading() + + if (data.ajax) fillFaceboxFromAjax(data.ajax, klass) + else if (data.image) fillFaceboxFromImage(data.image, klass) + else if (data.div) fillFaceboxFromHref(data.div, klass) + else if ($.isFunction(data)) data.call($) + else $.facebox.reveal(data, klass) + } + + /* + * Public, $.facebox methods + */ + + $.extend($.facebox, { + settings: { + opacity : 0.2, + overlay : true, + loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif', + closeImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png', + imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ], + faceboxHtml : '\ + ' + }, + + loading: function() { + init() + if ($('#facebox .loading').length == 1) return true + showOverlay() + + $('#facebox .content').empty() + $('#facebox .body').children().hide().end(). + append('
') + + $('#facebox').css({ + top: getPageScroll()[1] + (getPageHeight() / 10), + left: $(window).width() / 2 - 205 + }).show() + + $(document).bind('keydown.facebox', function(e) { + if (e.keyCode == 27) $.facebox.close() + return true + }) + $(document).trigger('loading.facebox') + }, + + reveal: function(data, klass) { + $(document).trigger('beforeReveal.facebox') + if (klass) $('#facebox .content').addClass(klass) + $('#facebox .content').append('
'+JSON.stringify(JSON.parse(data),null,4)+'
') + $('#facebox .loading').remove() + $('#facebox .body').children().fadeIn('normal') + $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').width() / 2)) + $(document).trigger('reveal.facebox').trigger('afterReveal.facebox') + }, + + close: function() { + $(document).trigger('close.facebox') + return false + } + }) + + /* + * Public, $.fn methods + */ + + $.fn.facebox = function(settings) { + if ($(this).length == 0) return + + init(settings) + + function clickHandler() { + $.facebox.loading(true) + + // support for rel="facebox.inline_popup" syntax, to add a class + // also supports deprecated "facebox[.inline_popup]" syntax + var klass = this.rel.match(/facebox\[?\.(\w+)\]?/) + if (klass) klass = klass[1] + + fillFaceboxFromHref(this.href, klass) + return false + } + + return this.bind('click.facebox', clickHandler) + } + + /* + * Private methods + */ + + // called one time to setup facebox on this page + function init(settings) { + if ($.facebox.settings.inited) return true + else $.facebox.settings.inited = true + + $(document).trigger('init.facebox') + makeCompatible() + + var imageTypes = $.facebox.settings.imageTypes.join('|') + $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i') + + if (settings) $.extend($.facebox.settings, settings) + $('body').append($.facebox.settings.faceboxHtml) + + var preload = [ new Image(), new Image() ] + preload[0].src = $.facebox.settings.closeImage + preload[1].src = $.facebox.settings.loadingImage + + $('#facebox').find('.b:first, .bl').each(function() { + preload.push(new Image()) + preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1') + }) + + $('#facebox .close').click($.facebox.close) + $('#facebox .close_image').attr('src', $.facebox.settings.closeImage) + } + + // getPageScroll() by quirksmode.com + function getPageScroll() { + var xScroll, yScroll; + if (self.pageYOffset) { + yScroll = self.pageYOffset; + xScroll = self.pageXOffset; + } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict + yScroll = document.documentElement.scrollTop; + xScroll = document.documentElement.scrollLeft; + } else if (document.body) {// all other Explorers + yScroll = document.body.scrollTop; + xScroll = document.body.scrollLeft; + } + return new Array(xScroll,yScroll) + } + + // Adapted from getPageSize() by quirksmode.com + function getPageHeight() { + var windowHeight + if (self.innerHeight) { // all except Explorer + windowHeight = self.innerHeight; + } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode + windowHeight = document.documentElement.clientHeight; + } else if (document.body) { // other Explorers + windowHeight = document.body.clientHeight; + } + return windowHeight + } + + // Backwards compatibility + function makeCompatible() { + var $s = $.facebox.settings + + $s.loadingImage = $s.loading_image || $s.loadingImage + $s.closeImage = $s.close_image || $s.closeImage + $s.imageTypes = $s.image_types || $s.imageTypes + $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml + } + + // Figures out what you want to display and displays it + // formats are: + // div: #id + // image: blah.extension + // ajax: anything else + function fillFaceboxFromHref(href, klass) { + // div + if (href.match(/#/)) { + var url = window.location.href.split('#')[0] + var target = href.replace(url,'') + if (target == '#') return + $.facebox.reveal($(target).html(), klass) + + // image + } else if (href.match($.facebox.settings.imageTypesRegexp)) { + fillFaceboxFromImage(href, klass) + // ajax + } else { + fillFaceboxFromAjax(href, klass) + } + } + + function fillFaceboxFromImage(href, klass) { + var image = new Image() + image.onload = function() { + $.facebox.reveal('
', klass) + } + image.src = href + } + + function fillFaceboxFromAjax(href, klass) { + $.get(href, function(data) { $.facebox.reveal(data, klass) }) + } + + function skipOverlay() { + return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null + } + + function showOverlay() { + if (skipOverlay()) return + + if ($('#facebox_overlay').length == 0) + $("body").append('
') + + $('#facebox_overlay').hide().addClass("facebox_overlayBG") + .css('opacity', $.facebox.settings.opacity) + .click(function() { $(document).trigger('close.facebox') }) + .fadeIn(200) + return false + } + + function hideOverlay() { + if (skipOverlay()) return + + $('#facebox_overlay').fadeOut(200, function(){ + $("#facebox_overlay").removeClass("facebox_overlayBG") + $("#facebox_overlay").addClass("facebox_hide") + $("#facebox_overlay").remove() + }) + + return false + } + + /* + * Bindings + */ + + $(document).bind('close.facebox', function() { + $(document).unbind('keydown.facebox') + $('#facebox').fadeOut(function() { + $('#facebox .content').removeClass().addClass('content') + $('#facebox .loading').remove() + $(document).trigger('afterClose.facebox') + }) + hideOverlay() + }) + +})(jQuery); diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 164ba27..d0cabb2 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -650,7 +650,9 @@ public class Jalview { File imageFile = new File(file); imageName = imageFile.getName(); - new HtmlSvgOutput(new File(file), af.alignPanel); + HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel); + htmlSVG.generateHtmlSvgOutput(new File(file)); + System.out.println("Creating HTML image: " + file); continue; } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 20fa657..834e561 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -1341,7 +1341,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void htmlMenuItem_actionPerformed(ActionEvent e) { - new HtmlSvgOutput(null, alignPanel); + HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel); + htmlSVG.generateHtmlSvgOutput(null); } @Override diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 4db029c..9f1162f 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -956,11 +956,11 @@ public class AlignmentPanel extends GAlignmentPanel implements if (av.getWrapAlignment()) { - return printWrappedAlignment(pg, pwidth, pheight, pi); + return printWrappedAlignment(pwidth, pheight, pi, pg); } else { - return printUnwrapped(pg, pwidth, pheight, pi); + return printUnwrapped(pwidth, pheight, pi, pg); } } @@ -981,16 +981,28 @@ public class AlignmentPanel extends GAlignmentPanel implements * @throws PrinterException * DOCUMENT ME! */ - public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi) + public int printUnwrapped(int pwidth, int pheight, int pi, + Graphics... pg) 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.setColor(Color.white); - pg.fillRect(0, 0, pwidth, pheight); - pg.setFont(av.getFont()); + pg[G0].setColor(Color.white); + pg[G0].fillRect(0, 0, pwidth, pheight); + pg[G0].setFont(av.getFont()); // ////////////////////////////////// // / How many sequences and residues can we fit on a printable page? @@ -1047,17 +1059,31 @@ public class AlignmentPanel extends GAlignmentPanel implements } // draw Scale - pg.translate(idWidth, 0); - getScalePanel().drawScale(pg, startRes, endRes, pwidth - idWidth, - scaleHeight); - pg.translate(-idWidth, scaleHeight); + 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 ids Color currentColor = null; Color currentTextColor = null; - pg.setFont(getIdPanel().getIdCanvas().getIdfont()); + if (isMultiGraphics) + { + pg[G0].translate(0, scaleHeight); + } + pg[G0].setFont(getIdPanel().getIdCanvas().getIdfont()); SequenceI seq; for (int i = startSeq; i < endSeq; i++) @@ -1075,45 +1101,70 @@ public class AlignmentPanel extends GAlignmentPanel implements currentTextColor = Color.black; } - pg.setColor(currentColor); - pg.fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth, + pg[G0].setColor(currentColor); + pg[G0].fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth, av.getCharHeight()); - pg.setColor(currentTextColor); + pg[G0].setColor(currentTextColor); int xPos = 0; if (av.isRightAlignIds()) { - fm = pg.getFontMetrics(); + fm = pg[G0].getFontMetrics(); xPos = idWidth - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix())) - 4; } - pg.drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos, + pg[G0].drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos, (((i - startSeq) * av.getCharHeight()) + av.getCharHeight()) - (av.getCharHeight() / 5)); } - pg.setFont(av.getFont()); + pg[G0].setFont(av.getFont()); + // draw main sequence panel - pg.translate(idWidth, 0); - getSeqPanel().seqCanvas.drawPanel(pg, startRes, endRes, startSeq, - endSeq, 0); + pg[G0].translate(idWidth, 0); + if (isMultiGraphics) + { + 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); + } if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight())) { - // draw annotation - need to offset for current scroll position + // draw annotation label - need to offset for current scroll position int offset = -getAlabels().getScrollOffset(); - pg.translate(0, offset); - pg.translate(-idWidth - 3, (endSeq - startSeq) * av.getCharHeight() - + 3); - getAlabels().drawComponent(pg, idWidth); - pg.translate(idWidth + 3, 0); - getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av, - pg, -1, startRes, endRes + 1); - pg.translate(0, -offset); + 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); + } } return Printable.PAGE_EXISTS; @@ -1136,8 +1187,8 @@ public class AlignmentPanel extends GAlignmentPanel implements * @throws PrinterException * DOCUMENT ME! */ - public int printWrappedAlignment(Graphics pg, int pwidth, int pheight, - int pi) throws PrinterException + public int printWrappedAlignment(int pwidth, int pheight, int pi, + Graphics pg) throws PrinterException { int annotationHeight = 0; AnnotationLabels labels = null; @@ -1316,8 +1367,9 @@ public class AlignmentPanel extends GAlignmentPanel implements { if (im.getGraphics() != null) { - printWrappedAlignment(im.getGraphics(), aDimension.getWidth(), - aDimension.getHeight() + boarderBottomOffset, 0); + printWrappedAlignment(aDimension.getWidth(), + aDimension.getHeight() + boarderBottomOffset, 0, + im.getGraphics()); im.writeImage(); } } @@ -1325,8 +1377,8 @@ public class AlignmentPanel extends GAlignmentPanel implements { if (im.getGraphics() != null) { - printUnwrapped(im.getGraphics(), aDimension.getWidth(), - aDimension.getHeight(), 0); + printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), + 0, im.getGraphics()); im.writeImage(); } } diff --git a/src/jalview/io/BioJsHTMLOutput.java b/src/jalview/io/BioJsHTMLOutput.java index 817f75c..9b6a15a 100644 --- a/src/jalview/io/BioJsHTMLOutput.java +++ b/src/jalview/io/BioJsHTMLOutput.java @@ -137,7 +137,7 @@ public class BioJsHTMLOutput exportData.getStartEndPostions(), ap .getAlignViewport().getColumnSelection()); - String bioJSTemplateString = getBioJsTemplateAsString(); + String bioJSTemplateString = HtmlFile.readFileAsString(getCurrentBJSTemplateFile()); String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString .replaceAll("#sequenceData#", bioJSON).toString(); @@ -208,46 +208,6 @@ public class BioJsHTMLOutput return selectedFile; } - public static String getBioJsTemplateAsString() throws IOException - { - InputStreamReader isReader = null; - BufferedReader buffReader = null; - StringBuilder sb = new StringBuilder(); - Objects.requireNonNull(getCurrentBJSTemplateFile(), - "BioJsTemplate File not initialized!"); - @SuppressWarnings("deprecation") - URL url = getCurrentBJSTemplateFile().toURL(); - if (url != null) - { - try - { - isReader = new InputStreamReader(url.openStream()); - buffReader = new BufferedReader(isReader); - String line; - String lineSeparator = System.getProperty("line.separator"); - while ((line = buffReader.readLine()) != null) - { - sb.append(line).append(lineSeparator); - } - - } catch (Exception ex) - { - ex.printStackTrace(); - } finally - { - if (isReader != null) - { - isReader.close(); - } - - if (buffReader != null) - { - buffReader.close(); - } - } - } - return sb.toString(); - } public static void refreshBioJSVersionsInfo(String dirName) throws URISyntaxException diff --git a/src/jalview/io/HtmlFile.java b/src/jalview/io/HtmlFile.java index e31e78d..d19a203 100644 --- a/src/jalview/io/HtmlFile.java +++ b/src/jalview/io/HtmlFile.java @@ -27,8 +27,13 @@ import jalview.api.FeaturesDisplayedI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SequenceI; +import java.io.BufferedReader; +import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; import java.io.StringReader; +import java.net.URL; +import java.util.Objects; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -190,4 +195,52 @@ public class HtmlFile extends AlignFile implements ComplexAlignFile return new PDBFeatureSettings(); } + /** + * Read a template file content as string + * + * @param file + * - the file to be read + * @return File content as String + * @throws IOException + */ + public static String readFileAsString(File file) throws IOException + { + InputStreamReader isReader = null; + BufferedReader buffReader = null; + StringBuilder sb = new StringBuilder(); + Objects.requireNonNull(file, "File must not be null!"); + @SuppressWarnings("deprecation") + URL url = file.toURL(); + if (url != null) + { + try + { + isReader = new InputStreamReader(url.openStream()); + buffReader = new BufferedReader(isReader); + String line; + String lineSeparator = System.getProperty("line.separator"); + while ((line = buffReader.readLine()) != null) + { + sb.append(line).append(lineSeparator); + } + + } catch (Exception ex) + { + ex.printStackTrace(); + } finally + { + if (isReader != null) + { + isReader.close(); + } + + if (buffReader != null) + { + buffReader.close(); + } + } + } + return sb.toString(); + } + } diff --git a/src/jalview/io/HtmlSvgOutput.java b/src/jalview/io/HtmlSvgOutput.java index decb06f..e6e698c 100644 --- a/src/jalview/io/HtmlSvgOutput.java +++ b/src/jalview/io/HtmlSvgOutput.java @@ -23,7 +23,6 @@ package jalview.io; import jalview.api.AlignExportSettingI; import jalview.api.FeatureRenderer; import jalview.datamodel.AlignmentExportData; -import jalview.datamodel.SequenceI; import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; import jalview.gui.HTMLOptions; @@ -32,13 +31,11 @@ import jalview.gui.OOMWarning; import jalview.math.AlignmentDimension; import jalview.util.MessageManager; -import java.awt.Color; -import java.awt.FontMetrics; import java.awt.Graphics; -import java.awt.print.Printable; import java.awt.print.PrinterException; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import org.jfree.graphics2d.svg.SVGGraphics2D; import org.jfree.graphics2d.svg.SVGHints; @@ -57,12 +54,11 @@ public class HtmlSvgOutput private boolean headless; - public HtmlSvgOutput(File file, AlignmentPanel ap) + public HtmlSvgOutput(AlignmentPanel ap) { this.av = ap.av; this.ap = ap; fr = ap.cloneFeatureRenderer(); - generateHtmlSvgOutput(file); } public void generateHtmlSvgOutput(File file) @@ -116,9 +112,11 @@ public class HtmlSvgOutput setProgressMessage(MessageManager.formatMessage( "status.exporting_alignment_as_x_file", "HTML")); AlignmentDimension aDimension = ap.getAlignmentDimension(); - SVGGraphics2D g1 = new SVGGraphics2D(aDimension.getWidth(), + SVGGraphics2D idPanelGraphics = new SVGGraphics2D( + aDimension.getWidth(), aDimension.getHeight()); - SVGGraphics2D g2 = new SVGGraphics2D(aDimension.getWidth(), + SVGGraphics2D alignPanelGraphics = new SVGGraphics2D( + aDimension.getWidth(), aDimension.getHeight()); String renderStyle = jalview.bin.Cache.getDefault( @@ -143,24 +141,25 @@ public class HtmlSvgOutput if (renderStyle.equalsIgnoreCase("Lineart")) { - g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, + idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); - g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, + alignPanelGraphics.setRenderingHint( + SVGHints.KEY_DRAW_STRING_TYPE, SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); } if (av.getWrapAlignment()) { printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0, - g1, g2); + alignPanelGraphics); } else { printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, - g1, g2); + idPanelGraphics, alignPanelGraphics); } - String titleSvgData = g1.getSVGDocument(); - String alignSvgData = g2.getSVGDocument(); + String idPanelSvgData = idPanelGraphics.getSVGDocument(); + String alignPanelSvgData = alignPanelGraphics.getSVGDocument(); String jsonData = null; boolean isEmbbedBioJSON = Boolean.valueOf(jalview.bin.Cache .getDefault("EXPORT_EMBBED_BIOJSON", "true")); @@ -215,7 +214,7 @@ public class HtmlSvgOutput exportData.getStartEndPostions(), av.getColumnSelection()); } - String htmlData = getHtml(titleSvgData, alignSvgData, jsonData, + String htmlData = getHtml(idPanelSvgData, alignPanelSvgData, jsonData, av.getWrapAlignment()); FileOutputStream out = new FileOutputStream(fileX); out.write(htmlData.getBytes()); @@ -269,138 +268,13 @@ public class HtmlSvgOutput public int printUnwrapped(int pwidth, int pheight, int pi, Graphics... pg) throws PrinterException { - int idWidth = ap.getVisibleIdWidth(false); - FontMetrics fm = ap.getFontMetrics(av.getFont()); - int scaleHeight = av.getCharHeight() + fm.getDescent(); - - pg[0].setColor(Color.white); - pg[0].fillRect(0, 0, pwidth, pheight); - pg[0].setFont(av.getFont()); - - // ////////////////////////////////// - // / How many sequences and residues can we fit on a printable page? - int totalRes = (pwidth - idWidth) / av.getCharWidth(); - int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1; - int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1; - - // /////////////////////////// - // / Only print these sequences and residues on this page - int startRes; - - // /////////////////////////// - // / Only print these sequences and residues on this page - int endRes; - - // /////////////////////////// - // / Only print these sequences and residues on this page - int startSeq; - - // /////////////////////////// - // / Only print these sequences and residues on this page - int endSeq; - startRes = (pi % pagesWide) * totalRes; - endRes = (startRes + totalRes) - 1; - - if (endRes > (av.getAlignment().getWidth() - 1)) - { - endRes = av.getAlignment().getWidth() - 1; - } - startSeq = (pi / pagesWide) * totalSeq; - endSeq = startSeq + totalSeq; - if (endSeq > av.getAlignment().getHeight()) - { - endSeq = av.getAlignment().getHeight(); - } - int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1) - * pheight; - if (av.isShowAnnotation()) - { - pagesHigh += ap.getAnnotationPanel().adjustPanelHeight() + 3; - } - pagesHigh /= pheight; - if (pi >= (pagesWide * pagesHigh)) - { - return Printable.NO_SUCH_PAGE; - } - - // draw Scale - pg[1].translate(0, 0); - ap.getScalePanel().drawScale(pg[1], startRes, endRes, pwidth - idWidth, - scaleHeight); - pg[1].translate(-idWidth, scaleHeight); - - // ////////////// - // Draw the ids - Color currentColor = null; - Color currentTextColor = null; - pg[0].translate(0, scaleHeight); - pg[0].setFont(ap.getIdPanel().getIdCanvas().getIdfont()); - SequenceI seq; - for (int i = startSeq; i < endSeq; i++) - { - seq = av.getAlignment().getSequenceAt(i); - if ((av.getSelectionGroup() != null) - && av.getSelectionGroup().getSequences(null).contains(seq)) - { - currentColor = Color.gray; - currentTextColor = Color.black; - } - else - { - currentColor = av.getSequenceColour(seq); - currentTextColor = Color.black; - } - pg[0].setColor(currentColor); - pg[0].fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth, - av.getCharHeight()); - pg[0].setColor(currentTextColor); - int xPos = 0; - if (av.isRightAlignIds()) - { - fm = pg[0].getFontMetrics(); - xPos = idWidth - - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix())) - - 4; - } - pg[0].drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos, - (((i - startSeq) * av.getCharHeight()) + av.getCharHeight()) - - (av.getCharHeight() / 5)); - } - pg[0].setFont(av.getFont()); - pg[0].translate(idWidth, 0); - - // draw main sequence panel - pg[1].translate(idWidth, 0); - ap.getSeqPanel().seqCanvas.drawPanel(pg[1], startRes, endRes, startSeq, - endSeq, 0); - if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight())) - { - // draw annotation label - need to offset for current scroll position - int offset = -ap.getAlabels().getScrollOffset(); - pg[0].translate(0, offset); - pg[0].translate(-idWidth - 3, - (endSeq - startSeq) * av.getCharHeight() + 3); - ap.getAlabels().drawComponent(pg[0], idWidth); - pg[0].translate(idWidth + 3, 0); - pg[0].translate(0, -offset); - - // draw annotation - need to offset for current scroll position - pg[1].translate(0, offset); - pg[1].translate(-idWidth - 3, - (endSeq - startSeq) * av.getCharHeight() + 3); - pg[1].translate(idWidth + 3, 0); - ap.getAnnotationPanel().renderer.drawComponent( - ap.getAnnotationPanel(), av, pg[1], -1, startRes, endRes + 1); - pg[1].translate(0, -offset); - } - - return Printable.PAGE_EXISTS; + return ap.printUnwrapped(pwidth, pheight, pi, pg); } public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg) throws PrinterException { - return ap.printWrappedAlignment(pg[1], pwidth, pheight, pi); + return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]); } private String getHtml(String titleSvg, String alignmentSvg, @@ -506,262 +380,14 @@ public class HtmlSvgOutput // jquery facebox for displaying raw BioJSON data"); if (jsonData != null) { - htmlSvg.append("/* Facebox (for jQuery)\n"); - htmlSvg.append("* version: 1.3\n"); - htmlSvg.append(" * @requires jQuery v1.2 or later\n"); - htmlSvg.append(" * @homepage https://github.com/defunkt/facebox\n"); - htmlSvg.append(" * Licensed under the MIT:\n"); - htmlSvg.append(" * http://www.opensource.org/licenses/mit-license.php\n"); - htmlSvg.append(" * Copyright Forever Chris Wanstrath, Kyle Neath\n"); - htmlSvg.append(" * Usage:\n"); - htmlSvg.append(" * jQuery(document).ready(function() {\n"); - htmlSvg.append(" * jQuery('a[rel*=facebox]').facebox()\n"); - htmlSvg.append(" * })\n"); - htmlSvg.append(" * Terms\n"); - htmlSvg.append(" * Loads the #terms div in the box\n"); - htmlSvg.append(" * Terms\n"); - htmlSvg.append(" * Loads the terms.html page in the box\n"); - htmlSvg.append(" * Terms\n"); - htmlSvg.append(" * Loads the terms.png image in the box\n"); - htmlSvg.append(" * You can also use it programmatically:\n"); - htmlSvg.append(" * jQuery.facebox('some html')\n"); - htmlSvg.append(" * jQuery.facebox('some html', 'my-groovy-style')\n"); - htmlSvg.append(" * The above will open a facebox with \"some html\" as the content.\n"); - htmlSvg.append(" * jQuery.facebox(function($) {\n"); - htmlSvg.append(" * $.get('blah.html', function(data) { $.facebox(data) })\n"); - htmlSvg.append(" * })\n"); - htmlSvg.append(" * The above will show a loading screen before the passed function is called,\n"); - htmlSvg.append(" * allowing for a better ajaxy experience.\n"); - htmlSvg.append(" * The facebox function can also display an ajax page, an image, or the contents of a div:\n"); - htmlSvg.append(" * jQuery.facebox({ ajax: 'remote.html' })\n"); - htmlSvg.append(" * jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')\n"); - htmlSvg.append(" * jQuery.facebox({ image: 'stairs.jpg' })\n"); - htmlSvg.append(" * jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')\n"); - htmlSvg.append(" * jQuery.facebox({ div: '#box' })\n"); - htmlSvg.append(" * jQuery.facebox({ div: '#box' }, 'my-groovy-style')\n"); - htmlSvg.append(" * Want to close the facebox? Trigger the 'close.facebox' document event:\n"); - htmlSvg.append(" * jQuery(document).trigger('close.facebox')\n"); - htmlSvg.append(" * Facebox also has a bunch of other hooks:\n"); - htmlSvg.append(" * loading.facebox\n"); - htmlSvg.append(" * beforeReveal.facebox\n"); - htmlSvg.append(" * reveal.facebox (aliased as 'afterReveal.facebox')\n"); - htmlSvg.append(" * init.facebox\n"); - htmlSvg.append(" * afterClose.facebox\n"); - htmlSvg.append(" * Simply bind a function to any of these hooks:\n"); - htmlSvg.append(" * $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })\n"); - htmlSvg.append(" *\n"); - htmlSvg.append(" */\n"); - htmlSvg.append("(function($) {\n"); - htmlSvg.append(" $.facebox = function(data, klass) {\n"); - htmlSvg.append(" $.facebox.loading()\n"); - htmlSvg.append(" if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)\n"); - htmlSvg.append(" else if (data.image) fillFaceboxFromImage(data.image, klass)\n"); - htmlSvg.append(" else if (data.div) fillFaceboxFromHref(data.div, klass)\n"); - htmlSvg.append(" else if ($.isFunction(data)) data.call($)\n"); - htmlSvg.append(" else $.facebox.reveal(data, klass)\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" $.extend($.facebox, {\n"); - htmlSvg.append(" settings: {\n"); - htmlSvg.append(" opacity : 0.2,\n"); - htmlSvg.append(" overlay : true,\n"); - htmlSvg.append(" loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif',\n"); - htmlSvg.append(" closeImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png',\n"); - htmlSvg.append(" imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ],\n"); - htmlSvg.append(" faceboxHtml : '
"); - htmlSvg.append("
"); - htmlSvg.append("
"); - htmlSvg.append("
"); - htmlSvg.append(" "); - htmlSvg.append("
"); - htmlSvg.append("
'\n"); - htmlSvg.append(" }, \n"); - htmlSvg.append(" loading: function() {\n"); - htmlSvg.append(" init()\n"); - htmlSvg.append(" if ($('#facebox .loading').length == 1) return true\n"); - htmlSvg.append(" showOverlay() \n"); - htmlSvg.append(" $('#facebox .content').empty().\n"); - htmlSvg.append(" append('
')\n"); - htmlSvg.append(" $('#facebox').show().css({\n"); - htmlSvg.append(" top: getPageScroll()[1] + (getPageHeight() / 10),\n"); - htmlSvg.append(" left: $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2)\n"); - htmlSvg.append(" }) \n"); - htmlSvg.append(" $(document).bind('keydown.facebox', function(e) {\n"); - htmlSvg.append(" if (e.keyCode == 27) $.facebox.close()\n"); - htmlSvg.append(" return true\n"); - htmlSvg.append(" })\n"); - htmlSvg.append(" $(document).trigger('loading.facebox')\n"); - htmlSvg.append(" },\n"); - htmlSvg.append(" reveal: function(data, klass) {\n"); - htmlSvg.append(" $(document).trigger('beforeReveal.facebox')\n"); - htmlSvg.append(" if (klass) $('#facebox .content').addClass(klass)\n"); - htmlSvg.append(" $('#facebox .content').empty().append('
'+JSON.stringify(JSON.parse(data),null,4)+'
')\n"); - htmlSvg.append(" $('#facebox .popup').children().fadeIn('normal')\n"); - htmlSvg.append(" $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2))\n"); - htmlSvg.append(" $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')\n"); - htmlSvg.append(" }, \n"); - htmlSvg.append(" close: function() {\n"); - htmlSvg.append(" $(document).trigger('close.facebox')\n"); - htmlSvg.append(" return false\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" })\n"); - htmlSvg.append(" $.fn.facebox = function(settings) {\n"); - htmlSvg.append(" if ($(this).length == 0) return \n"); - htmlSvg.append(" init(settings) \n"); - htmlSvg.append(" function clickHandler() {\n"); - htmlSvg.append(" $.facebox.loading(true) \n"); - htmlSvg.append(" // support for rel=\"facebox.inline_popup\" syntax, to add a class\n"); - htmlSvg.append(" // also supports deprecated \"facebox[.inline_popup]\" syntax\n"); - htmlSvg.append(" var klass = this.rel.match(/facebox\\[?\\.(\\w+)\\]?/)\n"); - htmlSvg.append(" if (klass) klass = klass[1]\n"); - htmlSvg.append(" fillFaceboxFromHref(this.href, klass)\n"); - htmlSvg.append(" return false\n"); - htmlSvg.append(" } \n"); - htmlSvg.append(" return this.bind('click.facebox', clickHandler)\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" // called one time to setup facebox on this page\n"); - htmlSvg.append(" function init(settings) {\n"); - htmlSvg.append(" if ($.facebox.settings.inited) return true\n"); - htmlSvg.append(" else $.facebox.settings.inited = true\n"); - htmlSvg.append(" $(document).trigger('init.facebox')\n"); - htmlSvg.append(" makeCompatible()\n"); - htmlSvg.append(" var imageTypes = $.facebox.settings.imageTypes.join('|')\n"); - htmlSvg.append(" $.facebox.settings.imageTypesRegexp = new RegExp('\\\\.(' + imageTypes + ')(\\\\?.*)?$', 'i')\n"); - - htmlSvg.append(" if (settings) $.extend($.facebox.settings, settings)\n"); - htmlSvg.append(" $('body').append($.facebox.settings.faceboxHtml)\n"); - - htmlSvg.append(" var preload = [ new Image(), new Image() ]\n"); - htmlSvg.append(" preload[0].src = $.facebox.settings.closeImage\n"); - htmlSvg.append(" preload[1].src = $.facebox.settings.loadingImage\n"); - - htmlSvg.append(" $('#facebox').find('.b:first, .bl').each(function() {\n"); - htmlSvg.append(" preload.push(new Image())\n"); - htmlSvg.append(" preload.slice(-1).src = $(this).css('background-image').replace(/url\\((.+)\\)/, '$1')\n"); - htmlSvg.append(" })\n"); - - htmlSvg.append(" $('#facebox .close')\n"); - htmlSvg.append(" .click($.facebox.close)\n"); - htmlSvg.append(" .append('')\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" // getPageScroll() by quirksmode.com\n"); - htmlSvg.append(" function getPageScroll() {\n"); - htmlSvg.append(" var xScroll, yScroll;\n"); - htmlSvg.append(" if (self.pageYOffset) {\n"); - htmlSvg.append(" yScroll = self.pageYOffset;\n"); - htmlSvg.append(" xScroll = self.pageXOffset;\n"); - htmlSvg.append(" } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict\n"); - htmlSvg.append(" yScroll = document.documentElement.scrollTop;\n"); - htmlSvg.append(" xScroll = document.documentElement.scrollLeft;\n"); - htmlSvg.append(" } else if (document.body) {// all other Explorers\n"); - htmlSvg.append(" yScroll = document.body.scrollTop;\n"); - htmlSvg.append(" xScroll = document.body.scrollLeft;\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" return new Array(xScroll,yScroll)\n"); - htmlSvg.append(" }\n"); - - // Adapted from getPageSize() by quirksmode.com"); - htmlSvg.append(" function getPageHeight() {\n"); - htmlSvg.append(" var windowHeight\n"); - htmlSvg.append(" if (self.innerHeight) { // all except Explorer\n"); - htmlSvg.append(" windowHeight = self.innerHeight;\n"); - htmlSvg.append(" } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode\n"); - htmlSvg.append(" windowHeight = document.documentElement.clientHeight;\n"); - htmlSvg.append(" } else if (document.body) { // other Explorers\n"); - htmlSvg.append(" windowHeight = document.body.clientHeight;\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" return windowHeight\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" // Backwards compatibility\n"); - htmlSvg.append(" function makeCompatible() {\n"); - htmlSvg.append(" var $s = $.facebox.settings \n"); - htmlSvg.append(" $s.loadingImage = $s.loading_image || $s.loadingImage\n"); - htmlSvg.append(" $s.closeImage = $s.close_image || $s.closeImage\n"); - htmlSvg.append(" $s.imageTypes = $s.image_types || $s.imageTypes\n"); - htmlSvg.append(" $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" // Figures out what you want to display and displays it\n"); - htmlSvg.append(" // formats are:\n"); - htmlSvg.append(" // div: #id\n"); - htmlSvg.append(" // image: blah.extension\n"); - htmlSvg.append(" // ajax: anything else\n"); - htmlSvg.append(" function fillFaceboxFromHref(href, klass) {\n"); - htmlSvg.append(" // div\n"); - htmlSvg.append(" if (href.match(/#/)) {\n"); - htmlSvg.append(" var url = window.location.href.split('#')[0]\n"); - htmlSvg.append(" var target = href.replace(url,'')\n"); - htmlSvg.append(" if (target == '#') return\n"); - htmlSvg.append(" $.facebox.reveal($(target).html(), klass)\n"); - - htmlSvg.append(" // image\n"); - htmlSvg.append(" } else if (href.match($.facebox.settings.imageTypesRegexp)) {\n"); - htmlSvg.append(" fillFaceboxFromImage(href, klass)\n"); - htmlSvg.append(" // ajax\n"); - htmlSvg.append(" } else {\n"); - htmlSvg.append(" fillFaceboxFromAjax(href, klass)\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" function fillFaceboxFromImage(href, klass) {\n"); - htmlSvg.append(" var image = new Image()\n"); - htmlSvg.append(" image.onload = function() {\n"); - htmlSvg.append(" $.facebox.reveal('
', klass)\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" image.src = href\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" function fillFaceboxFromAjax(href, klass) {\n"); - htmlSvg.append(" $.facebox.jqxhr = $.get(href, function(data) { $.facebox.reveal(data, klass) })\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" function skipOverlay() {\n"); - htmlSvg.append(" return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" function showOverlay() {\n"); - htmlSvg.append(" if (skipOverlay()) return\n"); - - htmlSvg.append(" if ($('#facebox_overlay').length == 0)\n"); - htmlSvg.append(" $(\"body\").append('
')\n"); - - htmlSvg.append(" $('#facebox_overlay').hide().addClass(\"facebox_overlayBG\")\n"); - htmlSvg.append(" .css('opacity', $.facebox.settings.opacity)\n"); - htmlSvg.append(" .click(function() { $(document).trigger('close.facebox') })\n"); - htmlSvg.append(" .fadeIn(200)\n"); - htmlSvg.append(" return false\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" function hideOverlay() {\n"); - htmlSvg.append(" if (skipOverlay()) return \n"); - htmlSvg.append(" $('#facebox_overlay').fadeOut(200, function(){\n"); - htmlSvg.append(" $(\"#facebox_overlay\").removeClass(\"facebox_overlayBG\")\n"); - htmlSvg.append(" $(\"#facebox_overlay\").addClass(\"facebox_hide\")\n"); - htmlSvg.append(" $(\"#facebox_overlay\").remove()\n"); - htmlSvg.append(" }) \n"); - htmlSvg.append(" return false\n"); - htmlSvg.append(" }\n"); - - htmlSvg.append(" $(document).bind('close.facebox', function() {\n"); - htmlSvg.append(" if ($.facebox.jqxhr) {\n"); - htmlSvg.append(" $.facebox.jqxhr.abort()\n"); - htmlSvg.append(" $.facebox.jqxhr = null\n"); - htmlSvg.append(" }\n"); - htmlSvg.append(" $(document).unbind('keydown.facebox')\n"); - htmlSvg.append(" $('#facebox').fadeOut(function() {\n"); - htmlSvg.append(" $('#facebox .content').removeClass().addClass('content')\n"); - htmlSvg.append(" $('#facebox .loading').remove()\n"); - htmlSvg.append(" $(document).trigger('afterClose.facebox')\n"); - htmlSvg.append(" })\n"); - htmlSvg.append(" hideOverlay()\n"); - htmlSvg.append(" })\n"); - - htmlSvg.append("})(jQuery);\n"); - + File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js"); + try + { + htmlSvg.append(HtmlFile.readFileAsString(faceBoxJsFile)); + } catch (IOException e) + { + e.printStackTrace(); + } } htmlSvg.append("\n"); diff --git a/test/jalview/io/BioJsHTMLOutputTest.java b/test/jalview/io/BioJsHTMLOutputTest.java index ddf9a15..09ce54c 100644 --- a/test/jalview/io/BioJsHTMLOutputTest.java +++ b/test/jalview/io/BioJsHTMLOutputTest.java @@ -54,7 +54,8 @@ public class BioJsHTMLOutputTest { e.printStackTrace(); } - bjsTemplate = BioJsHTMLOutput.getBioJsTemplateAsString(); + bjsTemplate = HtmlFile.readFileAsString(BioJsHTMLOutput + .getCurrentBJSTemplateFile()); // System.out.println(bjsTemplate); } catch (IOException e) { -- 1.7.10.2