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.exceptions.NoFileSelectedException;
24 import jalview.gui.AlignmentPanel;
25 import jalview.gui.HTMLOptions;
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;
36 import org.jfree.graphics2d.svg.SVGGraphics2D;
37 import org.jfree.graphics2d.svg.SVGHints;
39 public class HtmlSvgOutput extends HTMLOutput
42 public HtmlSvgOutput(AlignmentPanel ap)
48 public void exportHTML(String outputFile)
53 if (outputFile == null)
55 outputFile = getOutputFile();
57 generatedFile = new File(outputFile);
58 } catch (NoFileSelectedException e)
60 setProgressMessage(MessageManager.formatMessage(
61 "status.cancelled_image_export_operation", "HTML"));
65 setProgressMessage(MessageManager
66 .formatMessage("info.error_creating_file", "HTML"));
70 new Thread(this).start();
73 public int printUnwrapped(int pwidth, int pheight, int pi,
74 Graphics idGraphics, Graphics alignmentGraphics)
75 throws PrinterException
77 return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
81 public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
83 return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0], false);
86 private String getHtml(String titleSvg, String alignmentSvg,
87 String jsonData, boolean wrapped)
89 StringBuilder htmlSvg = new StringBuilder();
90 htmlSvg.append("<html>\n");
94 "<button onclick=\"javascipt:openJalviewUsingCurrentUrl();\">Launch in Jalview</button> ");
96 "<input type=\"submit\" value=\"View raw BioJSON Data\" onclick=\"jQuery.facebox({ div:'#seqData' }); return false;\" />");
98 "<div style=\"display: none;\" name=\"seqData\" id=\"seqData\" >"
99 + jsonData + "</div>");
100 htmlSvg.append("<br/> ");
102 htmlSvg.append("\n<style type=\"text/css\"> "
103 + "div.parent{ width:100%;<!-- overflow: auto; -->}\n"
104 + "div.titlex{ width:11%; float: left; }\n"
105 + "div.align{ width:89%; float: right; }\n"
106 + "div.main-container{ border: 2px solid blue; border: 2px solid blue; width: 99%; min-height: 99%; }\n"
107 + ".sub-category-container {overflow-y: scroll; overflow-x: hidden; width: 100%; height: 100%;}\n"
108 + "object {pointer-events: none;}");
109 if (jsonData != null)
111 // facebox style sheet for displaying raw BioJSON data
113 "#facebox { position: absolute; top: 0; left: 0; z-index: 100; text-align: left; }\n"
114 + "#facebox .popup{ position:relative; border:3px solid rgba(0,0,0,0); -webkit-border-radius:5px;"
115 + "-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);"
116 + "box-shadow:0 0 18px rgba(0,0,0,0.4); }\n"
117 + "#facebox .content { display:table; width: 98%; padding: 10px; background: #fff; -webkit-border-radius:4px; -moz-border-radius:4px;"
118 + " border-radius:4px; }\n"
119 + "#facebox .content > p:first-child{ margin-top:0; }\n"
120 + "#facebox .content > p:last-child{ margin-bottom:0; }\n"
121 + "#facebox .close{ position:absolute; top:5px; right:5px; padding:2px; background:#fff; }\n"
122 + "#facebox .close img{ opacity:0.3; }\n"
123 + "#facebox .close:hover img{ opacity:1.0; }\n"
124 + "#facebox .loading { text-align: center; }\n"
125 + "#facebox .image { text-align: center;}\n"
126 + "#facebox img { border: 0; margin: 0; }\n"
127 + "#facebox_overlay { position: fixed; top: 0px; left: 0px; height:100%; width:100%; }\n"
128 + ".facebox_hide { z-index:-100; }\n"
129 + ".facebox_overlayBG { background-color: #000; z-index: 99; }");
131 htmlSvg.append("</style>");
134 htmlSvg.append("<div class=\"main-container\" \n>");
135 htmlSvg.append("<div class=\"titlex\">\n");
136 htmlSvg.append("<div class=\"sub-category-container\"> \n");
137 htmlSvg.append(titleSvg);
138 htmlSvg.append("</div>");
140 "</div>\n\n<!-- ========================================================================================== -->\n\n");
141 htmlSvg.append("<div class=\"align\" >");
143 "<div class=\"sub-category-container\"> <div style=\"overflow-x: scroll;\">")
144 .append(alignmentSvg).append("</div></div>").append("</div>");
145 htmlSvg.append("</div>");
148 "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
149 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n"
151 + "var subCatContainer = $(\".sub-category-container\");\n"
152 + "subCatContainer.scroll(\nfunction() {\n"
153 + "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
155 htmlSvg.append("</script>\n");
159 htmlSvg.append("<div>\n").append(alignmentSvg).append("</div>");
161 "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
162 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
165 // javascript for launching file in Jalview
166 htmlSvg.append("<script language=\"JavaScript\">\n");
167 htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
169 " var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
171 " var jalviewVersion = json['appSettings'].version;\n");
172 htmlSvg.append(" var url = json['appSettings'].webStartUrl;\n");
174 " var myForm = document.createElement(\"form\");\n\n");
175 htmlSvg.append(" var heap = document.createElement(\"input\");\n");
176 htmlSvg.append(" heap.setAttribute(\"name\", \"jvm-max-heap\") ;\n");
177 htmlSvg.append(" heap.setAttribute(\"value\", \"2G\");\n\n");
178 htmlSvg.append(" var target = document.createElement(\"input\");\n");
179 htmlSvg.append(" target.setAttribute(\"name\", \"open\");\n");
180 htmlSvg.append(" target.setAttribute(\"value\", document.URL);\n\n");
182 " var jvVersion = document.createElement(\"input\");\n");
183 htmlSvg.append(" jvVersion.setAttribute(\"name\", \"version\") ;\n");
185 " jvVersion.setAttribute(\"value\", jalviewVersion);\n\n");
186 htmlSvg.append(" myForm.action = url;\n");
187 htmlSvg.append(" myForm.appendChild(heap);\n");
188 htmlSvg.append(" myForm.appendChild(target);\n");
189 htmlSvg.append(" myForm.appendChild(jvVersion);\n");
190 htmlSvg.append(" document.body.appendChild(myForm);\n");
191 htmlSvg.append(" myForm.submit() ;\n");
192 htmlSvg.append(" document.body.removeChild(myForm);\n");
193 htmlSvg.append("}\n");
195 if (jsonData != null)
197 // JQuery FaceBox for displaying raw BioJSON data");
198 File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
201 htmlSvg.append(HTMLOutput.readFileAsString(faceBoxJsFile));
202 } catch (IOException e)
208 htmlSvg.append("</script>\n");
209 htmlSvg.append("</html>");
210 return htmlSvg.toString();
214 public boolean isEmbedData()
216 return Boolean.valueOf(
217 jalview.bin.Cache.getDefault("EXPORT_EMBBED_BIOJSON", "true"));
221 public boolean isLaunchInBrowserAfterExport()
227 public File getExportedFile()
229 return generatedFile;
237 setProgressMessage(null);
238 setProgressMessage(MessageManager.formatMessage(
239 "status.exporting_alignment_as_x_file", "HTML"));
240 AlignmentDimension aDimension = ap.getAlignmentDimension();
241 SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
242 aDimension.width, aDimension.height);
243 SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
244 aDimension.width, aDimension.height);
246 String renderStyle = jalview.bin.Cache.getDefault("HTML_RENDERING",
249 // If we need to prompt, and if the GUI is visible then
250 // Prompt for rendering style
251 if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
253 HTMLOptions svgOption = new HTMLOptions();
254 renderStyle = svgOption.getValue();
256 if (renderStyle == null || svgOption.cancelled)
258 setProgressMessage(MessageManager.formatMessage(
259 "status.cancelled_image_export_operation", "HTML"));
264 if (renderStyle.equalsIgnoreCase("Lineart"))
266 idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
267 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
268 alignPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
269 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
271 if (ap.av.getWrapAlignment())
273 printWrapped(aDimension.width, aDimension.height, 0,
278 printUnwrapped(aDimension.width, aDimension.height, 0,
279 idPanelGraphics, alignPanelGraphics);
282 String idPanelSvgData = idPanelGraphics.getSVGDocument();
283 String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
284 String jsonData = getBioJSONData();
285 String htmlData = getHtml(idPanelSvgData, alignPanelSvgData, jsonData,
286 ap.av.getWrapAlignment());
287 FileOutputStream out = new FileOutputStream(generatedFile);
288 out.write(htmlData.getBytes());
291 setProgressMessage(MessageManager
292 .formatMessage("status.export_complete", "HTML"));
294 } catch (OutOfMemoryError err)
296 System.out.println("########################\n" + "OUT OF MEMORY "
297 + generatedFile + "\n" + "########################");
298 new OOMWarning("Creating Image for " + generatedFile, err);
299 } catch (Exception e)
302 setProgressMessage(MessageManager
303 .formatMessage("info.error_creating_file", "HTML"));