#include "html.h"
#include
static gint counter = 0;
void
html_init_config (HtmlConfig *config)
{
g_assert (config);
config->nodes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
HtmlFile *
html_file_new (HtmlConfig *config, const gchar *name, const gchar *title)
{
HtmlFile *file;
xmlNodePtr topnode, head, node;
file = g_new0 (HtmlFile, 1);
file->name = g_strdup (name);
file->doc = xmlNewDoc ("1.0");
topnode = xmlNewDocNode (file->doc, NULL, "html", NULL);
xmlDocSetRootElement (file->doc, topnode);
/* head */
head = xmlNewChild (topnode, NULL, "head", NULL);
node = xmlNewChild (head, NULL, "meta", NULL);
xmlSetProp (node, "content", "charset=ISO-8859-1");
xmlSetProp (node, "http-equiv", "content-type");
node = xmlNewChild (head, NULL, "title", title);
node = xmlNewChild (head, NULL, "style",
"body { "
" margin: 0px; padding: 0px; border:0px; "
" font: 8pt/16pt georgia; "
" color: #555753; "
" margin: 5px; "
" }"
""
"a:visited, a:link { "
" text-decoration: none ; color: #4085cd; "
"}"
""
"a:hover { "
" text-decoration: none; color: #FF0000; "
"}"
""
"p { "
" font: 8pt/16pt georgia; "
" margin-top: 0px; "
" text-align: justify;"
" }"
"h2 { "
" font: italic normal 14pt georgia; "
" letter-spacing: 1px; "
" margin-bottom: 0px; "
" color: #7D775C;"
" }"
""
"table {"
" font-size: 8pt;"
" /*border: 1pt solid #A8E775;*/"
" padding: 3px;"
"}"
""
"tr {"
" background: #EFEEEF;"
"}"
""
".none {"
" list-style : none;"
" padding-left: 0px;"
"}"
""
".error {"
" background-color: #FF8888;"
" font: bold;"
" /*font-size: medium;*/"
"}"
""
".warning {"
" color: #ff9900;"
" font: bold;"
" /*font-size: medium;*/"
"}"
""
".notice {"
" color: #22bb00;"
" font: bold;"
" /*font-size: medium;*/"
"}"
""
"#inactive {"
" background-color: #CCCCFF;"
"}"
""
".null {"
" color: lightblue;"
"}"
);
/* body */
node = xmlNewChild (topnode, NULL, "body", NULL);
file->body = node;
/* title */
node = xmlNewChild (file->body, NULL, "h1", title);
xmlSetProp (node, "class", "title");
/* toc */
file->toc = xmlNewChild (file->body, NULL, "ul", _("Table of contents"));
xmlSetProp (file->toc, "class", "none");
/* add to @config's list of files */
config->all_files = g_slist_append (config->all_files, file);
return file;
}
gboolean
html_file_write (HtmlFile *file, HtmlConfig *config)
{
gchar *str;
str = g_strdup_printf ("%s/%s", config->dir, file->name);
gint i;
i = xmlSaveFormatFile (str, file->doc, TRUE);
if (i == -1)
g_warning (_("Error writing XML file %s"), str);
g_free (str);
return i!=-1;
}
void
html_file_free (HtmlFile *file)
{
xmlFreeDoc (file->doc);
g_free (file->name);
g_free (file);
}
void
html_declare_node (HtmlConfig *config, const gchar *path, xmlNodePtr node)
{
html_declare_node_own (config, g_strdup (path), node);
}
void
html_declare_node_own (HtmlConfig *config, gchar *path, xmlNodePtr node)
{
xmlNodePtr enode;
enode = g_hash_table_lookup (config->nodes, path);
if (enode) {
g_warning ("Node path %s is already attributed", path);
g_free (path);
return;
}
g_hash_table_insert (config->nodes, path, node);
/*g_print ("--- Added node @ %s\n", path);*/
}
/*
* if @link_to starts with a '/' then a # is prepended (internal link)
*/
void
real_html_add_link_to_node (xmlNodePtr node, const gchar *text, const gchar *link_to)
{
xmlNodePtr href;
gchar *tmp;
href = xmlNewNode (NULL, "a");
tmp = g_strdup_printf (" [%s] ", text);
xmlNodeSetContent (href, tmp);
g_free (tmp);
if (node->children) {
xmlNodePtr sibl;
sibl = node->children;
while (sibl && xmlNodeIsText (sibl))
sibl = sibl->next;
if (sibl)
xmlAddPrevSibling (sibl, href);
else
xmlAddChild (node, href);
}
else
xmlAddChild (node, href);
if (*link_to == '/') {
tmp = g_strdup_printf ("#%s", link_to);
xmlSetProp (href, "href", tmp);
g_free (tmp);
}
else
xmlSetProp (href, "href", link_to);
}
void
html_add_link_to_node (HtmlConfig *config, const gchar *nodepath, const gchar *text, const gchar *link_to)
{
xmlNodePtr node;
node = g_hash_table_lookup (config->nodes, nodepath);
if (!node) {
g_warning ("Can't link non existant node '%s'", nodepath);
return;
}
real_html_add_link_to_node (node, text, link_to);
}
void
html_add_to_toc (HtmlConfig *config, HtmlFile *file, const gchar *text, const gchar *link_to)
{
xmlNodePtr li;
li = xmlNewChild (file->toc, NULL, "li", NULL);
real_html_add_link_to_node (li, text, link_to);
}
xmlNodePtr
html_add_header (HtmlConfig *config, HtmlFile *file, const gchar *text)
{
xmlNodePtr hnode, ntmp;
gchar *tmp;
hnode = xmlNewChild (file->body, NULL, "h2", text);
tmp = g_strdup_printf ("/a/%d", counter++);
html_add_to_toc (config, file, text, tmp);
ntmp = xmlNewChild (hnode, NULL, "a", "");
xmlSetProp (ntmp, "name", tmp);
g_free (tmp);
return hnode;
}
void
html_mark_path_error (HtmlConfig *config, const gchar *nodepath)
{
xmlNodePtr node;
node = g_hash_table_lookup (config->nodes, nodepath);
if (!node) {
g_warning ("Can't link non existant node '%s'", nodepath);
return;
}
html_mark_node_error (config, node);
}
void
html_mark_node_error (HtmlConfig *config, xmlNodePtr node)
{
xmlSetProp (node, "class", "error");
}
void
html_mark_node_warning (HtmlConfig *config, xmlNodePtr node)
{
xmlSetProp (node, "class", "warning");
}
void
html_mark_node_notice (HtmlConfig *config, xmlNodePtr node)
{
xmlSetProp (node, "class", "notice");
}
xmlNodePtr
html_render_attribute_str (xmlNodePtr parent, const gchar *node_type,
const gchar *att_name, const gchar *att_val)
{
xmlNodePtr node;
gchar *tmp;
tmp = g_strdup_printf ("%s = %s", att_name, att_val);
node = xmlNewChild (parent, NULL, node_type, tmp);
g_free (tmp);
return node;
}
xmlNodePtr
html_render_attribute_bool (xmlNodePtr parent, const gchar *node_type,
const gchar *att_name, gboolean att_val)
{
xmlNodePtr node;
gchar *tmp;
tmp = g_strdup_printf ("%s = %s", att_name, att_val ? _("Yes") : _("No"));
node = xmlNewChild (parent, NULL, node_type, tmp);
g_free (tmp);
return node;
}
xmlNodePtr
html_render_data_model (xmlNodePtr parent, GdaDataModel *model)
{
xmlNodePtr node, tr, td;
gint rows, cols, i;
g_return_val_if_fail (GDA_IS_DATA_MODEL (model), NULL);
node = xmlNewChild (parent, NULL, "table", "");
cols = gda_data_model_get_n_columns (model);
rows = gda_data_model_get_n_rows (model);
/* set the table structure */
tr = xmlNewChild (node, NULL, "tr", NULL);
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
xmlFreeNode (node);
return NULL;
}
td = xmlNewChild (tr, NULL, "th", gda_column_get_name (column));
}
/* add the model data to the XML output */
if (rows > 0) {
gint r, c;
for (r = 0; r < rows; r++) {
tr = xmlNewChild (node, NULL, "tr", "");
for (c = 0 ; c < cols; c++) {
GdaValue *value;
gchar *str;
value = (GdaValue *) gda_data_model_get_value_at (model, c, r);
if (!value || gda_value_is_null (value)) {
xmlNodePtr p;
td = xmlNewChild (tr, NULL, "td", NULL);
p = xmlNewChild (td, NULL, "p", "NULL");
xmlSetProp (p, "class", "null");
}
else {
if (gda_value_get_type (value) == GDA_VALUE_TYPE_BOOLEAN)
str = g_strdup (gda_value_get_boolean (value) ? "TRUE" : "FALSE");
else
str = gda_value_stringify (value);
td = xmlNewChild (tr, NULL, "td", str);
g_free (str);
}
}
}
}
return node;
}
xmlNodePtr
html_render_data_model_all (xmlNodePtr parent, GdaDataModel *model)
{
xmlNodePtr node, tr, td;
gint cols, i;
gchar *str;
g_return_val_if_fail (GDA_IS_DATA_MODEL (model), NULL);
/* model name and ID */
str = g_strdup_printf ("Model of class %s: name=%s ID=%s", G_OBJECT_TYPE_NAME(model),
gda_object_get_name (GDA_OBJECT (model)),
gda_object_get_id (GDA_OBJECT (model)));
node = xmlNewChild (parent, NULL, "h3", str);
g_free (str);
/* show the columns */
node = xmlNewChild (parent, NULL, "table", "");
cols = gda_data_model_get_n_columns (model);
tr = xmlNewChild (node, NULL, "tr", NULL);
/* name */
td = xmlNewChild (tr, NULL, "th", "Column attributes / columns");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "th", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "th", gda_column_get_name (column));
}
/* title */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "title");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_title (column));
}
/* dbms type */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "dbms type");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_dbms_type (column));
}
/* gda type */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "GDA type");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_type_to_string (gda_column_get_gda_type (column)));
}
/* NOT NULL */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "not NULL ?");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_allow_null (column) ? "FALSE" : "TRUE");
}
/* Primary key */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "primary key ?");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_primary_key (column) ? "YES" : "NO");
}
/* Unique */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "unique ?");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_unique_key (column) ? "YES" : "NO");
}
/* References */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "references");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_references (column));
}
/* Auto increment */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "Auto increment ?");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_auto_increment (column) ? "YES" : "NO");
}
/* defined size */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "defined size");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else {
gchar *str;
str = g_strdup_printf ("%ld", gda_column_get_defined_size (column));
td = xmlNewChild (tr, NULL, "td", str);
g_free (str);
}
}
/* table */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "table");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_table (column));
}
/* default value */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "default value");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else {
gchar *str = NULL;
const GdaValue *value;
value= gda_column_get_default_value (column);
if (value)
str = gda_value_stringify ((GdaValue *) value);
else
str = "";
td = xmlNewChild (tr, NULL, "td", str);
if (value)
g_free (str);
}
}
/* caption */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "caption");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else
td = xmlNewChild (tr, NULL, "td", gda_column_get_caption (column));
}
/* scale */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "scale");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else {
gchar *str;
str = g_strdup_printf ("%ld", gda_column_get_scale (column));
td = xmlNewChild (tr, NULL, "td", str);
g_free (str);
}
}
/* position */
tr = xmlNewChild (node, NULL, "tr", NULL);
td = xmlNewChild (tr, NULL, "td", "position");
for (i = 0; i < cols; i++) {
GdaColumn *column;
column = gda_data_model_describe_column (model, i);
if (!column) {
td = xmlNewChild (tr, NULL, "td", "Error");
xmlSetProp (td, "class", "error");
}
else {
gchar *str;
str = g_strdup_printf ("%d", gda_column_get_position (column));
td = xmlNewChild (tr, NULL, "td", str);
g_free (str);
}
}
html_render_data_model (parent, model);
}