2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.gui.AlignmentPanel;
25 import jalview.gui.LineartOptions;
26 import jalview.gui.OOMWarning;
27 import jalview.math.AlignmentDimension;
28 import jalview.util.MessageManager;
30 import java.awt.Graphics;
31 import java.awt.print.PrinterException;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.util.concurrent.atomic.AtomicBoolean;
37 import org.jfree.graphics2d.svg.SVGGraphics2D;
38 import org.jfree.graphics2d.svg.SVGHints;
40 public class HtmlSvgOutput extends HTMLOutput
42 public HtmlSvgOutput(AlignmentPanel ap)
47 public int printUnwrapped(int pwidth, int pheight, int pi,
48 Graphics idGraphics, Graphics alignmentGraphics)
49 throws PrinterException
51 return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
55 public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
56 throws PrinterException
58 return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]);
61 String getHtml(String titleSvg, String alignmentSvg,
62 String jsonData, boolean wrapped)
64 StringBuilder htmlSvg = new StringBuilder();
65 htmlSvg.append("<html>\n");
69 "<button onclick=\"javascipt:openJalviewUsingCurrentUrl();\">Launch in Jalview</button> ");
71 "<input type=\"submit\" value=\"View raw BioJSON Data\" onclick=\"jQuery.facebox({ div:'#seqData' }); return false;\" />");
73 "<div style=\"display: none;\" name=\"seqData\" id=\"seqData\" >"
74 + jsonData + "</div>");
75 htmlSvg.append("<br/> ");
77 htmlSvg.append("\n<style type=\"text/css\"> "
78 + "div.parent{ width:100%;<!-- overflow: auto; -->}\n"
79 + "div.titlex{ width:11%; float: left; }\n"
80 + "div.align{ width:89%; float: right; }\n"
81 + "div.main-container{ border: 2px solid blue; border: 2px solid blue; width: 99%; min-height: 99%; }\n"
82 + ".sub-category-container {overflow-y: scroll; overflow-x: hidden; width: 100%; height: 100%;}\n"
83 + "object {pointer-events: none;}");
86 // facebox style sheet for displaying raw BioJSON data
88 "#facebox { position: absolute; top: 0; left: 0; z-index: 100; text-align: left; }\n"
89 + "#facebox .popup{ position:relative; border:3px solid rgba(0,0,0,0); -webkit-border-radius:5px;"
90 + "-moz-border-radius:5px; border-radius:5px; -webkit-box-shadow:0 0 18px rgba(0,0,0,0.4); -moz-box-shadow:0 0 18px rgba(0,0,0,0.4);"
91 + "box-shadow:0 0 18px rgba(0,0,0,0.4); }\n"
92 + "#facebox .content { display:table; width: 98%; padding: 10px; background: #fff; -webkit-border-radius:4px; -moz-border-radius:4px;"
93 + " border-radius:4px; }\n"
94 + "#facebox .content > p:first-child{ margin-top:0; }\n"
95 + "#facebox .content > p:last-child{ margin-bottom:0; }\n"
96 + "#facebox .close{ position:absolute; top:5px; right:5px; padding:2px; background:#fff; }\n"
97 + "#facebox .close img{ opacity:0.3; }\n"
98 + "#facebox .close:hover img{ opacity:1.0; }\n"
99 + "#facebox .loading { text-align: center; }\n"
100 + "#facebox .image { text-align: center;}\n"
101 + "#facebox img { border: 0; margin: 0; }\n"
102 + "#facebox_overlay { position: fixed; top: 0px; left: 0px; height:100%; width:100%; }\n"
103 + ".facebox_hide { z-index:-100; }\n"
104 + ".facebox_overlayBG { background-color: #000; z-index: 99; }");
106 htmlSvg.append("</style>");
109 htmlSvg.append("<div class=\"main-container\" \n>");
110 htmlSvg.append("<div class=\"titlex\">\n");
111 htmlSvg.append("<div class=\"sub-category-container\"> \n");
112 htmlSvg.append(titleSvg);
113 htmlSvg.append("</div>");
115 "</div>\n\n<!-- ========================================================================================== -->\n\n");
116 htmlSvg.append("<div class=\"align\" >");
118 "<div class=\"sub-category-container\"> <div style=\"overflow-x: scroll;\">")
119 .append(alignmentSvg).append("</div></div>").append("</div>");
120 htmlSvg.append("</div>");
123 "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
124 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n"
126 + "var subCatContainer = $(\".sub-category-container\");\n"
127 + "subCatContainer.scroll(\nfunction() {\n"
128 + "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
130 htmlSvg.append("</script>\n");
134 htmlSvg.append("<div>\n").append(alignmentSvg).append("</div>");
136 "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
137 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
140 // javascript for launching file in Jalview
141 htmlSvg.append("<script language=\"JavaScript\">\n");
142 htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
144 " var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
146 " var jalviewVersion = json['appSettings'].version;\n");
147 htmlSvg.append(" var url = json['appSettings'].webStartUrl;\n");
149 " var myForm = document.createElement(\"form\");\n\n");
150 htmlSvg.append(" var heap = document.createElement(\"input\");\n");
151 htmlSvg.append(" heap.setAttribute(\"name\", \"jvm-max-heap\") ;\n");
152 htmlSvg.append(" heap.setAttribute(\"value\", \"2G\");\n\n");
153 htmlSvg.append(" var target = document.createElement(\"input\");\n");
154 htmlSvg.append(" target.setAttribute(\"name\", \"open\");\n");
155 htmlSvg.append(" target.setAttribute(\"value\", document.URL);\n\n");
157 " var jvVersion = document.createElement(\"input\");\n");
158 htmlSvg.append(" jvVersion.setAttribute(\"name\", \"version\") ;\n");
160 " jvVersion.setAttribute(\"value\", jalviewVersion);\n\n");
161 htmlSvg.append(" myForm.action = url;\n");
162 htmlSvg.append(" myForm.appendChild(heap);\n");
163 htmlSvg.append(" myForm.appendChild(target);\n");
164 htmlSvg.append(" myForm.appendChild(jvVersion);\n");
165 htmlSvg.append(" document.body.appendChild(myForm);\n");
166 htmlSvg.append(" myForm.submit() ;\n");
167 htmlSvg.append(" document.body.removeChild(myForm);\n");
168 htmlSvg.append("}\n");
170 if (jsonData != null)
172 // JQuery FaceBox for displaying raw BioJSON data");
173 File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
176 htmlSvg.append(HTMLOutput.readFileAsString(faceBoxJsFile));
177 } catch (IOException e)
183 htmlSvg.append("</script>\n");
184 htmlSvg.append("</html>");
185 return htmlSvg.toString();
189 public boolean isEmbedData()
191 return Boolean.valueOf(
192 jalview.bin.Cache.getDefault("EXPORT_EMBBED_BIOJSON", "true"));
196 public boolean isLaunchInBrowserAfterExport()
206 String renderStyle = Cache.getDefault("HTML_RENDERING",
208 AtomicBoolean textOption = new AtomicBoolean(
209 !"Lineart".equals(renderStyle));
212 * configure the action to run on OK in the dialog
214 Runnable okAction = new Runnable()
219 doOutput(textOption.get());
224 * Prompt for character rendering style if preference is not set
226 if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
228 LineartOptions svgOption = new LineartOptions("HTML", textOption);
229 svgOption.setResponseAction(1, new Runnable()
234 setProgressMessage(MessageManager.formatMessage(
235 "status.cancelled_image_export_operation",
239 svgOption.setResponseAction(0, okAction);
240 svgOption.showDialog();
241 /* no code here - JalviewJS cannot execute it */
246 * else (if preference set) just do the export action
248 doOutput(textOption.get());
250 } catch (OutOfMemoryError err)
252 System.out.println("########################\n" + "OUT OF MEMORY "
253 + generatedFile + "\n" + "########################");
254 new OOMWarning("Creating Image for " + generatedFile, err);
255 } catch (Exception e)
258 setProgressMessage(MessageManager
259 .formatMessage("info.error_creating_file", getDescription()));
264 * Builds and writes the image to the file specified by field
265 * <code>generatedFile</code>
267 * @param textCharacters
268 * true for Text character rendering, false for Lineart
270 protected void doOutput(boolean textCharacters)
274 AlignmentDimension aDimension = ap.getAlignmentDimension();
275 SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
276 aDimension.getWidth(), aDimension.getHeight());
277 SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
278 aDimension.getWidth(), aDimension.getHeight());
279 if (!textCharacters) // Lineart selected
281 idPanelGraphics.setRenderingHint(
282 SVGHints.KEY_DRAW_STRING_TYPE,
283 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
284 alignPanelGraphics.setRenderingHint(
285 SVGHints.KEY_DRAW_STRING_TYPE,
286 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
288 if (ap.av.getWrapAlignment())
290 printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
295 printUnwrapped(aDimension.getWidth(), aDimension.getHeight(),
296 0, idPanelGraphics, alignPanelGraphics);
299 String idPanelSvgData = idPanelGraphics.getSVGDocument();
300 String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
301 String jsonData = getBioJSONData();
302 String htmlData = getHtml(idPanelSvgData, alignPanelSvgData,
303 jsonData, ap.av.getWrapAlignment());
304 FileOutputStream out = new FileOutputStream(generatedFile);
305 out.write(htmlData.getBytes());
308 setProgressMessage(MessageManager
309 .formatMessage("status.export_complete", getDescription()));
311 } catch (Exception e)
314 setProgressMessage(MessageManager
315 .formatMessage("info.error_creating_file", getDescription()));