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.gui.AlignmentPanel;
24 import jalview.gui.HTMLOptions;
25 import jalview.gui.OOMWarning;
26 import jalview.math.AlignmentDimension;
27 import jalview.util.MessageManager;
29 import java.awt.Graphics;
30 import java.awt.print.PrinterException;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
35 import org.jfree.graphics2d.svg.SVGGraphics2D;
36 import org.jfree.graphics2d.svg.SVGHints;
38 public class HtmlSvgOutput extends HTMLOutput
41 private File generatedFile;
43 public HtmlSvgOutput(AlignmentPanel ap)
49 public void exportHTML(String file)
56 file = getOutputFile();
58 generatedFile = new File(file);
61 setProgressMessage(MessageManager.formatMessage(
62 "info.error_creating_file", "HTML"));
73 setProgressMessage(null);
74 setProgressMessage(MessageManager.formatMessage(
75 "status.exporting_alignment_as_x_file", "HTML"));
76 AlignmentDimension aDimension = ap.getAlignmentDimension();
77 SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
78 aDimension.getWidth(),
79 aDimension.getHeight());
80 SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
81 aDimension.getWidth(),
82 aDimension.getHeight());
84 String renderStyle = jalview.bin.Cache.getDefault(
85 "HTML_RENDERING", "Prompt each time");
87 // If we need to prompt, and if the GUI is visible then
88 // Prompt for rendering style
89 if (renderStyle.equalsIgnoreCase("Prompt each time")
92 HTMLOptions svgOption = new HTMLOptions();
93 renderStyle = svgOption.getValue();
95 if (renderStyle == null || svgOption.cancelled)
97 setProgressMessage(MessageManager.formatMessage(
98 "status.cancelled_image_export_operation", "HTML"));
103 if (renderStyle.equalsIgnoreCase("Lineart"))
105 idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
106 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
107 alignPanelGraphics.setRenderingHint(
108 SVGHints.KEY_DRAW_STRING_TYPE,
109 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
111 if (ap.av.getWrapAlignment())
113 printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
118 printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
119 idPanelGraphics, alignPanelGraphics);
122 String idPanelSvgData = idPanelGraphics.getSVGDocument();
123 String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
124 String jsonData = getBioJSONData();
125 String htmlData = getHtml(idPanelSvgData, alignPanelSvgData, jsonData,
126 ap.av.getWrapAlignment());
127 FileOutputStream out = new FileOutputStream(generatedFile);
128 out.write(htmlData.getBytes());
132 } catch (OutOfMemoryError err)
134 System.out.println("########################\n"
135 + "OUT OF MEMORY " + generatedFile + "\n"
136 + "########################");
137 new OOMWarning("Creating Image for " + generatedFile, err);
138 } catch (Exception e)
141 setProgressMessage(MessageManager.formatMessage(
142 "info.error_creating_file", "HTML"));
144 setProgressMessage(MessageManager.formatMessage(
145 "status.export_complete", "HTML"));
152 static JalviewFileChooser getHTMLChooser()
154 return new jalview.io.JalviewFileChooser(
155 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
156 new String[] { "html" },
157 new String[] { "Hypertext Markup Language" },
158 "Hypertext Markup Language");
161 public int printUnwrapped(int pwidth, int pheight, int pi,
162 Graphics idGraphics, Graphics alignmentGraphics)
163 throws PrinterException
165 return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
169 public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
170 throws PrinterException
172 return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]);
175 private String getHtml(String titleSvg, String alignmentSvg,
176 String jsonData, boolean wrapped)
178 StringBuilder htmlSvg = new StringBuilder();
179 htmlSvg.append("<html>\n");
180 if (jsonData != null)
182 htmlSvg.append("<button onclick=\"javascipt:openJalviewUsingCurrentUrl();\">Launch in Jalview</button> ");
183 htmlSvg.append("<input type=\"submit\" value=\"View raw BioJSON Data\" onclick=\"jQuery.facebox({ div:'#seqData' }); return false;\" />");
184 htmlSvg.append("<div style=\"display: none;\" name=\"seqData\" id=\"seqData\" >"
185 + jsonData + "</div>");
186 htmlSvg.append("<br/> ");
188 htmlSvg.append("\n<style type=\"text/css\"> "
189 + "div.parent{ width:100%;<!-- overflow: auto; -->}\n"
190 + "div.titlex{ width:11%; float: left; }\n"
191 + "div.align{ width:89%; float: right; }\n"
192 + "div.main-container{ border: 2px solid blue; border: 2px solid blue; width: 99%; min-height: 99%; }\n"
193 + ".sub-category-container {overflow-y: scroll; overflow-x: hidden; width: 100%; height: 100%;}\n"
194 + "object {pointer-events: none;}");
195 if (jsonData != null)
197 // facebox style sheet for displaying raw BioJSON data
198 htmlSvg.append("#facebox { position: absolute; top: 0; left: 0; z-index: 100; text-align: left; }\n"
199 + "#facebox .popup{ position:relative; border:3px solid rgba(0,0,0,0); -webkit-border-radius:5px;"
200 + "-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);"
201 + "box-shadow:0 0 18px rgba(0,0,0,0.4); }\n"
202 + "#facebox .content { display:table; width: 98%; padding: 10px; background: #fff; -webkit-border-radius:4px; -moz-border-radius:4px;"
203 + " border-radius:4px; }\n"
204 + "#facebox .content > p:first-child{ margin-top:0; }\n"
205 + "#facebox .content > p:last-child{ margin-bottom:0; }\n"
206 + "#facebox .close{ position:absolute; top:5px; right:5px; padding:2px; background:#fff; }\n"
207 + "#facebox .close img{ opacity:0.3; }\n"
208 + "#facebox .close:hover img{ opacity:1.0; }\n"
209 + "#facebox .loading { text-align: center; }\n"
210 + "#facebox .image { text-align: center;}\n"
211 + "#facebox img { border: 0; margin: 0; }\n"
212 + "#facebox_overlay { position: fixed; top: 0px; left: 0px; height:100%; width:100%; }\n"
213 + ".facebox_hide { z-index:-100; }\n"
214 + ".facebox_overlayBG { background-color: #000; z-index: 99; }");
216 htmlSvg.append("</style>");
219 htmlSvg.append("<div class=\"main-container\" \n>");
220 htmlSvg.append("<div class=\"titlex\">\n");
221 htmlSvg.append("<div class=\"sub-category-container\"> \n");
222 htmlSvg.append(titleSvg);
223 htmlSvg.append("</div>");
224 htmlSvg.append("</div>\n\n<!-- ========================================================================================== -->\n\n");
225 htmlSvg.append("<div class=\"align\" >");
227 "<div class=\"sub-category-container\"> <div style=\"overflow-x: scroll;\">")
228 .append(alignmentSvg).append("</div></div>").append("</div>");
229 htmlSvg.append("</div>");
231 htmlSvg.append("<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
232 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n"
234 + "var subCatContainer = $(\".sub-category-container\");\n"
235 + "subCatContainer.scroll(\nfunction() {\n"
236 + "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
238 htmlSvg.append("</script>\n");
242 htmlSvg.append("<div>\n")
243 .append(alignmentSvg).append("</div>");
244 htmlSvg.append("<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
245 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
249 // javascript for launching file in Jalview
251 htmlSvg.append("<script language=\"JavaScript\">\n");
252 htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
253 htmlSvg.append(" var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
254 htmlSvg.append(" var jalviewVersion = json['appSettings'].version;\n");
255 htmlSvg.append(" var url = json['appSettings'].webStartUrl;\n");
256 htmlSvg.append(" var myForm = document.createElement(\"form\");\n\n");
257 htmlSvg.append(" var heap = document.createElement(\"input\");\n");
258 htmlSvg.append(" heap.setAttribute(\"name\", \"jvm-max-heap\") ;\n");
259 htmlSvg.append(" heap.setAttribute(\"value\", \"2G\");\n\n");
260 htmlSvg.append(" var target = document.createElement(\"input\");\n");
261 htmlSvg.append(" target.setAttribute(\"name\", \"open\");\n");
262 htmlSvg.append(" target.setAttribute(\"value\", document.URL);\n\n");
263 htmlSvg.append(" var jvVersion = document.createElement(\"input\");\n");
264 htmlSvg.append(" jvVersion.setAttribute(\"name\", \"version\") ;\n");
265 htmlSvg.append(" jvVersion.setAttribute(\"value\", jalviewVersion);\n\n");
266 htmlSvg.append(" myForm.action = url;\n");
267 htmlSvg.append(" myForm.appendChild(heap);\n");
268 htmlSvg.append(" myForm.appendChild(target);\n");
269 htmlSvg.append(" myForm.appendChild(jvVersion);\n");
270 htmlSvg.append(" document.body.appendChild(myForm);\n");
271 htmlSvg.append(" myForm.submit() ;\n");
272 htmlSvg.append(" document.body.removeChild(myForm);\n");
273 htmlSvg.append("}\n");
275 // jquery facebox for displaying raw BioJSON data");
276 if (jsonData != null)
278 File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
281 htmlSvg.append(HTMLOutput.readFileAsString(faceBoxJsFile));
282 } catch (IOException e)
288 htmlSvg.append("</script>\n");
289 htmlSvg.append("</html>");
290 return htmlSvg.toString();
294 public boolean isEmbedData()
296 return Boolean.valueOf(jalview.bin.Cache.getDefault(
297 "EXPORT_EMBBED_BIOJSON", "true"));
301 public boolean isLaunchInBrowserAfterExport()
307 public File getExportedFile()
309 return generatedFile;