// // File: hdsGenerate.cpp // // Legal Notice: This file is part of the HadronZoo C++ Class Library. Copyright 2025 HadronZoo Project (http://www.hadronzoo.com) // // The HadronZoo C++ Class Library is free software: You can redistribute it, and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free // Software Foundation, either version 3 of the License, or any later version. // // The HadronZoo C++ Class Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR // A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses. //
#include <fstream> #include <cmath>
#include <unistd.h> #include <netdb.h> #include <openssl/ssl.h>
#include "hzDissemino.h"
using namespace std ;
/* ** Prototypes */
const char* Exec2Txt (Exectype eType) ;
/* ** Shorthand for generating HTML */
// Google script static hzString s_Recaptcha = "<script src=\"https://www.google.com/recaptcha/api.js\" async defer></script>\n" ;
// Standard meta tags for generated pages static hzString s_std_metas = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n" "<meta http-equiv=\"Expires\" content=\"-1\"/>\n" "<meta http-equiv=\"Cache-Control\" content=\"no-cache\"/>\n" "<meta http-equiv=\"Cache-Control\" content=\"no-store\"/>\n" "<meta http-equiv=\"Pragma\" content=\"no-cache\"/>\n" "<meta http-equiv=\"Pragma\" content=\"no-store\"/>\n" ;
/* ** Variables */
static hzString tagInput = "input" ; // String for HTML tag input static hzString tagImg = "img" ; // String for HTML tag img static hzString tagBr = "br" ; // String for HTML tag br
extern hzString _dsmScript_ckEmail ; // Javascript to validate email address extern hzString _dsmScript_ckUrl ; // Javascript to validate URL extern hzString _dsmScript_ckExists ; // Javascript to run AJAX check for value already exists extern hzString _dsmScript_tog ; // Javascript to toggle nav-tree items extern hzString _dsmScript_loadArticle ; // Javascript to load aricles upon selection from nav-tree extern hzString _dsmScript_navtree ; // Javascript to display nav-tree extern hzString _dsmScript_gwp ; // Javascript to obtain window params
extern hzString _hzGlobal_str_TRUE ; // For flowchart decision boxes extern hzString _hzGlobal_str_FALSE ; // For flowchart decision boxes extern hzString _hzGlobal_str_START ; // For flowchart START stadium
/* ** Pull down menu driver */
void hdsNavbar::Generate (hzChain& Z, hzHttpEvent* pE, uint32_t& nLine) { // Aggregates into the supplied chain, the HTML nessesary to display the navbar // // Arguments: 1) Z The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsNavbar::Generate") ;
hzList<hzString>::Iter si ; // Subjects iterator
hzPair p ; // NV pair representing page url and page title hdsInfo* pInfo = 0 ; // Session //hdsSubject* pSubj ; // Subject hzString subject ; // Subject hdsResource* pPage ; // Page within subject uint32_t x ; // Subhect iterator uint32_t y ; // Page iterator (within subject) uint32_t nLo ; // First page of a given subject uint32_t nHi ; // Last page of a given subject
if (pE) pInfo = (hdsInfo*) pE->Session() ;
if (m_JS) { Z << "<script language=\"javascript\" src=\"/jsc/navbarItems.js\"></script>\n" ; Z << "<script language=\"javascript\" src=\"/jsc/navbarMenu.js\"></script>\n" ; return ; }
Z << "\n<table cellspacing='0' cellpadding='0' width='90%' background-color='#000000' border='0'>\n" "<tr>\n" "\t<td width='1'> </td><td height='20' valign='center'>\n" ;
// Prepare headings #if 0 for (x = 0 ; x < m_pApp->m_vecPgSubjects.Count() ; x++) { pSubj = m_pApp->m_vecPgSubjects[x] ;
if (!pSubj->pglist.Count()) continue ;
if (pSubj->pglist.Count() <= 1) Z.Printf("\t<span id='Pdm%d' class='measure'><a href='%s' onmouseover='hideLast()' class='top'>", x, *pSubj->first) ; else Z.Printf("\t<span id='Pdm%d' class='measure'><a href=\"#\" class='top' onmouseover='doSub(%d)' onclick='return false'>", x, x) ;
Z.Printf("%s </a></span>\n", *pSubj->subject) ; } #endif for (si = m_pApp->m_lstPgSubjects, x = 0 ; si.Valid() && x < m_pApp->m_lstPgSubjects.Count() ; si++, x++) { subject = si.Element() ;
if (m_pApp->m_lstPgSubjects.Count() == 1) Z.Printf("\t<span id='Pdm%d' class='measure'><a href='%s' onmouseover='hideLast()' class='top'>", x, *subject) ; else Z.Printf("\t<span id='Pdm%d' class='measure'><a href=\"#\" class='top' onmouseover='doSub(%d)' onclick='return false'>", x, x) ;
Z.Printf("%s </a></span>\n", *subject) ; } Z << "\t</td>\n" "</tr>\n" "</table>\n" ;
// Prepare lists (sub-menus) #if 0 for (x = 0 ; x < m_pApp->m_vecPgSubjects.Count() ; x++) { Z.Printf("<div id='Sub%d' style='visibility:hidden;position:absolute;width:relative;' onmouseover='IEBum(0,%d)' onmouseout='IEBum(1,%d)'>\n", x, x, x) ; Z << "\t<table border='0' background-color='#000000' cellspacing=0 cellpadding=0 width='200'>\n" ;
pSubj = m_pApp->m_vecPgSubjects[x] ;
if (!pSubj->pglist.Count()) continue ;
for (y = 0 ; y < pSubj->pglist.Count() ; y++) { pPage = pSubj->pglist[y] ;
if (pPage->m_resAccess == ACCESS_PUBLIC || (pPage->m_resAccess == ACCESS_NOBODY && (!pInfo || !(pInfo->m_Access & ACCESS_MASK))) || (pInfo && (pInfo->m_Access & ACCESS_ADMIN || (pInfo->m_Access & ACCESS_MASK) == pPage->m_resAccess))) Z.Printf("\t<tr><td height='13' valign='center'> <a href='%s' id='link' class='top' onmouseover='IEBum(0,%d)'>%s</a></td></tr>\n", *pPage->m_Url, x, *pPage->m_Title) ; }
Z << "\t</table>\n</div>\n" ; } #endif for (si = m_pApp->m_lstPgSubjects, x = 0 ; si.Valid() && x < m_pApp->m_lstPgSubjects.Count() ; si++, x++) { subject = si.Element() ; Z.Printf("<div id='Sub%d' style='visibility:hidden;position:absolute;width:relative;' onmouseover='IEBum(0,%d)' onmouseout='IEBum(1,%d)'>\n", x, x, x) ; Z << "\t<table border='0' background-color='#000000' cellspacing=0 cellpadding=0 width='200'>\n" ;
nLo = m_pApp->m_mapSubj2Res.First(subject) ; if (nLo < 0) continue ; nHi = m_pApp->m_mapSubj2Res.Last(subject) ;
for (y = nLo ; y <= nHi ; y++) { pPage = m_pApp->m_mapSubj2Res.GetObj(y) ;
if (pPage->m_resAccess == ACCESS_PUBLIC || (pPage->m_resAccess == ACCESS_NOBODY && (!pInfo || !(pInfo->m_Access & ACCESS_MASK))) || (pInfo && (pInfo->m_Access & ACCESS_ADMIN || (pInfo->m_Access & ACCESS_MASK) == pPage->m_resAccess))) Z.Printf("\t<tr><td height='13' valign='center'> <a href='%s' id='link' class='top' onmouseover='IEBum(0,%d)'>%s</a></td></tr>\n", *pPage->m_Url, x, *pPage->m_Title) ; }
Z << "\t</table>\n</div>\n" ; } }
/* ** Error message */
void hdsApp::_doHead (hzChain& Z, const char* cpPage) { // Formulate a standard HTML header (the <head> tag) and agregate it to the supplied chain. The title is set to the supplied value and the header // contains a link to the application's stylesheet. // // Arguments: 1) Z The target chain // 2) cpPage The page title // // Returns: None
_hzfunc("hdsApp::_doHead") ;
Z << "<!DOCTYPE html>\n" "<html>\n" "<head>\n" "<title>" << cpPage << "</title>\n" << s_std_metas << "<link rel=\"stylesheet\" href=\"" << m_namCSS << "\">\n" "</head>\n\n" ; //"<link rel=\"icon\" href=\"data:;base64,iVBORw0KGgo=\">\n" }
void hdsApp::_doHeadR (hzChain& Z, const char* cpPage, const char* cpUrl, int nDelay) { // Formulate a standard HTML header as with _doHead() but with the addition of a <meta> refresh tag to direct the browser to another URL after a // stated time interval. // // Arguments: 1) Z The target chain // 2) cpPage The page title // 3) cpUrl The redirection RL // 4) nDelay The delay in seconds // // Returns: None
_hzfunc("hdsApp::_doHeadR") ;
Z << "<!DOCTYPE html>\n" "<html>\n" "<head>\n" "<title>" << cpPage << "</title>\n" ;
if (!nDelay) nDelay = 10 ; if (cpUrl) Z.Printf("<meta http-equiv=\"Refresh\" content=\"%d; url='%s'\">\n", nDelay, cpUrl) ; else Z.Printf("<meta http-equiv=\"Refresh\" content=\"%d\">\n", nDelay) ;
Z << s_std_metas << "<link rel=\"stylesheet\" href=\"" << m_namCSS << "\">\n" "</head>\n\n" ; }
// FnGrp: hdsApp::SendErrorPage // // Generate HTML to display a system error report. This will name the function in which the error occured and the error message // // Returns: None // // Func: hdsApp::_xerror (hzHttpEvent*, HttpRC, const char*, const char* ...) // Func: hdsApp::_xerror (hzHttpEvent*, HttpRC, const char*, hzChain&)
void hdsApp::SendErrorPage (hzHttpEvent* pE, HttpRC rv, const char* func, const char* va_alist ...) { // Arguments: 1) pE The current HTTP event // 2) rv The required HTML return code // 3) func The function name // 4) va_alist The error message either as a varargs string // // Returns: None
_hzfunc("hdsApp::SendErrorPage(1)") ;
va_list ap1 ; // Variable argument list hzChain C ; // Output chain hzChain E ; // Error chain
if (!pE) { hzerr(E_ARGUMENT, "No HTTP Event") ; return ; }
va_start(ap1, va_alist) ;
E._vainto(va_alist, ap1) ;
_doHead(C, "Error") ; C << "<body marginwidth=\"0\" marginheight=\"0\" leftmargin=\"0\" topmargin=\"0\">\n\n" ; C << "<center><h2>Oops!</h2></center>\n" ; C << "<table width=\"300\" align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"fld\">\n" ; C << "<tr height=\"100\"><td>Function " << func << " Has produced the following error<td></tr>\n" ; C << "<tr height=\"350\"><td>" << E << "</td></tr>\n" ; C.Printf("<tr height=\"150\"><td><input type=\"button\" value=\"Go Back\" onclick=\"window.location.href='%s'\"></td></tr>\n", *pE->Referer()) ; C << "</table>\n\n</body>\n</html>\n" ;
pE->SendRawChain(rv, HMTYPE_TXT_HTML, C, 0, false) ; }
void hdsApp::SendErrorPage (hzHttpEvent* pE, HttpRC rv, const char* func, hzChain& error) { // Arguments: 1) pE The current HTTP event // 2) rv The required HTML return code // 3) func The function name // 4) error The error message as a preformulated chain // // Returns: None
_hzfunc("hdsApp::SendErrorPage(1)") ;
hzChain C ; // Output chain
if (!pE) { hzerr(E_ARGUMENT, "No HTTP Event") ; return ; }
_doHead(C, "Error") ; C << "<body marginwidth=\"0\" marginheight=\"0\" leftmargin=\"0\" topmargin=\"0\">\n\n" ; C << "<center><h2>Oops!</h2></center>\n" ; C << "<table width=\"300\" align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"fld\">\n" ; C << "<tr height=\"100\"><td>Function " << func << " Has produced the following error<td></tr>\n" ; C << "<tr height=\"350\"><td>" << error << "</td></tr>\n" ; C.Printf("<tr height=\"150\"><td><input type=\"button\" value=\"Go Back\" onclick=\"window.location.href='%s'\"></td></tr>\n", *pE->Referer()) ; C << "</table>\n\n</body>\n</html>\n" ;
pE->SendRawChain(rv, HMTYPE_TXT_HTML, C, 0, false) ; }
/* ** Web Component display functions */
void hdsButton::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Aggregate to the supplied chain, HTML to manifest a button. // // The button can be a link (GET request) OR a form action (POST request). In the link case, button member m_Linkto will give the location. In the form action case, there will // need to be submission URL which is obtained from the form reference (given in HTTP event variable m_pContextForm). // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsButton::Generate") ;
hdsFormref* pFR ; // Form reference hzString url ; // URL to use (if form action) uint32_t x ; // Indent counter
if (m_Line != nLine) { C.AddByte(CHAR_NL) ; for (x = m_Indent ; x ; x--) C.AddByte(CHAR_TAB) ; nLine = m_Line ; }
if (pE->m_pContextForm) { pFR = (hdsFormref*) pE->m_pContextForm ; x = m_pApp->m_FormRef2Url.First(pFR) ; if (x >= 0) url = m_pApp->m_FormRef2Url.GetObj(x + m_Resv - 1) ; }
if (m_Formname) { if (url) C.Printf("<input type=\"submit\" formaction=\"%s\" value=\"%s\">", *url, *m_strContent) ; else C.Printf("<input type=\"submit\" value=\"%s\">", *m_strContent) ; } else { if (pE && m_Linkto[0] == CHAR_PERCENT) C.Printf("<input type=\"button\" value=\"%s\" onclick=\"window.location.href='%s'\">", *m_strContent, *m_pApp->ConvertText(m_Linkto, pE)) ; else C.Printf("<input type=\"button\" value=\"%s\" onclick=\"window.location.href='%s'\">", *m_strContent, *m_Linkto) ; } }
void hdsRecap::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Aggregates to the supplied chain (the HTML body), the RECAPTCHA tag responsible for the appearence of the google 'human being' test icon. This // will contain the public key which must be supplied as an argument to the <project> tag. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsRecap::Generate") ;
if (m_pApp->m_KeyPublic) C.Printf("<div class=\"g-recaptcha\" data-sitekey=\"%s\"></div>", *m_pApp->m_KeyPublic) ; else C << "<div class=\"g-recaptcha\" invalid data-sitekey=\"not supplied\"></div>" ; }
void hdsDirlist::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Does not in itself produce HTML but the subtags do. The complete set of subtags are called for each member of the list the hdsTable controls. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsDirlist::Generate") ;
hzMapS <hzString,hzDirent> byName ; // Directory entries by name hzMapM <uint32_t,hzDirent> byDate ; // Directory entries by name
hzVect <hzDirent> dirents ; // List of directories hzList <hdsCol>::Iter ci ; // Column iterator
hzDirent de ; // Directory entry hzXDate date ; // Last mod date hdsCol col ; // Column hzAtom atom ; // Current value hdsVE* pVE ; // Visible entitiy hzString apath ; // Translated path (absolute so includes doc root) hzString rpath ; // Translated path (relative to doc root) hzString crit ; // Resolved criteria uint32_t nDirs ; // Number of directories uint32_t nFiles ; // Number of files uint32_t x ; // Table controller uint32_t y ; // Table controller
// Do the heading C.AddByte(CHAR_NL) ; for (x = m_Indent ; x ; x--) C.AddByte(CHAR_TAB) ;
// Obtain resolved parmeters rpath = m_pApp->ConvertText(m_Directory, pE) ; apath = m_pApp->m_Docroot + rpath ; crit = m_pApp->ConvertText(m_Criteria, pE) ;
// Provide filelist matching the criteria ReadDir(dirents, *apath, *crit) ;
if (!dirents.Count()) { // Print the ifnone tags for (pVE = m_pNone ; pVE ; pVE = pVE->Sibling()) pVE->Generate(C, pE, nLine) ; } else { // Sort directory entries for (nDirs = nFiles = x = 0 ; x < dirents.Count() ; x++) { de = dirents[x] ;
if (de.IsDir()) nDirs++ ; else nFiles++ ;
if (m_Order == 1 || m_Order == 2) byName.Insert(de.strName(), de) ; if (m_Order == 3 || m_Order == 4) byDate.Insert(de.Mtime(), de) ; }
if (m_Order) { // Now place back in array if (m_Order == 1) for (x = 0 ; x < dirents.Count() ; x++) dirents[x] = byName.GetObj(x) ;
if (m_Order == 3) for (x = 0 ; x < dirents.Count() ; x++) dirents[x] = byDate.GetObj(x) ;
if (m_Order == 2) for (y = dirents.Count() - 1, x = 0 ; x < dirents.Count() ; y--, x++) dirents[x] = byName.GetObj(y) ;
if (m_Order == 4) for (y = dirents.Count() - 1, x = 0 ; x < dirents.Count() ; y--, x++) dirents[x] = byDate.GetObj(y) ; } // Create HTML table for listing C.Printf("<table width=\"%d\" align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"%s\">\n", m_Width, *m_CSS) ; C.Printf("<tr valign=\"top\" height=\"20\"><td>Listing %d directories and %d files</td></tr>\n", nDirs, nFiles) ; C.Printf("<tr valign=\"top\" height=\"%d\">\n\t<td>\n", m_Height) ; C.Printf("\t<table width=\"%d\" align=\"center\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\" class=\"%s\">\n", m_Width, *m_CSS) ;
// Do table headers C << "\t<tr>\n" ; for (ci = m_Cols ; ci.Valid() ; ci++) { col = ci.Element() ;
C.Printf("\t<th width=\"%d\">%s</th>\n", col.m_nSize, *col.m_Title) ; } C << "\t</tr>\n" ;
// Do first rows as parent directory if (pE->m_Resarg) { C << "\t<tr>" ; for (ci = m_Cols ; ci.Valid() ; ci++) { col = ci.Element() ;
if (col.m_Title == "Mtime") C << "<td>---</td>" ; else if (col.m_Title == "Type") C << "<td>DIR</td>" ; else if (col.m_Title == "Size") C << "<td>---</td>" ; else if (col.m_Title == "Name") C.Printf("<td><a href=\"%s\">Back to parent dir</a></td>", *m_Directory) ; else C << "<td> </td>" ; } C << "\t</tr>\n" ; }
// Do table rows (directories) for (x = 0 ; x < dirents.Count() ; x++) { de = dirents[x] ; if (!de.IsDir()) continue ;
C << "\t<tr>" ; for (ci = m_Cols ; ci.Valid() ; ci++) { col = ci.Element() ;
if (col.m_Title == "Mtime") { date.SetByEpoch(de.Mtime()) ; C.Printf("<td>%s</td>", *date) ; } else if (col.m_Title == "Type") C << "<td>DIR</td>" ; else if (col.m_Title == "Size") C.Printf("<td alight=\"right\">%s</td>", FormalNumber(de.Size())) ; else if (col.m_Title == "Name") C.Printf("<td><a href=\"%s-%s\"> %s</a></td>", *m_Directory, de.txtName(), de.txtName()) ; else C << "<td> </td>" ; } C << "\t</tr>\n" ; }
// Do table rows (files) for (x = 0 ; x < dirents.Count() ; x++) { de = dirents[x] ; if (de.IsDir()) continue ;
C << "\t<tr>" ; for (ci = m_Cols ; ci.Valid() ; ci++) { col = ci.Element() ;
if (col.m_Title == "Mtime") { date.SetByEpoch(de.Mtime()) ; C.Printf("<td>%s</td>", *date) ; } else if (col.m_Title == "Type") C << "<td>File</td>" ; else if (col.m_Title == "Size") C.Printf("<td alight=\"right\">%s</td>", FormalNumber(de.Size())) ; else if (col.m_Title == "Name") { if (pE->m_Resarg) C.Printf("<td><a href=\"/userdir/%s/%s\"> %s</a></td>", *pE->m_Resarg, de.txtName(), de.txtName()) ; else C.Printf("<td><a href=\"/userdir/%s\"> %s</a></td>", de.txtName(), de.txtName()) ; } else C << "<td> </td>" ; } C << "\t</tr>\n" ; } C << "\t</table>\n</table>\n" ; } }
void hdsTable::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Does not in itself produce HTML but the subtags do. The complete set of subtags are called for each member of the list the hdsTable controls. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsTable::Generate") ;
hzList<hdsCol>::Iter ci ; // Column iterator hzVect<uint32_t> items ; // Items drawn from class member (of table) to be listed as rows
hdbObject obj ; // Retrieved data object hdbIdset srchResult ; // Items selected from applicable repository hdsCol col ; // Column hdsVE* pVE ; // For processing subtags hzAtom atom ; // Current value hzString value ; // Value in session if set uint32_t nFound ; // Table controller uint32_t objId ; // Object id hzEcode rc ; // Return code from Fetch()
// Do the heading C.AddByte(CHAR_NL) ;
// Do the select if (m_Criteria == "all") nFound = m_pRepos->Count() ; else { m_pRepos->Select(srchResult, *m_Criteria) ; nFound = srchResult.Count() ; }
// Display results if (nFound == 0) { // In the event of no objects found, print the ifnone tags for (pVE = m_pNone ; pVE ; pVE = pVE->Sibling()) pVE->Generate(C, pE, nLine) ; } else { // Create HTML table for listing C.Printf("<table width=\"%d\" align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"%s\">\n", m_nWidth, *m_CSS) ; C.Printf("<tr valign=\"top\" height=\"20\"><td>Listing %d objects</td></tr>\n", nFound) ; C.Printf("<tr valign=\"top\" height=\"%d\">\n\t<td>\n", m_nHeight) ; C.Printf("\t<table width=\"%d\" align=\"center\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\" class=\"%s\">\n", m_nWidth, *m_CSS) ;
// Do table headers C << "\t<tr>\n" ; for (ci = m_Cols ; ci.Valid() ; ci++) { col = ci.Element() ;
C.Printf("\t<th width=\"%d\">%s</th>\n", col.m_nSize, *col.m_Title) ; } C << "\t</tr>\n" ;
// Provide filelist matching the criteria obj.Init(m_pRepos->Class()) ;
for (objId = 1 ; objId <= nFound ; objId++) { // Fetch data object rc = m_pRepos->Fetch(obj, objId) ; if (rc != E_OK) break ;
// Now display object as row C << "\t<tr>" ; for (ci = m_Cols ; ci.Valid() ; ci++) { col = ci.Element() ;
//m_pRepos->Fetchval(atom, col.m_mbrNo, objId) ; obj.GetValue(atom, m_pRepos->Class()->GetMember(col.m_mbrNo)) ; if (atom.IsSet()) value = atom.Str() ; else value.Clear() ;
if (col.m_nSize) C.Printf("<td width=\"%d\">%s</td>", col.m_nSize, *value) ; //atom.Str()) ; else C.Printf("<td>%s</td>", *value) ; //atom.Str()) ; } C << "</tr>\n" ; } C << "</table>\n" ; } }
void hdsField::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Aggregates to the supplied chain, HTML code for presenting an input field as part of a form. The resulting field will be unpopulated unless a // data source is specified as an attribute to <xfield> and only then if that source successfully evaluates. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsField::Generate") ;
hzAtom atom ; // For fetching field value from db hdbEnum* pSlct ; // Selector const char* pDictStr ; // String from dictionary string number hzString value ; // Value in session if set hzString S ; // Temp string uint32_t rows ; // Selector rows for radio uint32_t n ; // Selector items iterator hzEcode rc ; // Return code
if (pE && m_Source) { rc = m_pApp->PcEntConv(atom, m_Source, pE) ; if (atom.IsSet()) value = atom.Str() ; }
switch (m_Fldspec.htype) { case HTMLTYPE_HIDDEN: // Insert hidden value C.Printf("<input type=\"hidden\" name=\"%s\" value=\"%s\"/>", *m_Varname, *value) ; //atom.Str()) ; break ;
case HTMLTYPE_SELECT: // Write out the selector with already selected options marked as selected
pSlct = (hdbEnum*) m_Fldspec.m_pType ;
if (m_flagVE & VE_MULTIPLE) C.Printf("<select name=\"%s\" multiple>", *m_Varname) ; else C.Printf("<select name=\"%s\">", *m_Varname) ;
for (n = 0 ; n < pSlct->Count() ; n++) { S = pSlct->GetStr(n) ; //strNo = pSlct->m_Items[n] ; //pDictStr = _hzGlobal_setStrings->Xlate(strNo) ;
if (value == pDictStr) C.Printf("<option selected>%s</option>", *S) ; else C.Printf("<option>%s</option>", *S) ; } C << "</select>" ; break ;
case HTMLTYPE_RADIO: // Write out the selector as a radio button set. The seletor cannot be multiple but the number of colums must be specified. The radio set will appear // within a <table> in which each column except the last, will contain N items. N is calculated as the total selector population divided by the number // of columns, then plus one. The last column will contain the remainder. The items will be displayed in the order they appear in the selector but are // used to fill each column before moving on to the next. The columns are from left to right.
pSlct = (hdbEnum*) m_Fldspec.m_pType ; rows = (pSlct->Count() / m_Fldspec.nCols) + 1 ;
C << "<table>\n" ; C << "\t<tr>\n" ; C << "\t\t<td>\n" ;
for (n = 0 ; n < pSlct->Count() ; n++) { S = pSlct->GetStr(n) ;
if (n && (n % rows) == 0) { C.Printf("<input type=\"radio\" name=\"%s\" value=\"%d\">%s\n", *m_Varname, n, *S) ; C << "\t\t<td>\n\t\t</td>\n" ; continue ; }
C.Printf("<input type=\"radio\" name=\"%s\" value=\"%d\">%s<br>\n", *m_Varname, n, *S) ; } C << "\t\t</td>\n" ; C << "\t</tr>\n" ; C << "</table>\n" ; break ;
case HTMLTYPE_CHECKBOX: if (value) C.Printf("<input type=\"checkbox\" name=\"%s\" checked>", *m_Varname) ; else C.Printf("<input type=\"checkbox\" name=\"%s\">", *m_Varname) ; break ;
case HTMLTYPE_FILE: C.Printf("<input type=\"file\" name=\"%s\" value=\"%s\">", *m_Varname, *value) ; break ;
case HTMLTYPE_TEXT: case HTMLTYPE_TEXTAREA:
if (m_Fldspec.nRows <= 1) { if (m_flagVE & VE_UNIQUE) C.Printf("<input type=\"text\" name=\"%s\" size=\"%d\" maxlength=\"%d\" onchange=\"ckUnique_%s()\"", *m_Varname, m_Fldspec.nCols, m_Fldspec.nSize, *m_Varname) ; else C.Printf("<input type=\"text\" name=\"%s\" size=\"%d\" maxlength=\"%d\"", *m_Varname, m_Fldspec.nCols, m_Fldspec.nSize) ;
if (m_CSS) C.Printf(" class=\"%s\"", *m_CSS) ; if (value) C.Printf(" value=\"%s\"", *value) ; if (m_flagVE & VE_DISABLED) C << " disabled" ; C << "/>" ; } else { C.Printf("<textarea name=\"%s\" rows=\"%d\" cols=\"%d\" maxlength=\"%d\"", *m_Varname, m_Fldspec.nRows, m_Fldspec.nCols, m_Fldspec.nSize) ;
if (m_CSS) C.Printf(" class=\"%s\"", *m_CSS) ; C.AddByte(CHAR_MORE) ;
if (value) C << value ; C << "</textarea>" ; } break ;
case HTMLTYPE_PASSWORD:
C.Printf("<input type=\"password\" name=\"%s\" size=\"%d\" maxlength=\"%d\"", *m_Varname, m_Fldspec.nCols, m_Fldspec.nSize) ; if (m_CSS) C.Printf(" class=\"%s\"", *m_CSS) ; if (value) C.Printf(" value=\"%s\"", *value) ; C << "/>" ; break ;
default: C.Printf("Sorry: HTML Unknown type. FldDesc=%s Name=%s Type=%s htype=%d Rows=%d Cols=%d Size=%d", *m_Fldspec.m_Refname, *m_Varname, m_Fldspec.m_pType->txtType(), m_Fldspec.htype, m_Fldspec.nRows, m_Fldspec.nCols, m_Fldspec.nSize) ; break ; } }
void hdsFormref::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Aggregates to the supplied chain (the HTML body), the HTML code for presenting a form. This will present the whole form so everything from the // opening <form> tag to the closing </form> antitag. // // The HTML for the form is actually vested with the form definition so generating HTML for a form reference is a matter of .... // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsFormref::Generate") ;
hzList<hdsVE*>::Iter ih ; // Html entity iterator
hdsFormdef* pFormdef ; // Actual form referenced hdsVE* pVE ; // Html entity hzString url ; // URL from hdsApp map m_FormRef2Url uint32_t nV ; // Visual entity iterator uint32_t relLn ; // Relative line uint32_t x ; // Tab controller
if (m_Line != nLine) { C.AddByte(CHAR_NL) ; for (x = m_Indent ; x ; x--) C.AddByte(CHAR_TAB) ; nLine = m_Line ; }
pFormdef = m_pApp->m_FormDefs[m_Formname] ;
if (!pFormdef) { C.Printf("<p>ERROR: NULL FORM DEF</p>\n") ; return ; }
if (pFormdef->m_nActions == 1) { x = m_pApp->m_FormRef2Url.First(this) ; url = m_pApp->m_FormRef2Url.GetObj(x) ;
if (m_flagVE & VE_MULTIPART) C.Printf("<form name=\"%s\" method=\"POST\" action=\"%s\" onsubmit=\"return ck%s()\" enctype=\"multipart/form-data\">\n", *m_Formname, *url, *m_Formname) ; else C.Printf("<form name=\"%s\" method=\"POST\" action=\"%s\" onsubmit=\"return ck%s()\">\n", *m_Formname, *url, *m_Formname) ; } else { if (m_flagVE & VE_MULTIPART) C.Printf("<form name=\"%s\" method=\"POST\" enctype=\"multipart/form-data\">\n", *m_Formname, *url, *url) ; else C.Printf("<form name=\"%s\" method=\"POST\">\n", *m_Formname, *url, *url) ; }
relLn = nLine ; pE->m_pContextForm = this ; for (nV = 0 ; nV < pFormdef->m_VEs.Count() ; nV++) { pVE = pFormdef->m_VEs[nV] ; pVE->Generate(C, pE, relLn) ; }
if (nLine != m_Line) { C.AddByte(CHAR_NL) ; for (x = m_Indent ; x ; x--) C.AddByte(CHAR_TAB) ; } C << "</form>\n" ; }
void hdsPage::WriteValidationJS (void) { // This is run once upon startup and applies to each page in which there is one or more forms. It Creates the JavaScript that must be run to pre // validate form content before submission to the server. // // Arguments: None // Returns: None
_hzfunc("hdsPage::WriteValidationJS") ;
hzList<hdsFormref*>::Iter fi ; // Form iterator
hzChain Z ; // For building page validation script(s) hdsFormref* pFormref ; // Form in page hdsFormdef* pFormdef ; // Form in page hdsField* pFld ; // Field in form uint32_t n ; // Field iterator
// Check for pre-submission requirements. This is where one or more fields can only be validated by querying the server. For example in a form to // register a new user, the email address must be new. The 'onchange' event is used to check on the server for the existance of the field class, // member and value.
_hzGlobal_Dissemino->m_pLog->Log("DOING PAGE %s\n", *m_Title) ;
for (fi = m_xForms ; fi.Valid() ; fi++) { pFormref = fi.Element() ; m_pApp->m_pLog->Log("DOING FORM REF %p\n", pFormref) ;
if (!pFormref) { _hzGlobal_Dissemino->m_pLog->Log("ERROR Page %s has a NULL form reference\n", *m_Title) ; continue ; }
//pFormdef = pFormref->m_pFormdef ; pFormdef = m_pApp->m_FormDefs[pFormref->m_Formname] ; if (!pFormdef) { m_pApp->m_pLog->Log("ERROR Page %s has a NULL form definition\n", *m_Title) ; continue ; }
for (n = 0 ; n < pFormdef->m_vecFlds.Count() ; n++) { pFld = pFormdef->m_vecFlds[n] ;
if (!pFld->m_Varname) continue ;
if (!(pFld->m_flagVE & VE_UNIQUE)) continue ;
if (!pFld->m_pClass || !pFld->m_pMem) continue ;
Z.Printf("function ckUnique_%s()\n{\n", *pFld->m_Varname) ; Z.Printf("\tif (ckExists('%s','%s',document.%s.%s.value))\n", pFld->m_pClass->txtType(), pFld->m_pMem->txtName(), *pFormdef->m_Formname, *pFld->m_Varname) ; Z << "\t{\n" ; Z.Printf("\t\talert(\"%s already in use\");\n", *pFld->m_Varname) ; Z.Printf("\t\tdocument.%s.%s.value=\"\";\n", *pFormdef->m_Formname, *pFld->m_Varname) ; Z.Printf("\t\tdocument.%s.%s.focus();\n", *pFormdef->m_Formname, *pFld->m_Varname) ; Z << "\t}\n}\n" ;
m_bScriptFlags |= INC_SCRIPT_EXISTS ; }
// Now do the ordinary format checking validation scripting Z.Printf("function ck%s()\n{\n", *pFormdef->m_Formname) ;
for (n = 0 ; n < pFormdef->m_vecFlds.Count() ; n++) { pFld = pFormdef->m_vecFlds[n] ;
if (!pFld->m_Varname) continue ;
if (!(pFld->m_flagVE & VE_COMPULSORY)) continue ;
if (pFld->m_Fldspec.m_pType->Basetype() == BASETYPE_ENUM) Z.Printf("\tif (document.%s.%s.value==\"0\")\n", *pFormdef->m_Formname, *pFld->m_Varname) ; else Z.Printf("\tif (document.%s.%s.value==\"\")\n", *pFormdef->m_Formname, *pFld->m_Varname) ; Z.Printf("\t\t{ alert(\"Please provide your %s\"); document.%s.%s.focus(); return false; }\n", *pFld->m_Varname, *pFormdef->m_Formname, *pFld->m_Varname) ;
if (pFld->m_Fldspec.m_pType->Basetype() == BASETYPE_EMADDR) { Z.Printf("\tif (!ckEmaddr(document.%s.%s.value))\n", *pFormdef->m_Formname, *pFld->m_Varname) ; Z.Printf("\t\t{ document.%s.%s.focus(); return false }\n", *pFormdef->m_Formname, *pFld->m_Varname) ; m_bScriptFlags |= INC_SCRIPT_CKEMAIL ; }
if (pFld->m_Fldspec.m_pType->Basetype() == BASETYPE_URL) { Z.Printf("\tif (!ckUrl(document.%s.%s.value))\n", *pFormdef->m_Formname, *pFld->m_Varname) ; Z.Printf("\t\t{ document.%s.%s.focus(); return false }\n", *pFormdef->m_Formname, *pFld->m_Varname) ; m_bScriptFlags |= INC_SCRIPT_CKURL ; } }
if (pFormdef->m_bScriptFlags & INC_SCRIPT_RECAPTCHA) { Z.Printf("\tif (grecaptcha.getResponse()==\"\")\n") ; Z.Printf("\t\t{ alert(\"Please prove you are human!\"); return false; }\n") ; }
Z.Printf("\tdocument.%s.submit();\n\treturn true\n}\n", *pFormdef->m_Formname) ; }
m_validateJS = Z ; }
/* ** Grapics */
void hdsGraphic::Draw (hzChain& Z) { // Draw shape _hzfunc("hdsGraphic::Draw") ;
threadLog("ok .. \n") ; switch (m_eShape) { case HDSGRAPH_DIAMOND: Z.Printf("<polygon points=\"%u,%u %u,%u %u,%u %u,%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u\"/>\n", lftMidptX(), lftMidptY(), topMidptX(), topMidptY(), rhtMidptX(), rhtMidptY(), botMidptX(), botMidptY(), m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_HEXAGON: Z.Printf("<polygon points=\"%u,%u %u,%u %u,%u %u,%u, %u,%u, %u,%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u\"/>\n", m_Lft, m_Top + (m_Height/2), m_Lft + (m_Height/2), m_Top, m_Rht - (m_Height/2), m_Top, m_Rht, m_Top + (m_Height/2), m_Rht - (m_Height/2), m_Bot, m_Lft + (m_Height/2), m_Bot, m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_ARROW: Z.Printf("<polygon points=\"%u,%u %u,%u %u,%u %u,%u %u,%u %u,%u %u,%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u\"/>\n", m_Lft, m_Top + m_Height/3, topMidptX(), m_Top + m_Height/3, topMidptX(), m_Top, rhtMidptX(), rhtMidptY(), botMidptX(), botMidptY(), botMidptX(), m_Bot - m_Height/3, m_Lft, m_Bot - m_Height/3, m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_RECT: Z.Printf("<rect x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u;\"/>\n", m_Lft, m_Top, m_Width, m_Height, m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_VRECT: break ; case HDSGRAPH_HRECT: break ;
case HDSGRAPH_RRECT: Z.Printf("<rect x=\"%u\" y=\"%u\" rx=\"%u\" ry=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u;\"/>\n", m_Lft, m_Top, m_Rad, m_Rad, m_Width, m_Height, m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_STADIUM: Z.Printf("<rect x=\"%u\" y=\"%u\" rx=\"%u\" ry=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u;\"/>\n", m_Lft, m_Top, m_Height/2, m_Height/2, m_Width, m_Height, m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_CIRCLE: Z.Printf("<circle cx=\"%u\" cy=\"%u\" r=\"%u\" stroke=\"#%06x\" stroke-width=\"%u\" fill=\"#%06x\"/>\n", m_Lft + (m_Width/2), m_Top + (m_Height/2), m_Rad, m_ColorFill, m_ColorLine, m_Thick) ; break ;
case HDSGRAPH_LGATE_AND: break ; case HDSGRAPH_LGATE_OR: break ; case HDSGRAPH_LGATE_NOT: break ; case HDSGRAPH_LGATE_NAND: break ; case HDSGRAPH_LGATE_NOR: break ; } }
void _hds_svg_drawTriangle (hzChain& Z, uint32_t aX, uint32_t aY, uint32_t bX, uint32_t bY, uint32_t cX, uint32_t cY, uint32_t color) { _hzfunc(__func__) ;
Z.Printf("<polygon points=\"%u,%u %u,%u %u,%u\" style=\"fill:#%06x;\"/>\n", aX, aY, bX, bY, cX, cY, color) ; }
void _hds_svg_drawLine (hzChain& Z, hdsLine& ln) { _hzfunc(__func__) ;
Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", ln.m_startH, ln.m_startV, ln.m_finalH, ln.m_finalV, ln.m_Color, ln.m_Thick) ; }
void _hds_svg_drawLine (hzChain& Z, uint32_t aX, uint32_t aY, uint32_t bX, uint32_t bY, uint32_t color, uint32_t width) { _hzfunc(__func__) ;
Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", aX, aY, bX, bY, color, width) ; }
void _hds_svg_drawText (hzChain& Z, hzString& text, uint32_t H, uint32_t V, uint32_t color, uint16_t alignCode) { // Align code 1 center, 2 right else left _hzfunc(__func__) ; if (!text) return ;
if (alignCode == 1) Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\" dominant-baseline=\"top\" text-anchor=\"middle\">%s</text>\n", H, V, color, *text) ; else if (alignCode == 2) Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\" dominant-baseline=\"top\" text-anchor=\"end\">%s</text>\n", H, V, color, *text) ; else Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\" dominant-baseline=\"top\">%s</text>\n", H, V, color, *text) ; }
void _hds_svg_drawMLText (hzChain& Z, hzString& text, uint32_t X, uint32_t Y, uint32_t color, uint32_t id) { // Multi-line Text _hzfunc(__func__) ;
const char* i ; // Text iterator
Z.Printf("<text fill=\"#%06x\" dominant-baseline=\"top\">\n", color) ; Z.Printf("\t<tspan x=\"%u\" dy=\"%u\">%d:", X, Y, id) ; for (i = *text ; *i ; i++) { if (*i == CHAR_NL) { Y += 20 ; Z << "\t</tspan>\n" ; Z.Printf("\t<tspan x=\"%u\" y=\"%u\">", X, Y) ; continue ; } Z.AddByte(*i) ; } Z << "\t</tspan>\n" ; Z << "</text>\n" ; }
void hdsChartPie::Generate (hzChain& Z, hzHttpEvent* pE, uint32_t& nLine) { // Category: HTML Generation // // Displays a pie chart by means of the <svg> tag and associated javascript. // // Arguments: 1) Z The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsChartPie::Generate") ;
_pie* pSlice ; // Pie value double val ; // Current segment value double sofar ; // Total value of all segments so far processed double deg ; // Angle from top double ang ; // Angle in radians uint32_t X ; // Destination horizontal coord uint32_t Y ; // Destination vertical coord uint32_t last_y = 0 ; // y-coord uint32_t last_x = 0 ; // x-coord uint32_t n ; // Parts iterator uint32_t bSmall ; // Short arc indicator
//char buf[200] ;
// Open svg tag Z.Printf("\n<svg id=\"%s\" height=\"%d\" width=\"%d\" style=\"background:#%06x;\">", *m_Id, m_Height, m_Width, m_BgColor) ;
// Draw header and footer if applicable if (m_Header) _hds_svg_drawText(Z, m_Header, m_Width/2, 20, m_FgColor, 1) ;
// Work out what percentage of the total, each part represents last_x = m_ccX ; last_y = m_ccY - m_Rad ; sofar = val = 0.0 ;
for (n = 0 ; n < m_nSlices ; n++) { pSlice = m_pSlices + n ;
bSmall = pSlice->m_nValue/m_Total >= 0.5 ? 1 : 0 ;
Z << "\t<path d=\"" ;
if ((n+1) == m_nSlices) { X = m_ccX ; Y = m_ccY - m_Rad ; Z.Printf("M %u %u L %u %u A %u %u 0 %d 1 %u %u Z\" fill=\"#%06x\"/>\n", m_ccX, m_ccY, last_x, last_y, m_Rad, m_Rad, bSmall, X, Y, pSlice->color) ; } else { sofar += pSlice->m_nValue ; deg = (360 * sofar)/m_Total ; ang = (deg * M_PI)/180 ; X = m_ccX + (m_Rad * sin(ang)) ; Y = m_ccY - (m_Rad * cos(ang)) ;
Z.Printf("M %u %u L %u %u A %u %u 0 %d 1 %u %u Z\" fill=\"#%06x\"/>\n", m_ccX, m_ccY, last_x, last_y, m_Rad, m_Rad, bSmall, X, Y, pSlice->color) ; last_x = X ; last_y = Y ; } }
// Write index X = m_ccX + m_Rad + 40 ; Y = m_ccY - m_Rad ;
for (n = 0 ; n < m_nSlices ; n++) { pSlice = m_pSlices + n ;
Z.Printf("<rect x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:1\"/>\n", X, Y, 12, 12, pSlice->color, m_FgColor, 1) ; _hds_svg_drawText(Z, pSlice->header, X+15, Y+12, m_FgColor, 0) ; Y += 20 ; }
if (m_Footer) _hds_svg_drawText(Z, m_Footer, m_Width/2, m_Height - 20, m_FgColor, 1) ;
Z << "</svg>\n" ; }
void hdsChartStd::Generate (hzChain& Z, hzHttpEvent* pE, uint32_t& nLine) { // Category: HTML Generation // // Displays a chart by placing in the page HTML, a <svg> tag. // // Arguments: 1) Z The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsChartStd::Generate") ;
hzList<_rset*>::Iter ri ; // Dataset iterator
_rset* pSet ; // Dataset double per_pixel_X ; // For ploting x double per_pixel_Y ; // For ploting y double val ; // Current value double stepSize ; // Axis value per step uint32_t X ; // Current horizontal coord uint32_t Y ; // Current vertical coord uint16_t axisPixelsX ; // Total pixels on V-axis uint16_t axisPixelsY ; // Total pixels on V-axis uint32_t n ; // Loop iterator
/* ** Start draw instrutions */
Z.Printf("<svg id=\"%s\" height=\"%d\" width=\"%d\" style=\"border:1px solid #000000; background:#%06x;\">", *m_Id, m_Height, m_Width, m_BgColor) ;
// Draw header and footer if applicable if (m_Header) _hds_svg_drawText(Z, m_Header, m_Width/2, 20, m_FgColor, 1) ;
// Calculate pixels axisPixelsY = m_nSlotsY * m_nPxSlotY ; axisPixelsX = m_nSlotsX * m_nPxSlotX ; per_pixel_Y = (m_nMaxY - m_nMinY)/axisPixelsY ; per_pixel_X = (m_nMaxX - m_nMinX)/axisPixelsX ;
// Draw vertical and horizontal axis Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:1\"/>\n", m_origX, m_origY - axisPixelsY, m_origX, m_origY, m_FgColor) ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:1\"/>\n", m_origX, m_origY, m_origX + axisPixelsX, m_origY, m_FgColor) ;
// Draw out vertical axis heading and markers X = 20 ; Y = 30 ; Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%s</text>\n", X, Y, m_FgColor, *m_HdrY) ;
stepSize = (m_nMaxY - m_nMinY)/m_nSlotsY ; Y = m_origY ; for (val = m_nMinY ; val <= m_nMaxY ; val += stepSize) { Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%u</text>\n", X, Y, m_FgColor, (uint32_t) val) ; Y -= m_nPxSlotY ; }
// Draw out horizontal axis heading and markers stepSize = (m_nMaxX - m_nMinX)/m_nSlotsX ; Y = m_origY + 20 ; X = m_origX ; for (val = m_nMinX ; val <= m_nMaxX ; val += stepSize) { Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%u</text>\n", X, Y, m_FgColor, (uint32_t) val) ; X += m_nPxSlotX ; }
// Plot values for (ri = m_Sets ; ri.Valid() ; ri++) { pSet = ri.Element() ;
Z << "<polyline points=\"" ;
X = m_origX + ((m_hVals[0] - m_nMinX)/per_pixel_X) ; Y = m_origY - ((pSet->m_vVals[0] - m_nMinY)/per_pixel_Y) ; Z.Printf("%u,%u", X, Y) ;
for (n = 1 ; n <= m_nSlotsX ; n++) { X = m_origX + ((m_hVals[n] - m_nMinX)/per_pixel_X) ; Y = m_origY - ((pSet->m_vVals[n] - m_nMinY)/per_pixel_Y) ; Z.Printf(" %u,%u", X, Y) ; }
Z.Printf("\" style=\"fill:none;stroke:#%06x;stroke-width:1\"/>\n", pSet->color) ; }
// Do the component index if applicable Y = m_origY + 40 ; if (m_Sets.Count() > 1) { X = m_origX ; for (ri = m_Sets ; ri.Valid() ; ri++) { pSet = ri.Element() ; Z.Printf("<rect x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;\"/>\n", X, Y, 12, 12, pSet->color) ; Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%s</text>\n", X+15, Y+12, m_FgColor, *pSet->header) ; X += 10 * (pSet->header.Length()) ; } Y += 20 ; } if (m_Footer) _hds_svg_drawText(Z, m_Footer, m_Width/2, Y, m_FgColor, 1) ;
Z << "Your Browser does not support the HTML5 SVG tag\n" "</svg>\n" ; }
void hdsChartBar::Generate (hzChain& Z, hzHttpEvent* pE, uint32_t& nLine) { // Category: HTML Generation // // Displays a chart by placing in the page HTML, a <svg> tag. // // Arguments: 1) Z The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsChartBar::Generate") ;
hzList<_rset*>::Iter ri ; // Dataset iterator
_rset* pSet ; // Dataset //double per_pixel_X ; // For ploting x double per_pixel_Y ; // For ploting y double stepSize ; // Axis value per step uint32_t val ; // Current value uint32_t X ; // Current horizontal coord uint32_t Y ; // Current vertical coord uint16_t axisPixelsX ; // Total pixels on X-axis uint16_t axisPixelsY ; // Total pixels on Y-axis uint32_t n ; // Loop iterator
/* ** Start draw instrutions */
Z.Printf("<svg id=\"%s\" height=\"%d\" width=\"%d\" style=\"border:1px solid #000000; background:#%06x;\">", *m_Id, m_Height, m_Width, m_BgColor) ;
// Draw header and footer if applicable if (m_Header) _hds_svg_drawText(Z, m_Header, m_Width/2, 20, m_FgColor, 1) ;
// Calculate pixels axisPixelsX = m_nSlotsX * m_nPxSlotX ; axisPixelsY = m_nSlotsY * m_nPxSlotY ; //per_pixel_X = (m_nMaxX - m_nMinX)/axisPixelsX ; per_pixel_Y = (m_nMaxY - m_nMinY)/axisPixelsY ;
// Draw vertical and horizontal axis Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:1\"/>\n", m_origX, m_origY - axisPixelsY, m_origX, m_origY, m_FgColor) ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:1\"/>\n", m_origX, m_origY, m_origX + axisPixelsX, m_origY, m_FgColor) ;
// Draw out vertical axis heading and markers Y = 30 ; X = 20 ; Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%s</text>\n", X, Y, m_FgColor, *m_HdrY) ;
stepSize = (m_nMaxY - m_nMinY)/m_nSlotsY ; Y = m_origY ; for (val = m_nMinY ; val <= m_nMaxY ; val += stepSize) { Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%u</text>\n", X, Y, m_FgColor, (uint32_t) val) ; Y -= m_nPxSlotY ; }
// Draw out horizontal axis heading and markers stepSize = (m_nMaxX - m_nMinX)/m_nSlotsX ; Y = m_origY + 20 ; X = m_origX ; for (val = m_nMinX ; val <= m_nMaxX ; val += stepSize) { Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%u</text>\n", X, Y, m_FgColor, (uint32_t) val) ; X += m_nPxSlotX ; }
// Plot values for (n = 0 ; n <= m_nSlotsX ; n++) { Y = m_origY ; X = m_origX + (n * m_nPxSlotX) + 1 ;
for (ri = m_Sets ; ri.Valid() ; ri++) { pSet = ri.Element() ; val = ((pSet->m_vVals[n] - m_nMinY) * per_pixel_Y) ;
Z.Printf("<rect x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;\"/>\n", X, Y - val, (uint32_t)m_nPxSlotX - 1, val, pSet->color) ;
Y -= val ; } }
// Do the component index if applicable Y = m_origY + 40 ; if (m_Sets.Count() > 1) { X = m_origX ; for (ri = m_Sets ; ri.Valid() ; ri++) { pSet = ri.Element() ; Z.Printf("<rect x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;\"/>\n", X, Y, 12, 12, pSet->color) ; Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%s</text>\n", X+15, Y+15, m_FgColor, *pSet->header) ; X += 10 * (pSet->header.Length()) ; } Y += 20 ; } if (m_Footer) _hds_svg_drawText(Z, m_Footer, m_Width/2, Y, m_FgColor, 1) ;
Z << "Your Browser does not support the HTML5 SVG tag\n" "</svg>\n" ; }
/* ** Diagrams and Flowcharts */
static hzString s_fc_conn_TRUE = "Y" ; static hzString s_fc_conn_FALSE = "N" ;
void _drawFlowConn (hzChain& Z, hdsFlowchart* pFlow, hdsConnector* pConn) { // Flowchart support function.
_hzfunc(__func__) ;
hdsGraphic* pG_src ; // Origin shape hdsGraphic* pG_tgt ; // Target shape uint32_t color ; // Line color uint32_t lw ; // Line width uint16_t sX ; // Connector source X coord uint16_t sY ; // Connector source Y coord uint16_t tX ; // Connector target X coord uint16_t tY ; // Connector target Y coord uint16_t mY ; // Connector source/target Y midpoint
if (!pFlow) { threadLog("FAIL NO FLOWCHART\n") ; return ; }
if (!pConn) { threadLog("FAIL NO CONNECTORS\n") ; return ; }
if (!pFlow->m_pShapes) { threadLog("FAIL NO SHAPES\n") ; return ; }
if (pConn->m_Origin == pConn->m_Target) { threadLog("FAIL SRC=TGT %d\n", pConn->m_Origin) ; return ; }
if (!pConn->m_Target) { threadLog("FAIL SRC %d TGT %d\n", pConn->m_Origin, pConn->m_Target) ; return ; }
threadLog("PASS SRC %d TGT %d\n", pConn->m_Origin, pConn->m_Target) ;
color = pFlow->m_ColorLine ; lw = pFlow->m_nWidthConn ; pG_src = pFlow->m_pShapes + pConn->m_Origin ; pG_tgt = pFlow->m_pShapes + pConn->m_Target ; //threadLog("case x.2\n") ;
if (pG_tgt->rhtMidptY() == pG_src->rhtMidptY()) { // Target graphic is vertically equal to the source target - Draw line from either the RHS of source to the LHS of target, or vice versa, then triangle arrow head
//threadLog("case A\n") ; if (pG_tgt->m_Lft > pG_src->m_Rht) { threadLog("case a.1\n") ; sX = pG_src->rhtMidptX() ; sY = pG_src->rhtMidptY() ; tX = pG_tgt->lftMidptX() ; tY = pG_tgt->lftMidptY() ;
_hds_svg_drawLine(Z, sX, sY, tX, tY, color, lw) ; _hds_svg_drawTriangle(Z, tX-10, tY-4, tX-10, tY+4, tX-6, tY, color) ; } else { //threadLog("case a.2\n") ; sX = pG_src->lftMidptX() ; sY = pG_src->lftMidptY() ; tX = pG_tgt->rhtMidptX() ; tY = pG_tgt->rhtMidptY() ;
_hds_svg_drawLine(Z, sX, sY, tX, tY, color, lw) ; _hds_svg_drawTriangle(Z, tX+10, tY-4, tX+10, tY+4, tX+6, tY, color) ; }
goto doText ; }
if (pG_tgt->rhtMidptY() > pG_src->rhtMidptY()) { // Downwards flow (increasing Y). Draw one or more lines with an overall down direction. Put the triangle toward the target on the last appraoch //threadLog("case B\n") ; sX = pG_src->botMidptX() ; sY = pG_src->botMidptY() ; tX = pG_tgt->topMidptX() ; tY = pG_tgt->topMidptY() ; mY = sY + ((tY-sY)/2) ; threadLog("case b.1\n") ;
if (sX == tX) { //threadLog("case b.2\n") ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", sX, sY, tX, tY, color, lw) ; } else { // Draw short vertical line (first leg), a horizontal line and then another vertical (last approach) Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", sX, sY, sX, mY, color, lw) ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", sX, mY, tX, mY, color, lw) ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", tX, mY, tX, tY, color, lw) ; } _hds_svg_drawTriangle(Z, tX-4, tY-10, tX+4, tY-10, tX, tY-6, color) ;
goto doText ; }
// Upwards flow (decreasing Y). Draw one or more lines with an overall up direction. Put the triangle toward the target on the last appraoch //threadLog("case C\n") ; sX = pG_src->topMidptX() ; sY = pG_src->topMidptY() ; tX = pG_tgt->botMidptX() ; tY = pG_tgt->botMidptY() ; mY = sY - ((tY-sY)/2) ; //threadLog("case c.1\n") ;
if (sX == tX) { Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", sX, sY, tX, tY, color, lw) ; } else { // Draw short vertical line (first leg), a horizontal line and then another vertical (last approach) Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", sX, sY, sX, mY, color, lw) ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", sX, mY, tX, mY, color, lw) ; Z.Printf("<line x1=\"%u\" y1=\"%u\" x2=\"%u\" y2=\"%u\" style=\"stroke:#%06x;stroke-width:%u\"/>\n", tX, mY, tX, tY, color, lw) ; }
_hds_svg_drawTriangle(Z, tX-4, tY+10, tX+4, tY+10, tX, tY+6, color) ;
doText: if (pConn->m_eType) { if (pConn->m_eType & HDS_CONNECTOR_TRUE) _hds_svg_drawText(Z, s_fc_conn_TRUE, sX, sY, 0xff0000, 1) ; else { if (pConn->m_eType & HDS_CONNECTOR_FALSE) _hds_svg_drawText(Z, s_fc_conn_FALSE, sX, sY, 0xff0000, 1) ; } } }
void hdsFlowchart::Generate (hzChain& Z, hzHttpEvent* pE, uint32_t& nLine) { // Displays a diagram by placing in the page HTML, a <svg> tag. // // Arguments: 1) Z The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsFlowchart::Generate") ;
hdsText TX ; // Current text hdsGraphic* pG ; // Current shape hdsConnector* pConn ; // Connector hzString text ; // For diagnostics uint32_t n ; // Shapes and connector iterator
threadLog("Shapes %d, Connects %d\n", m_nShapes, m_nConnects) ;
// Use SVG if (m_nBoundary) Z.Printf("<svg id=\"%s\" height=\"%d\" width=\"%d\" style=\"border:1px solid #000000; background:#%06x;\">\n", *m_Id, m_Height, m_Width, m_BgColor) ; else Z.Printf("<svg id=\"%s\" height=\"%d\" width=\"%d\" style=\"background:#%06x;\">\n", *m_Id, m_Height, m_Width, m_BgColor) ;
// Draw shapes for (n = 0 ; n < m_nShapes ; n++) { pG = m_pShapes + n ; if (!pG) break ;
Z.AddByte(CHAR_TAB) ;
switch (pG->m_eShape) { case HDSGRAPH_HEXAGON: Z.Printf("<polygon points=\"%u,%u %u,%u %u,%u %u,%u, %u,%u, %u,%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u\"/>\n", pG->m_Lft, pG->m_Top + (pG->m_Height/2), pG->m_Lft + (pG->m_Height/2), pG->m_Top, pG->m_Rht - (pG->m_Height/2), pG->m_Top, pG->m_Rht, pG->m_Top + (pG->m_Height/2), pG->m_Rht - (pG->m_Height/2), pG->m_Bot, pG->m_Lft + (pG->m_Height/2), pG->m_Bot, m_ColorTest, m_ColorLine, m_nWidthConn) ; break ;
case HDSGRAPH_RECT: Z.Printf("<rect x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u;\"/>\n", pG->m_Lft, pG->m_Top, pG->m_Width, pG->m_Height, m_ColorProc, m_ColorLine, m_nWidthConn) ; break ;
case HDSGRAPH_STADIUM: Z.Printf("<rect x=\"%u\" y=\"%u\" rx=\"%u\" ry=\"%u\" width=\"%u\" height=\"%u\" style=\"fill:#%06x;stroke:#%06x;stroke-width:%u;\"/>\n", pG->m_Lft, pG->m_Top, pG->m_Height/2, pG->m_Height/2, pG->m_Width, pG->m_Height, m_ColorTerm, m_ColorLine, m_nWidthConn) ; break ; }
if (pG->m_Text) { if (pG->m_nLines == 1) Z.Printf("\t<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%d:%s</text>\n", pG->lftMidptX(), pG->lftMidptY(), pG->m_ColorLine, n, *pG->m_Text) ; else _hds_svg_drawMLText(Z, pG->m_Text, pG->m_Lft, pG->m_Top+20, pG->m_ColorLine, n) ; } else { Z.Printf("\t<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%d: No text</text>\n", pG->lftMidptX(), pG->lftMidptY(), pG->m_ColorLine, n) ; } }
// Draw connectors for (n = 0 ; n < m_nConnects ; n++) { pConn = m_pConn + n ; //if (!pConn) // break ;
//if (pConn->m_Origin && pConn->m_Target) //{ //pG = m_pShapes + pConn->m_Origin ; //pT = m_pShapes + pConn->m_Target ;
_drawFlowConn(Z, this, pConn) ; //} }
Z << "</svg>\n" ; }
void hdsDiagram::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Displays a diagram by placing in the page HTML, a <svg> tag. This has to refer to a JavaScript which must appear earlier in the HTML // // Arguments: 1) Z The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsDiagram::Generate") ;
hzList<hdsGraphic>::Iter gI ; // Graphic object iterator hzList<hdsLine>::Iter lI ; // List iterator for lines hzList<hdsText>::Iter tI ; // List iterator for texts
hzChain Z ; // This part of chain hdsText TX ; // Current text hdsLine LN ; // Current line hdsGraphic gObj ; // Current graphic object
// Calculate total width and height of svg image for (gI = m_Shapes ; gI.Valid() ; gI++) { gObj = gI.Element() ; }
// Generate the svg tag Z.Printf("<svg id=\"%s\" height=\"%d\" width=\"%d\" style=\"border:1px solid #000000; background:#%06x;\">", *m_Id, m_Height, m_Width, m_BgColor) ;
for (gI = m_Shapes ; gI.Valid() ; gI++) { gObj = gI.Element() ;
gObj.Draw(Z) ; }
// Handle lines last as a special case for (lI = m_Lines ; lI.Valid() ; lI++) { LN = lI.Element() ; _hds_svg_drawLine(Z, LN) ; }
for (tI = m_Texts ; tI.Valid() ; tI++) { TX = tI.Element() ;
Z.Printf("<text x=\"%u\" y=\"%u\" fill=\"#%06x\">%s</text>\n", TX.V(), TX.H(), TX.Color(), TX.Text()) ; } Z << "</svg>\n" ; C << Z ; //"document.getElementById('articlecontent').addEventListener('DOMCharacterDataModified',paintJob" << m_Id << ");\n" }
void hdsHtag::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Display the inactive HTML tag as part of page // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsHtag::Generate") ;
hdsVE* pVE ; // For processing subtags //hzFixPair pa ; // Tag attribute hzPair pa ; // Tag attribute hzString S ; // Temp string uint32_t n ; // Tab counter int32_t aLo ; // First attribute int32_t aHi ; // Last attribute int32_t nA ; // Attribute iterator hzHtagform tagForm ; // HTML tag type
// Write out newline and tabs if the current tag's line is greater than the supplied line if (m_Line != nLine) { C.AddByte(CHAR_NL) ; for (n = m_Indent ; n ; n--) C.AddByte(CHAR_TAB) ; nLine = m_Line ; }
// Write out the opening tag C.AddByte(CHAR_LESS) ; C << m_Tag ; if (m_nAttrs) { aLo = m_pApp->m_VE_attrs.First(m_VID) ;
if (aLo >= 0) { aHi = m_pApp->m_VE_attrs.Last(m_VID) ;
for (nA = aLo ; nA <= aHi ; nA++) { pa = m_pApp->m_VE_attrs.GetObj(nA) ;
C.AddByte(CHAR_SPACE) ; C << *pa.name ; C.AddByte(CHAR_EQUAL) ; C.AddByte(CHAR_DQUOTE) ;
if (pE && (m_flagVE & VE_AT_ACTIVE)) C << m_pApp->ConvertText(*pa.value, pE) ; else C << *pa.value ;
C.AddByte(CHAR_DQUOTE) ; } } } C.AddByte(CHAR_MORE) ;
// Now for each subtag, output first the pretext (part of this tag's content) and then call Display on the subtag for (pVE = Children() ; pVE ; pVE = pVE->Sibling()) { if (pVE->m_strPretext) { S = pVE->m_strPretext ;
if (pE && (pVE->m_flagVE & VE_PT_ACTIVE)) C << m_pApp->ConvertText(S, pE) ; else C << S ; }
pVE->Generate(C, pE, nLine) ; }
// Now write out the content if (m_strContent) { // if (pLang && m_usiContent) // S = pLang->m_LangStrings[m_usiContent] ; // else S = m_strContent ;
if (pE && m_flagVE & VE_CT_ACTIVE) C << m_pApp->ConvertText(S, pE) ; else C << S ; }
// Now write the antitag S = *m_Tag ; tagForm = TagLookup(S) ;
if (tagForm.rule != HTRULE_SINGLE) { if (nLine != m_Line) { C.AddByte(CHAR_NL) ; for (n = m_Indent ; n ; n--) C.AddByte(CHAR_TAB) ; nLine = m_Line ; }
C.AddByte(CHAR_LESS) ; C.AddByte(CHAR_FWSLASH) ; C << m_Tag ; C.AddByte(CHAR_MORE) ; } }
void hdsXtag::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // The <x> tag does not itself generate a HTML tag but instead inserts textual content into the parent tag. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsHtag::Generate") ;
hdsVE* pVE ; // For processing subtags hzString S ; // Temp string uint32_t n ; // Tab counter
// Write out newline and tabs if the current tag's line is greater than the supplied line if (m_Line != nLine) { C.AddByte(CHAR_NL) ; for (n = m_Indent ; n ; n--) C.AddByte(CHAR_TAB) ; nLine = m_Line ; }
// Now for each subtag, output first the pretext (part of this tag's content) and then call Display on the subtag for (pVE = Children() ; pVE ; pVE = pVE->Sibling()) { if (pVE->m_strPretext) { S = pVE->m_strPretext ;
if (pE && (pVE->m_flagVE & VE_PT_ACTIVE)) C << m_pApp->ConvertText(S, pE) ; else C << S ; }
pVE->Generate(C, pE, nLine) ; }
// Now write out the content if (m_strContent) { S = m_strContent ;
if (pE && m_flagVE & VE_CT_ACTIVE) C << m_pApp->ConvertText(S, pE) ; else C << S ; } }
void hdsBlock::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Aggregate to the supplied chain (the HTML body), the set of tags found within this hdsBlock instance. This is the functional equivelent of a // server side include. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsBlock::Generate") ;
hzList<hdsVE*>::Iter ih ; // Visible entity iterator
hdsVE* pVE ; // Child visible entity uint32_t relLn ; // Relative line uint32_t nV ; // Visual entity iterator
m_pApp->m_pLog->Log("BK %p %d %s\n", this, m_VID, *m_Refname) ; relLn = nLine ;
for (nV = 0 ; nV < m_VEs.Count() ; nV++) { pVE = m_VEs[nV] ; m_pApp->m_pLog->Log("VE %p %d %s\n", pVE, pVE->m_VID, *pVE->m_Tag) ; pVE->Generate(C, pE, nLine) ; }
nLine = relLn ; }
void hdsXdiv::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // On the condition that the user's access matches that of this <xdiv> tag, aggregate to the supplied chain (the HTML body), all child tags. Do // nothing otherwise. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsXdiv::Generate") ;
hdsVE* pVE ; // Visible entity hdsInfo* pInfo ; // Client session data bool bShow ; // Print or not to print
bShow = false ;
pInfo = (hdsInfo*) pE->Session() ;
if (!pInfo) { if (m_Access == ACCESS_PUBLIC || m_Access == ACCESS_NOBODY) bShow = true ; } else { if (m_Access == ACCESS_PUBLIC || (m_Access == ACCESS_ADMIN && pInfo->m_Access & ACCESS_ADMIN) || (pInfo->m_Access & ACCESS_MASK) == m_Access) bShow = true ; }
if (bShow) { for (pVE = Children() ; pVE ; pVE = pVE->Sibling()) pVE->Generate(C, pE, nLine) ; } }
void hdsCond::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // If the flags are 0, then the variable named in m_Tag must be null for the subtags of <xcond> to be executed. Otherwise the named variable must // exist and be non-null for the subtags to be executed. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 3) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsCond::Generate") ;
//hzFixPair pa ; // Tag attribute hzPair pa ; // Tag attribute hdsVE* pVE ; // Subtag pointer hdsInfo* pInfo ; // User session if applicable hzString nam ; // The variable value, if applicable hzString val ; // The variable value, if applicable int32_t aLo ; // First attribute int32_t aHi ; // Last attribute int32_t nA ; // Attribute iterator bool bPassed ; // True if condition passed
bPassed = true ;
if (pE) { if (m_nAttrs) { pInfo = (hdsInfo*) pE->Session() ; if (pInfo) { aLo = m_pApp->m_VE_attrs.First(pVE->m_VID) ;
if (aLo >= 0) { aHi = m_pApp->m_VE_attrs.Last(pVE->m_VID) ;
for (nA = aLo ; nA <= aHi ; nA++) { pa = m_pApp->m_VE_attrs.GetObj(nA) ;
if (*pa.value) val = m_pApp->ConvertText(*pa.value, pE) ; nam = *pa.name ;
if ((nam == "isnull" && val) || (nam == "exists" && !val)) { bPassed = false ; break ; } } } } } }
if (bPassed) { for (pVE = Children() ; pVE ; pVE = pVE->Sibling()) pVE->Generate(C, pE, nLine) ; } }
void hdsPage::Head (hzHttpEvent* pE) { // Send only the HTTP header for a page to the browser. // // Arguments: 1) pE The HTTP event // // Returns: None
_hzfunc("hdsPage::Head") ;
ifstream is ; // Read file stream hzXDate d ; // Date for header lines hzChain Z ; // Response for browser is built here const char* pEnd ; // Filename extension and hence type hzMimetype type ; // File's HTTP type HttpRC hrc ; // HTTP return code hzEcode rc ; // Return code from sending function
// Establish real filename, either cpFilename or index.htm(l)
// Determine the type of file so that the correct header can be // sent to the browser
pEnd = strrchr(*m_Url, CHAR_PERIOD) ; if (pEnd) type = Filename2Mimetype(pEnd) ; else type = HMTYPE_TXT_HTML ;
// Send the header
Z.Clear() ;
switch (hrc) { case HTTPMSG_OK: Z << "HTTP/1.1 200 OK\r\n" ; break ; case HTTPMSG_NOTFOUND: Z << "HTTP/1.1 404 Not found\r\n" ; break ; default: Z.Printf("HTTP/1.1 %03d\r\n", hrc) ; } ;
d.SysDateTime() ;
Z.Printf("Date: %s\r\n", d.Txt(FMT_DT_INET)) ; Z << "Server: HTTP/1.0 (HadronZoo, Linux)\r\n" ; Z.Printf("Last-Modified: %s\r\n", d.Txt(FMT_DT_INET)) ;
d.altdate(SECOND, 1000) ; Z.Printf("Expires: %s\r\n", d.Txt(FMT_DT_INET)) ;
Z << "Accept-Ranges: bytes\r\n" ; if (hrc == HTTPMSG_OK) Z.Printf("Content-Length: 0\r\n") ; Z << "Content-Type: " << Mimetype2Txt(type) << "\n\n" ;
pE->SendRawChain(HTTPMSG_OK, HMTYPE_TXT_HTML, Z, 0, false) ; }
void hdsArtref::Generate (hzChain& C, hzHttpEvent* pE, uint32_t& nLine) { // Aggregate to the supplied chain (the HTML body), this article's preformulated value (the tags found within this article) // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // 4) nLine Line number tracker (controls NL printing) // // Returns: None
_hzfunc("hdsArtref::Generate") ;
hzList<hdsVE*>::Iter ih ; // Html entity iterator
hdsInfo* pInfo = 0 ; // Session //hdsLang* pLang ; // Applicable language hdsNavtree* pAG = 0 ; // Article group hdsArticle* pArt = 0 ; // The article hdsArticleStd* pArtStd = 0 ; // The article as a visible entity container hdsArticleCIF* pArtCIF = 0 ; // The article as a C-Interface function hzString S ; // Temp string
if (!this) Fatal("No instance\n") ;
// Get session if one applies if (pE) pInfo = (hdsInfo*) pE->Session() ;
threadLog("info %p\n", pInfo) ;
// Lookup the tree of articles. This could be in the hdsApp map m_ArticleGroups or it could be vested with the session pAG = m_pApp->m_ArticleGroups[m_Group] ; if (!pAG) { if (pInfo && pInfo->m_pTree) if (pInfo->m_pTree->m_Groupname == m_Group) pAG = pInfo->m_pTree ; }
if (!pAG) { C.Printf("SORRY: No such article group (%s)", *m_Group) ; return ; }
if (m_Show == 300) { // Export tree as script C << "\n<script language=\"javascript\">\n" ; pAG->ExportDataScript(C) ; C.Printf("makeTree('%s');\n", *m_Group) ; C << "</script>\n" ; return ; }
if (m_Article[0] == CHAR_AT) { if (!memcmp(*m_Article, "@resarg;/", 9)) { if (pE && pE->m_Resarg) pArt = (hdsArticle*) pAG->GetItem(pE->m_Resarg) ; else { S = *m_Article + 9 ; pArt = (hdsArticle*) pAG->GetItem(S) ; } } } else { pArt = (hdsArticle*) pAG->GetItem(m_Article) ; threadLog("fetched article %p %s\n", pArt, *m_Article) ; }
if (!pArt) { C.Printf("SORRY: No article with group (%s) and name (%s)", *m_Group, *m_Article) ; } else { if (m_Show == 100) { C << pArt->m_Title ; } else if (m_Show == 200) { pArtStd = dynamic_cast<hdsArticleStd*>(pArt) ; if (pArtStd) { // pLang = (hdsLang*) pE->m_pContextLang ; // C << pLang->m_rawItems[pArtStd->m_USL] ; pArtStd->Display(C, pE) ; } else { pArtCIF = dynamic_cast<hdsArticleCIF*>(pArt) ; if (pArtCIF && pE) pArtCIF->m_pFunc(C, pArtCIF, pE) ; } } else { C.Printf("FOUND: article with group (%s) and name (%s) but no show directive", *m_Group, *pArt->m_Title) ; } } }
//void hdsArticleStd::Generate (hzChain& C, hzHttpEvent* pE) void hdsArticleStd::EvalHtml (hzChain& C) { // Generate HTML for an article. // // If the applicable article contains active elements and so is itself active, this function will be called to serve the article in response to an AJAX request. Otherwise this // function is only called to create a fixed HTML value for the article during program initialization. // // Note this function is never called by hdsPage::Display() since an hdsArticle cannot be a page component. // // Argument: C The HTML output chain // Returns: None
_hzfunc("hdsArticleStd::Display") ;
hzHttpEvent httpEv ; // Artificial HTTP event hdsVE* pVE ; // Html entity uint32_t nV ; // Visual entity iterator uint32_t relLn ; // Relative line
threadLog("Generating Article %s\n", *m_Title) ;
for (nV = 0 ; nV < m_VEs.Count() ; nV++) { pVE = m_VEs[nV] ; pVE->Generate(C, &httpEv, relLn) ; } }
void hdsArticleStd::Display (hzChain& C, hzHttpEvent* pE) { // Generate HTML for an article. // // If the applicable article contains active elements and so is itself active, this function will be called to serve the article in response to an AJAX request. Otherwise this // function is only called to create a fixed HTML value for the article during program initialization. // // Note this function is never called by hdsPage::Display() since an hdsArticle cannot be a page component. // // Arguments: 1) C The HTML output chain // 2) pE The HTTP event being responded to // // Returns: None
_hzfunc("hdsArticleStd::Display") ;
hdsVE* pVE ; // Html entity uint32_t nV ; // Visual entity iterator uint32_t relLn ; // Relative line
threadLog("Generating Article %s\n", *m_Title) ;
for (nV = 0 ; nV < m_VEs.Count() ; nV++) { pVE = m_VEs[nV] ; pVE->Generate(C, pE, relLn) ; } }
void hdsPage::EvalHtml (hzChain& C) //, hdsLang* pLang) { // Create HTML for a page that is inactive and so can be stored. This will be done once per inactive pager per supported language. Because this is part of the initialization // process there will not be an actual HTTP event so a blank one is created. This is necessary because the language is carried by the HTTP event m_pContextLang variable. // // CHANGE to:- // Create pro-forma HTML for the page. If the page is active, this HTML will interspersed with percent entities that must be evaluated with each serving. // // Arguments: 1) C The HTML output chain // 2) pLang Current language // // Returns: None
_hzfunc("hdsPage::EvalHtml") ;
hzList<hdsVE*>::Iter ih ; // Html entity iterator hzList<hdsFormref*>::Iter iF ; // Form iterator
hzHttpEvent httpEv ; // Artificial HTTP event hzChain X ; // For zipping output if applicable hdsVE* pH ; // Html entity hdsFormref* pFormref ; // Form reference hdsFormdef* pFormdef ; // Form definition uint32_t relLn ; // Relative line uint32_t nV ; // Visual entity iterator hzEcode rc ; // Return code
// if (!pLang) // Fatal("No language supplied\n") ; // httpEv.m_pContextLang = pLang ;
m_pApp->m_pLog->Log("PAGE %s Script Flags %x\n", *m_Title, m_bScriptFlags) ;
// Construct the output HTML if (!m_Title) m_Title = "untitled" ;
C << "<!DOCTYPE html>\n" "<html>\n" "<head>\n" ;
C << "<title>" << m_Title << "</title>\n" ;
if (m_Desc) C.Printf("<meta name=\"description\" content=\"%s\"/>\n", *m_Desc) ; else C.Printf("<meta name=\"description\" content=\"%s\"/>\n", *m_Title) ;
if (m_Keys) C.Printf("<meta name=\"keywords\" content=\"%s\"/>\n", *m_Keys) ;
C << s_std_metas ; C << "<link rel=\"stylesheet\" href=\"" << m_pApp->m_namCSS << "\"/>\n" ;
if (m_bScriptFlags || m_xForms.Count()) { if (m_bScriptFlags & INC_SCRIPT_RECAPTCHA) C << s_Recaptcha ;
C << "<script language=\"javascript\">\n" ;
// If page contains forms then it must include validation javascript in the HTML if (m_xForms.Count()) { if (m_bScriptFlags & INC_SCRIPT_CKEMAIL) C << _dsmScript_ckEmail ; if (m_bScriptFlags & INC_SCRIPT_CKURL) C << _dsmScript_ckUrl ; if (m_bScriptFlags & INC_SCRIPT_EXISTS) C << _dsmScript_ckExists ;
for (iF = m_xForms ; iF.Valid() ; iF++) { pFormref = iF.Element() ; pFormdef = m_pApp->m_FormDefs[pFormref->m_Formname] ; C << pFormdef->m_ValJS ; //C << pFormref->m_pFormdef->m_ValJS ; }
C << m_validateJS ; }
C << "</script>\n" ; } C << "</head>\n\n" ;
// Construct the <body> tag C << "<body" ; if (m_CSS) C.Printf(" class=\"%s\"", *m_CSS) ; else C.Printf(" bgcolor=\"#%06x\" marginwidth=\"%d\" marginheight=\"%d\" leftmargin=\"%d\" topmargin=\"%d\"", m_BgColor, m_Width, m_Height, m_Width, m_Top) ;
if (m_Onpage) C.Printf(" onpageshow=\"%s\"", *m_Onpage) ; if (m_Onload) C.Printf(" onload=\"%s\"", *m_Onload) ; if (m_Resize) C.Printf(" onresize=\"%s\"", *m_Resize) ; C << ">\n" ; m_pApp->m_pLog->Log("PAGE %s Script Flags %x\n", *m_Title, m_bScriptFlags) ;
// Now construct the page elements relLn = m_Line ;
for (nV = 0 ; nV < m_VEs.Count() ; nV++) { pH = m_VEs[nV] ; pH->Generate(C, &httpEv, relLn) ; }
// End page construction C << "</body>\n</html>\n" ; m_pApp->m_pLog->Log("PAGE %s Script Flags %x\n", *m_Title, m_bScriptFlags) ; }
void hdsPage::Display (hzHttpEvent* pE) { // Display HTML according to listed entities in the page. // // Argument: pE The HTTP event being responded to // // Returns: None
_hzfunc("hdsPage::Display") ;
hzList<hdsExec*>::Iter ei ; // Page exec commands iterator hzList<hdsVE*>::Iter ih ; // Html entity iterator hzList<hdsFormref*>::Iter iF ; // Form iterator
hzChain C ; // For formulating HTML hdsExec* pExec ; // Exec function hdsVE* pVE ; // Html entity hdsFormref* pFormref ; // Form hdsFormdef* pFormdef ; // Form definition uint32_t relLn ; // Relative line uint32_t nV ; // Visual entity iterator hzEcode rc ; // Return code
if (!pE) Fatal("No HTTP Event\n") ; if (!pE->m_pContextLang) Fatal("No Language\n") ;
m_pApp->m_pLog->Log("PAGE %s Script Flags %x\n", *m_Title, m_bScriptFlags) ;
// Run executable commands for (ei = m_Exec ; ei.Valid() ; ei++) { pExec = ei.Element() ; m_pApp->m_pLog->Log("HAVE EXEC %s\n", Exec2Txt(pExec->m_Command)) ;
rc = pExec->Exec(C, pE) ; m_pApp->m_pLog->Out(C) ; C.Clear() ; }
// Construct the output HTML if (!m_Title) m_Title = "untitled" ;
C << "<!DOCTYPE html>\n" "<html>\n" "<head>\n" ;
if (pE && pE->m_Resarg) C.Printf("<title>%s-%s</title>\n", *m_Title, *pE->m_Resarg) ; else C << "<title>" << m_Title << "</title>\n" ;
if (m_Desc) C.Printf("<meta name=\"description\" content=\"%s\"/>\n", *m_Desc) ; else C.Printf("<meta name=\"description\" content=\"%s\"/>\n", *m_Title) ; if (m_Keys) C.Printf("<meta name=\"keywords\" content=\"%s\"/>\n", *m_Keys) ;
C << s_std_metas ; C << "<link rel=\"stylesheet\" href=\"" << m_pApp->m_namCSS << "\"/>\n" ;
if (m_bScriptFlags || m_xForms.Count()) { if (m_bScriptFlags & INC_SCRIPT_RECAPTCHA) C << s_Recaptcha ;
C << "<script language=\"javascript\">\n" ;
if (m_bScriptFlags & INC_SCRIPT_WINDIM) C << _dsmScript_gwp ;
if (m_bScriptFlags & INC_SCRIPT_NAVTREE) { C << _dsmScript_tog ; C << _dsmScript_loadArticle ; C << _dsmScript_navtree ; }
// If page contains forms then it must include validation javascript in the HTML if (m_xForms.Count()) { if (m_bScriptFlags & INC_SCRIPT_CKEMAIL) C << _dsmScript_ckEmail ; if (m_bScriptFlags & INC_SCRIPT_CKURL) C << _dsmScript_ckUrl ; if (m_bScriptFlags & INC_SCRIPT_EXISTS) C << _dsmScript_ckExists ;
for (iF = m_xForms ; iF.Valid() ; iF++) { pFormref = iF.Element() ; pFormdef = m_pApp->m_FormDefs[pFormref->m_Formname] ;
C << pFormdef->m_ValJS ; }
C << m_validateJS ; }
C << "</script>\n" ; } C << "</head>\n\n" ;
// Construct the <body> tag C << "<body" ; if (m_CSS) C.Printf(" class=\"%s\"", *m_CSS) ; else C.Printf(" bgcolor=\"#%06x\" marginwidth=\"%d\" marginheight=\"%d\" leftmargin=\"%d\" topmargin=\"%d\"", m_BgColor, m_Width, m_Height, m_Width, m_Top) ;
if (m_Onpage) C.Printf(" onpageshow=\"%s\"", *m_Onpage) ; if (m_Onload) C.Printf(" onload=\"%s\"", *m_Onload) ; if (m_Resize) C.Printf(" onresize=\"%s\"", *m_Resize) ; C << ">\n" ;
// Now construct the page elements relLn = m_Line ;
for (nV = 0 ; nV < m_VEs.Count() ; nV++) { pVE = m_VEs[nV] ; pVE->Generate(C, pE, relLn) ; }
// End page construction C << "</body>\n</html>\n" ;
// Send out page. Note all generated pages are sent out raw, not zipped rc = pE->SendRawChain(HTTPMSG_OK, HMTYPE_TXT_HTML, C, 0, false) ; }