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;
29 import jalview.util.dialogrunner.RunResponse;
31 import java.awt.Graphics;
32 import java.awt.print.PrinterException;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.util.concurrent.atomic.AtomicBoolean;
38 import javax.swing.JOptionPane;
40 import org.jfree.graphics2d.svg.SVGGraphics2D;
41 import org.jfree.graphics2d.svg.SVGHints;
43 public class HtmlSvgOutput extends HTMLOutput
45 public HtmlSvgOutput(AlignmentPanel ap)
51 public void exportHTML(String outputFile)
56 if (outputFile == null)
58 outputFile = getOutputFile();
59 if (outputFile == null)
61 setProgressMessage(MessageManager.formatMessage(
62 "status.cancelled_image_export_operation", "HTML"));
66 generatedFile = new File(outputFile);
69 setProgressMessage(MessageManager
70 .formatMessage("info.error_creating_file", "HTML"));
74 new Thread(this).start();
77 public int printUnwrapped(int pwidth, int pheight, int pi,
78 Graphics idGraphics, Graphics alignmentGraphics)
79 throws PrinterException
81 return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
85 public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
86 throws PrinterException
88 return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]);
91 String getHtml(String titleSvg, String alignmentSvg,
92 String jsonData, boolean wrapped)
94 StringBuilder htmlSvg = new StringBuilder();
95 htmlSvg.append("<html>\n");
99 "<button onclick=\"javascipt:openJalviewUsingCurrentUrl();\">Launch in Jalview</button> ");
101 "<input type=\"submit\" value=\"View raw BioJSON Data\" onclick=\"jQuery.facebox({ div:'#seqData' }); return false;\" />");
103 "<div style=\"display: none;\" name=\"seqData\" id=\"seqData\" >"
104 + jsonData + "</div>");
105 htmlSvg.append("<br/> ");
107 htmlSvg.append("\n<style type=\"text/css\"> "
108 + "div.parent{ width:100%;<!-- overflow: auto; -->}\n"
109 + "div.titlex{ width:11%; float: left; }\n"
110 + "div.align{ width:89%; float: right; }\n"
111 + "div.main-container{ border: 2px solid blue; border: 2px solid blue; width: 99%; min-height: 99%; }\n"
112 + ".sub-category-container {overflow-y: scroll; overflow-x: hidden; width: 100%; height: 100%;}\n"
113 + "object {pointer-events: none;}");
114 if (jsonData != null)
116 // facebox style sheet for displaying raw BioJSON data
118 "#facebox { position: absolute; top: 0; left: 0; z-index: 100; text-align: left; }\n"
119 + "#facebox .popup{ position:relative; border:3px solid rgba(0,0,0,0); -webkit-border-radius:5px;"
120 + "-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);"
121 + "box-shadow:0 0 18px rgba(0,0,0,0.4); }\n"
122 + "#facebox .content { display:table; width: 98%; padding: 10px; background: #fff; -webkit-border-radius:4px; -moz-border-radius:4px;"
123 + " border-radius:4px; }\n"
124 + "#facebox .content > p:first-child{ margin-top:0; }\n"
125 + "#facebox .content > p:last-child{ margin-bottom:0; }\n"
126 + "#facebox .close{ position:absolute; top:5px; right:5px; padding:2px; background:#fff; }\n"
127 + "#facebox .close img{ opacity:0.3; }\n"
128 + "#facebox .close:hover img{ opacity:1.0; }\n"
129 + "#facebox .loading { text-align: center; }\n"
130 + "#facebox .image { text-align: center;}\n"
131 + "#facebox img { border: 0; margin: 0; }\n"
132 + "#facebox_overlay { position: fixed; top: 0px; left: 0px; height:100%; width:100%; }\n"
133 + ".facebox_hide { z-index:-100; }\n"
134 + ".facebox_overlayBG { background-color: #000; z-index: 99; }");
136 htmlSvg.append("</style>");
139 htmlSvg.append("<div class=\"main-container\" \n>");
140 htmlSvg.append("<div class=\"titlex\">\n");
141 htmlSvg.append("<div class=\"sub-category-container\"> \n");
142 htmlSvg.append(titleSvg);
143 htmlSvg.append("</div>");
145 "</div>\n\n<!-- ========================================================================================== -->\n\n");
146 htmlSvg.append("<div class=\"align\" >");
148 "<div class=\"sub-category-container\"> <div style=\"overflow-x: scroll;\">")
149 .append(alignmentSvg).append("</div></div>").append("</div>");
150 htmlSvg.append("</div>");
153 "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
154 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n"
156 + "var subCatContainer = $(\".sub-category-container\");\n"
157 + "subCatContainer.scroll(\nfunction() {\n"
158 + "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
160 htmlSvg.append("</script>\n");
164 htmlSvg.append("<div>\n").append(alignmentSvg).append("</div>");
166 "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
167 + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
170 // javascript for launching file in Jalview
171 htmlSvg.append("<script language=\"JavaScript\">\n");
172 htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
174 " var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
176 " var jalviewVersion = json['appSettings'].version;\n");
177 htmlSvg.append(" var url = json['appSettings'].webStartUrl;\n");
179 " var myForm = document.createElement(\"form\");\n\n");
180 htmlSvg.append(" var heap = document.createElement(\"input\");\n");
181 htmlSvg.append(" heap.setAttribute(\"name\", \"jvm-max-heap\") ;\n");
182 htmlSvg.append(" heap.setAttribute(\"value\", \"2G\");\n\n");
183 htmlSvg.append(" var target = document.createElement(\"input\");\n");
184 htmlSvg.append(" target.setAttribute(\"name\", \"open\");\n");
185 htmlSvg.append(" target.setAttribute(\"value\", document.URL);\n\n");
187 " var jvVersion = document.createElement(\"input\");\n");
188 htmlSvg.append(" jvVersion.setAttribute(\"name\", \"version\") ;\n");
190 " jvVersion.setAttribute(\"value\", jalviewVersion);\n\n");
191 htmlSvg.append(" myForm.action = url;\n");
192 htmlSvg.append(" myForm.appendChild(heap);\n");
193 htmlSvg.append(" myForm.appendChild(target);\n");
194 htmlSvg.append(" myForm.appendChild(jvVersion);\n");
195 htmlSvg.append(" document.body.appendChild(myForm);\n");
196 htmlSvg.append(" myForm.submit() ;\n");
197 htmlSvg.append(" document.body.removeChild(myForm);\n");
198 htmlSvg.append("}\n");
200 if (jsonData != null)
202 // JQuery FaceBox for displaying raw BioJSON data");
203 File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
206 htmlSvg.append(HTMLOutput.readFileAsString(faceBoxJsFile));
207 } catch (IOException e)
213 htmlSvg.append("</script>\n");
214 htmlSvg.append("</html>");
215 return htmlSvg.toString();
219 public boolean isEmbedData()
221 return Boolean.valueOf(
222 jalview.bin.Cache.getDefault("EXPORT_EMBBED_BIOJSON", "true"));
226 public boolean isLaunchInBrowserAfterExport()
236 setProgressMessage(null);
237 setProgressMessage(MessageManager.formatMessage(
238 "status.exporting_alignment_as_x_file", getDescription()));
240 String renderStyle = Cache.getDefault("HTML_RENDERING",
242 AtomicBoolean textOption = new AtomicBoolean(
243 !"Lineart".equals(renderStyle));
246 * configure the action to run on OK in the dialog
248 RunResponse okAction = new RunResponse(JOptionPane.OK_OPTION)
253 doOutput(textOption.get());
258 * Prompt for character rendering style if preference is not set
260 if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
262 LineartOptions svgOption = new LineartOptions("HTML", textOption);
263 svgOption.setResponseAction(new RunResponse(JOptionPane.NO_OPTION)
268 setProgressMessage(MessageManager.formatMessage(
269 "status.cancelled_image_export_operation",
273 svgOption.setResponseAction(okAction);
274 svgOption.showDialog();
275 /* no code here - JalviewJS cannot execute it */
280 * else (if preference set) just do the export action
282 doOutput(textOption.get());
284 } catch (OutOfMemoryError err)
286 System.out.println("########################\n" + "OUT OF MEMORY "
287 + generatedFile + "\n" + "########################");
288 new OOMWarning("Creating Image for " + generatedFile, err);
289 } catch (Exception e)
292 setProgressMessage(MessageManager
293 .formatMessage("info.error_creating_file", getDescription()));
298 * Builds and writes the image to the file specified by field
299 * <code>generatedFile</code>
301 * @param textCharacters
302 * true for Text character rendering, false for Lineart
304 protected void doOutput(boolean textCharacters)
308 AlignmentDimension aDimension = ap.getAlignmentDimension();
309 SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
310 aDimension.getWidth(), aDimension.getHeight());
311 SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
312 aDimension.getWidth(), aDimension.getHeight());
313 if (!textCharacters) // Lineart selected
315 idPanelGraphics.setRenderingHint(
316 SVGHints.KEY_DRAW_STRING_TYPE,
317 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
318 alignPanelGraphics.setRenderingHint(
319 SVGHints.KEY_DRAW_STRING_TYPE,
320 SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
322 if (ap.av.getWrapAlignment())
324 printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
329 printUnwrapped(aDimension.getWidth(), aDimension.getHeight(),
330 0, idPanelGraphics, alignPanelGraphics);
333 String idPanelSvgData = idPanelGraphics.getSVGDocument();
334 String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
335 String jsonData = getBioJSONData();
336 String htmlData = getHtml(idPanelSvgData, alignPanelSvgData,
337 jsonData, ap.av.getWrapAlignment());
338 FileOutputStream out = new FileOutputStream(generatedFile);
339 out.write(htmlData.getBytes());
342 setProgressMessage(MessageManager
343 .formatMessage("status.export_complete", getDescription()));
345 } catch (Exception e)
348 setProgressMessage(MessageManager
349 .formatMessage("info.error_creating_file", getDescription()));
354 protected String getDescription()