20130313
[gdash.git] / src / editor / exporthtml.cpp
blobf01eeb3489e39bd31b7f079b8c99c18512176a6e
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "config.h"
19 #include <glib.h>
20 #include <gtk/gtk.h>
21 #include <glib/gi18n.h>
23 #include "cave/caveset.hpp"
24 #include "cave/cavestored.hpp"
25 #include "cave/titleanimation.hpp"
26 #include "misc/logger.hpp"
27 #include "misc/printf.hpp"
28 #include "cave/gamerender.hpp"
29 #include "editor/editorcellrenderer.hpp"
30 #include "settings.hpp"
31 #include "gtk/gtkpixbuffactory.hpp"
33 /**
34 * Save caveset as html gallery.
35 * @param htmlname filename
36 * @param window show progress bar in a small dialog, transient for this window, if not NULL
38 void gd_save_html(char *htmlname, GtkWidget *window, CaveSet &caveset) {
39 char *pngbasename; /* used as a base for img src= tags */
40 char *pngoutbasename; /* used as a base name for png output files */
41 GtkWidget *dialog=NULL, *progress=NULL;
42 std::string contents;
43 GError *error=NULL;
45 if (window) {
46 dialog=gtk_dialog_new();
47 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
48 progress=gtk_progress_bar_new ();
49 gtk_window_set_title(GTK_WINDOW(dialog), _("Saving HTML gallery"));
50 gtk_box_pack_start_defaults(GTK_BOX (GTK_DIALOG (dialog)->vbox), progress);
51 gtk_widget_show_all(dialog);
54 if (g_str_has_suffix (htmlname, ".html")) {
55 /* has html extension */
56 pngoutbasename=g_strdup(htmlname);
57 *g_strrstr(pngoutbasename, ".html")=0;
59 else {
60 /* has no html extension */
61 pngoutbasename=g_strdup(htmlname);
62 htmlname=g_strdup_printf("%s.html", pngoutbasename);
64 pngbasename=g_path_get_basename(pngoutbasename);
66 contents+="<HTML>\n";
67 contents+="<HEAD>\n";
68 contents+=SPrintf("<TITLE>%ms</TITLE>\n") % caveset.name;
69 contents+="<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n";
70 if (gd_html_stylesheet_filename)
71 contents+=SPrintf("<link rel=\"stylesheet\" href=\"%s\">\n") % gd_html_stylesheet_filename;
72 if (gd_html_favicon_filename)
73 contents+=SPrintf("<link rel=\"shortcut icon\" href=\"%s\">\n") % gd_html_favicon_filename;
74 contents+="</HEAD>\n\n";
76 contents+="<BODY>\n";
78 // CAVESET DATA
79 contents+=SPrintf("<H1>%ms</H1>\n") % caveset.name;
80 /* if the game has its own title screen */
81 if (caveset.title_screen!="") {
82 GTKPixbufFactory pf;
84 /* create the title image and save it */
85 std::vector<Pixbuf *> title_images = get_title_animation_pixbuf(caveset.title_screen, caveset.title_screen_scroll, true, pf);
86 if (!title_images.empty()) {
87 GdkPixbuf *title_image=static_cast<GTKPixbuf *>(title_images[0])->get_gdk_pixbuf();
89 char *pngname=g_strdup_printf("%s_%03d.png", pngoutbasename, 0); /* it is the "zeroth" image */
90 gdk_pixbuf_save(title_image, pngname, "png", &error, "compression", "9", NULL);
91 if (error) {
92 gd_warning(error->message);
93 g_error_free(error);
94 error=NULL;
96 g_free(pngname);
98 contents+=SPrintf("<IMAGE SRC=\"%s_%03d.png\" WIDTH=\"%d\" HEIGHT=\"%d\">\n") % pngbasename % 0 % gdk_pixbuf_get_width(title_image) % gdk_pixbuf_get_height(title_image);
99 contents+="<BR>\n";
101 delete title_images[0];
104 contents+="<TABLE>\n";
105 contents+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Caves") % caveset.caves.size();
106 if (caveset.author!="")
107 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Author") % caveset.author;
108 if (caveset.description!="")
109 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Description") % caveset.description;
110 if (caveset.www!="")
111 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("WWW") % caveset.www;
112 if (caveset.remark!="")
113 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Remark") % caveset.remark;
114 if (caveset.story!="")
115 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Story") % caveset.story;
116 contents+="</TABLE>\n";
118 /* cave names, descriptions, hrefs */
119 contents+="<DL>\n";
120 for (unsigned n=0; n<caveset.caves.size(); n++) {
121 CaveStored &cave=caveset.cave(n);
123 contents+=SPrintf("<DT><A HREF=\"#cave%03d\">%s</A></DT>\n") % (n+1) % cave.name;
124 if (cave.description!="")
125 contents+=SPrintf(" <DD>%s</DD>\n") % cave.description;
127 contents+="</DL>\n\n";
129 GTKPixbufFactory pf;
130 EditorCellRenderer cr(pf, gd_theme);
131 for (unsigned i=0; i<caveset.caves.size(); i++) {
132 if (progress) {
133 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progress), (float) i/caveset.caves.size());
134 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), CPrintf("%d/%d") % i % caveset.caves.size());
135 gdk_window_process_all_updates();
138 /* rendering cave for png: seed=0 */
139 CaveStored &cave=caveset.cave(i);
140 CaveRendered rendered(cave, 0, 0);
142 /* check cave to see if we have amoeba or magic wall. properties will be shown in html, if so. */
143 bool has_amoeba=false, has_magic=false;
144 for (int y=0; y<cave.h; y++)
145 for (int x=0; x<cave.w; x++) {
146 if (rendered.map(x, y)==O_AMOEBA)
147 has_amoeba=true;
148 if (rendered.map(x, y)==O_MAGIC_WALL)
149 has_magic=true;
150 break;
153 /* cave header */
154 contents+=SPrintf("<A NAME=\"cave%03d\"></A>\n<H2>%ms</H2>\n") % (i+1) % cave.name;
156 /* save image */
157 char *pngname=g_strdup_printf("%s_%03d.png", pngoutbasename, i+1);
158 GdkPixbuf *pixbuf=gd_drawcave_to_pixbuf(&rendered, cr, 0, 0, true, false);
159 GError *error=NULL;
160 gdk_pixbuf_save(pixbuf, pngname, "png", &error, "compression", "9", NULL);
161 if (error) {
162 gd_warning(error->message);
163 g_error_free(error);
164 error=NULL;
166 g_free(pngname);
167 contents+=SPrintf("<IMAGE SRC=\"%s_%03d.png\" WIDTH=\"%d\" HEIGHT=\"%d\">\n") % pngbasename % (i+1) % gdk_pixbuf_get_width(pixbuf) % gdk_pixbuf_get_height(pixbuf);
168 g_object_unref(pixbuf);
170 contents+="<BR>\n";
171 contents+="<TABLE>\n";
172 if (cave.author!="")
173 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Author") % cave.author;
174 if (cave.description!="")
175 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Description") % cave.description;
176 if (cave.remark!="")
177 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Remark") % cave.remark;
178 if (cave.story!="")
179 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Story") % cave.story;
180 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Type") % (cave.intermission ? _("Intermission") : _("Normal cave"));
181 contents+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Selectable as start") % (cave.selectable ? _("Yes") : _("No"));
182 contents+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Diamonds needed") % cave.level_diamonds[0];
183 contents+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Diamond value") % cave.diamond_value;
184 contents+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Extra diamond value") % cave.extra_diamond_value;
185 contents+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Time (s)") % cave.level_time[0];
186 if (has_amoeba)
187 contents+=SPrintf("<TR><TH>%ms<TD>%d, %d\n") % _("Amoeba threshold and time (s)") % cave.level_amoeba_threshold[0] % cave.level_amoeba_time[0];
188 if (has_magic)
189 contents+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Magic wall milling time (s)") % cave.level_magic_wall_time[0];
190 contents+="</TABLE>\n";
192 contents+="\n";
195 contents+="</BODY>\n";
196 contents+="</HTML>\n";
197 g_free(pngoutbasename);
198 g_free(pngbasename);
200 if (!g_file_set_contents(htmlname, contents.c_str(), contents.size(), &error)) {
201 /* could not save properly */
202 gd_critical(error->message);
203 g_error_free(error);
206 if (dialog)
207 gtk_widget_destroy(dialog);