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.
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"
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
;
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;
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
);
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";
79 contents
+=SPrintf("<H1>%ms</H1>\n") % caveset
.name
;
80 /* if the game has its own title screen */
81 if (caveset
.title_screen
!="") {
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
);
92 gd_warning(error
->message
);
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
);
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
;
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 */
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";
130 EditorCellRenderer
cr(pf
, gd_theme
);
131 for (unsigned i
=0; i
<caveset
.caves
.size(); i
++) {
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
)
148 if (rendered
.map(x
, y
)==O_MAGIC_WALL
)
154 contents
+=SPrintf("<A NAME=\"cave%03d\"></A>\n<H2>%ms</H2>\n") % (i
+1) % cave
.name
;
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);
160 gdk_pixbuf_save(pixbuf
, pngname
, "png", &error
, "compression", "9", NULL
);
162 gd_warning(error
->message
);
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
);
171 contents
+="<TABLE>\n";
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
;
177 contents
+=SPrintf("<TR><TH>%ms<TD>%ms\n") % _("Remark") % cave
.remark
;
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];
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];
189 contents
+=SPrintf("<TR><TH>%ms<TD>%d\n") % _("Magic wall milling time (s)") % cave
.level_magic_wall_time
[0];
190 contents
+="</TABLE>\n";
195 contents
+="</BODY>\n";
196 contents
+="</HTML>\n";
197 g_free(pngoutbasename
);
200 if (!g_file_set_contents(htmlname
, contents
.c_str(), contents
.size(), &error
)) {
201 /* could not save properly */
202 gd_critical(error
->message
);
207 gtk_widget_destroy(dialog
);