2015-12-13 19:23:08 +00:00
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//#include <crtdbg.h>
# include "stdpch.h"
# include "nel/gui/group_html.h"
# include <string>
# include "nel/misc/types_nl.h"
# include "nel/misc/rgba.h"
# include "nel/misc/algo.h"
# include "nel/gui/libwww.h"
# include "nel/gui/group_html.h"
# include "nel/gui/group_list.h"
# include "nel/gui/group_container.h"
# include "nel/gui/view_link.h"
# include "nel/gui/ctrl_scroll.h"
# include "nel/gui/ctrl_button.h"
# include "nel/gui/ctrl_text_button.h"
# include "nel/gui/action_handler.h"
# include "nel/gui/group_paragraph.h"
# include "nel/gui/group_editbox.h"
# include "nel/gui/widget_manager.h"
# include "nel/gui/lua_manager.h"
# include "nel/gui/view_bitmap.h"
# include "nel/gui/dbgroup_combo_box.h"
# include "nel/gui/lua_ihm.h"
# include "nel/misc/i18n.h"
# include "nel/misc/md5.h"
# include "nel/3d/texture_file.h"
# include "nel/misc/big_file.h"
# include "nel/gui/url_parser.h"
using namespace std ;
using namespace NLMISC ;
// Default timeout to connect a server
# define DEFAULT_RYZOM_CONNECTION_TIMEOUT (30.0)
// Allow up to 10 redirects, then give up
# define DEFAULT_RYZOM_REDIRECT_LIMIT (10)
//
# define FONT_WEIGHT_BOLD 700
namespace NLGUI
{
// Uncomment to see the log about image download
//#define LOG_DL 1
CGroupHTML : : SWebOptions CGroupHTML : : options ;
// Active cURL www transfer
class CCurlWWWData
{
public :
CCurlWWWData ( CURL * curl , const std : : string & url )
: Request ( curl ) , Url ( url ) , Content ( " " ) , HeadersSent ( NULL )
{
}
~ CCurlWWWData ( )
{
if ( Request )
curl_easy_cleanup ( Request ) ;
if ( HeadersSent )
curl_slist_free_all ( HeadersSent ) ;
}
void setRecvHeader ( const std : : string & header )
{
size_t pos = header . find ( " : " ) ;
if ( pos = = std : : string : : npos )
return ;
std : : string key = toLower ( header . substr ( 0 , pos ) ) ;
if ( pos ! = std : : string : : npos )
{
HeadersRecv [ key ] = header . substr ( pos + 2 ) ;
//nlinfo(">> received header '%s' = '%s'", key.c_str(), HeadersRecv[key].c_str());
}
}
// return last received "Location: <url>" header or empty string if no header set
const std : : string getLocationHeader ( )
{
if ( HeadersRecv . count ( " location " ) > 0 )
return HeadersRecv [ " location " ] ;
return " " ;
}
public :
CURL * Request ;
std : : string Url ;
std : : string Content ;
// headers sent with curl request, must be released after transfer
curl_slist * HeadersSent ;
// headers received from curl transfer
std : : map < std : : string , std : : string > HeadersRecv ;
} ;
// Check if domain is on TrustedDomain
bool CGroupHTML : : isTrustedDomain ( const string & domain )
{
vector < string > : : iterator it ;
it = find ( options . trustedDomains . begin ( ) , options . trustedDomains . end ( ) , domain ) ;
return it ! = options . trustedDomains . end ( ) ;
}
// Update view after download has finished
void CGroupHTML : : setImage ( CViewBase * view , const string & file )
{
CCtrlButton * btn = dynamic_cast < CCtrlButton * > ( view ) ;
if ( btn )
{
btn - > setTexture ( file ) ;
btn - > setTexturePushed ( file ) ;
btn - > invalidateCoords ( ) ;
btn - > invalidateContent ( ) ;
btn - > resetInvalidCoords ( ) ;
btn - > updateCoords ( ) ;
paragraphChange ( ) ;
}
else
{
CViewBitmap * btm = dynamic_cast < CViewBitmap * > ( view ) ;
if ( btm )
{
btm - > setTexture ( file ) ;
btm - > invalidateCoords ( ) ;
btm - > invalidateContent ( ) ;
btm - > resetInvalidCoords ( ) ;
btm - > updateCoords ( ) ;
paragraphChange ( ) ;
}
else
{
CGroupCell * btgc = dynamic_cast < CGroupCell * > ( view ) ;
if ( btgc )
{
btgc - > setTexture ( file ) ;
btgc - > invalidateCoords ( ) ;
btgc - > invalidateContent ( ) ;
btgc - > resetInvalidCoords ( ) ;
btgc - > updateCoords ( ) ;
paragraphChange ( ) ;
}
}
}
}
// Force image width, height
void CGroupHTML : : setImageSize ( CViewBase * view , const CStyleParams & style )
{
sint32 width = style . Width ;
sint32 height = style . Height ;
sint32 maxw = style . MaxWidth ;
sint32 maxh = style . MaxHeight ;
sint32 imageWidth , imageHeight ;
bool changed = true ;
// get image texture size
// if image is being downloaded, then correct size is set after thats done
CCtrlButton * btn = dynamic_cast < CCtrlButton * > ( view ) ;
if ( btn )
{
btn - > fitTexture ( ) ;
imageWidth = btn - > getW ( false ) ;
imageHeight = btn - > getH ( false ) ;
}
else
{
CViewBitmap * btm = dynamic_cast < CViewBitmap * > ( view ) ;
if ( btm )
{
btm - > fitTexture ( ) ;
imageWidth = btm - > getW ( false ) ;
imageHeight = btm - > getH ( false ) ;
}
else
{
// not supported
return ;
}
}
// if width/height is not requested, then use image size
// else recalculate missing value, keep image ratio
if ( width = = - 1 & & height = = - 1 )
{
width = imageWidth ;
height = imageHeight ;
changed = false ;
}
else
if ( width = = - 1 | | height = = - 1 ) {
float ratio = ( float ) imageWidth / std : : max ( 1 , imageHeight ) ;
if ( width = = - 1 )
width = height * ratio ;
else
height = width / ratio ;
}
// apply max-width, max-height rules if asked
if ( maxw > - 1 | | maxh > - 1 )
{
applyCssMinMax ( width , height , 0 , 0 , maxw , maxh ) ;
changed = true ;
}
if ( changed )
{
CCtrlButton * btn = dynamic_cast < CCtrlButton * > ( view ) ;
if ( btn )
{
btn - > setScale ( true ) ;
btn - > setW ( width ) ;
btn - > setH ( height ) ;
}
else
{
CViewBitmap * image = dynamic_cast < CViewBitmap * > ( view ) ;
if ( image )
{
image - > setScale ( true ) ;
image - > setW ( width ) ;
image - > setH ( height ) ;
}
}
}
}
// Get an url and return the local filename with the path where the url image should be
string CGroupHTML : : localImageName ( const string & url )
{
string dest = " cache/ " ;
dest + = getMD5 ( ( uint8 * ) url . c_str ( ) , ( uint32 ) url . size ( ) ) . toString ( ) ;
dest + = " .cache " ;
return dest ;
}
// Add a image download request in the multi_curl
void CGroupHTML : : addImageDownload ( const string & url , CViewBase * img , const CStyleParams & style )
{
string finalUrl = getAbsoluteUrl ( url ) ;
// Search if we are not already downloading this url.
for ( uint i = 0 ; i < Curls . size ( ) ; i + + )
{
if ( Curls [ i ] . url = = finalUrl )
{
# ifdef LOG_DL
nlwarning ( " already downloading '%s' img %p " , finalUrl . c_str ( ) , img ) ;
# endif
Curls [ i ] . imgs . push_back ( CDataImageDownload ( img , style ) ) ;
return ;
}
}
// use requested url for local name
string dest = localImageName ( url ) ;
string tmpdest = localImageName ( url ) + " .tmp " ;
# ifdef LOG_DL
nlwarning ( " add to download '%s' dest '%s' img %p " , finalUrl . c_str ( ) , dest . c_str ( ) , img ) ;
# endif
// erase the tmp file if exists
if ( NLMISC : : CFile : : fileExists ( tmpdest ) )
NLMISC : : CFile : : deleteFile ( tmpdest ) ;
if ( ! NLMISC : : CFile : : fileExists ( dest ) )
{
if ( ! MultiCurl )
{
nlwarning ( " Invalid MultiCurl handle, unable to download '%s' " , finalUrl . c_str ( ) ) ;
return ;
}
CURL * curl = curl_easy_init ( ) ;
if ( ! curl )
{
nlwarning ( " Creating cURL handle failed, unable to download '%s' " , finalUrl . c_str ( ) ) ;
return ;
}
FILE * fp = fopen ( tmpdest . c_str ( ) , " wb " ) ;
if ( fp = = NULL )
{
curl_easy_cleanup ( curl ) ;
nlwarning ( " Can't open file '%s' for writing: code=%d '%s' " , tmpdest . c_str ( ) , errno , strerror ( errno ) ) ;
return ;
}
curl_easy_setopt ( curl , CURLOPT_NOPROGRESS , true ) ;
curl_easy_setopt ( curl , CURLOPT_URL , finalUrl . c_str ( ) ) ;
curl_easy_setopt ( curl , CURLOPT_FILE , fp ) ;
curl_multi_add_handle ( MultiCurl , curl ) ;
Curls . push_back ( CDataDownload ( curl , finalUrl , dest , fp , ImgType , img , " " , " " , style ) ) ;
# ifdef LOG_DL
nlwarning ( " adding handle %x, %d curls " , curl , Curls . size ( ) ) ;
# endif
RunningCurls + + ;
}
else
{
setImage ( img , dest ) ;
setImageSize ( img , style ) ;
}
}
void CGroupHTML : : initImageDownload ( )
{
# ifdef LOG_DL
nlwarning ( " Init Image Download " ) ;
# endif
/*
// Get current flag
int tmpFlag = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ) ;
// Turn on leak-checking bit
tmpFlag | = _CRTDBG_CHECK_ALWAYS_DF ;
// Set flag to the new value
_CrtSetDbgFlag ( tmpFlag ) ;
*/
string pathName = " cache " ;
if ( ! CFile : : isExists ( pathName ) )
CFile : : createDirectory ( pathName ) ;
}
// Get an url and return the local filename with the path where the bnp should be
string CGroupHTML : : localBnpName ( const string & url )
{
size_t lastIndex = url . find_last_of ( " / " ) ;
string dest = " user/ " + url . substr ( lastIndex + 1 ) ;
return dest ;
}
// Add a bnp download request in the multi_curl, return true if already downloaded
bool CGroupHTML : : addBnpDownload ( const string & url , const string & action , const string & script , const string & md5sum )
{
// Search if we are not already downloading this url.
for ( uint i = 0 ; i < Curls . size ( ) ; i + + )
{
if ( Curls [ i ] . url = = url )
{
# ifdef LOG_DL
nlwarning ( " already downloading '%s' " , url . c_str ( ) ) ;
# endif
return false ;
}
}
string dest = localBnpName ( url ) ;
string tmpdest = localBnpName ( url ) + " .tmp " ;
# ifdef LOG_DL
nlwarning ( " add to download '%s' dest '%s' " , url . c_str ( ) , dest . c_str ( ) ) ;
# endif
// erase the tmp file if exists
if ( NLMISC : : CFile : : fileExists ( tmpdest ) )
NLMISC : : CFile : : deleteFile ( tmpdest ) ;
// create/delete the local file
if ( NLMISC : : CFile : : fileExists ( dest ) )
{
if ( action = = " override " | | action = = " delete " )
{
CFile : : setRWAccess ( dest ) ;
NLMISC : : CFile : : deleteFile ( dest ) ;
}
else
{
return true ;
}
}
if ( action ! = " delete " )
{
if ( ! MultiCurl )
{
nlwarning ( " Invalid MultiCurl handle, unable to download '%s' " , url . c_str ( ) ) ;
return false ;
}
CURL * curl = curl_easy_init ( ) ;
if ( ! curl )
{
nlwarning ( " Creating cURL handle failed, unable to download '%s' " , url . c_str ( ) ) ;
return false ;
}
FILE * fp = fopen ( tmpdest . c_str ( ) , " wb " ) ;
if ( fp = = NULL )
{
curl_easy_cleanup ( curl ) ;
nlwarning ( " Can't open file '%s' for writing: code=%d '%s' " , tmpdest . c_str ( ) , errno , strerror ( errno ) ) ;
return false ;
}
curl_easy_setopt ( curl , CURLOPT_NOPROGRESS , true ) ;
curl_easy_setopt ( curl , CURLOPT_URL , url . c_str ( ) ) ;
curl_easy_setopt ( curl , CURLOPT_FILE , fp ) ;
curl_multi_add_handle ( MultiCurl , curl ) ;
Curls . push_back ( CDataDownload ( curl , url , dest , fp , BnpType , NULL , script , md5sum ) ) ;
# ifdef LOG_DL
nlwarning ( " adding handle %x, %d curls " , curl , Curls . size ( ) ) ;
# endif
RunningCurls + + ;
}
else
return true ;
return false ;
}
void CGroupHTML : : initBnpDownload ( )
{
if ( ! _TrustedDomain )
return ;
# ifdef LOG_DL
nlwarning ( " Init Bnp Download " ) ;
# endif
string pathName = " user " ;
if ( ! CFile : : isExists ( pathName ) )
CFile : : createDirectory ( pathName ) ;
}
// Call this evenly to check if an element is downloaded and then manage it
void CGroupHTML : : checkDownloads ( )
{
//nlassert(_CrtCheckMemory());
if ( Curls . empty ( ) & & _CurlWWW = = NULL )
return ;
int NewRunningCurls = 0 ;
while ( CURLM_CALL_MULTI_PERFORM = = curl_multi_perform ( MultiCurl , & NewRunningCurls ) )
{
# ifdef LOG_DL
nlwarning ( " more to do now %d - %d curls " , NewRunningCurls , Curls . size ( ) ) ;
# endif
}
if ( NewRunningCurls < RunningCurls )
{
// some download are done, callback them
# ifdef LOG_DL
nlwarning ( " new %d old %d " , NewRunningCurls , RunningCurls ) ;
# endif
// check msg
CURLMsg * msg ;
int msgs_left ;
while ( ( msg = curl_multi_info_read ( MultiCurl , & msgs_left ) ) )
{
# ifdef LOG_DL
nlwarning ( " > (%s) msgs_left %d " , _Id . c_str ( ) , msgs_left ) ;
# endif
if ( msg - > msg = = CURLMSG_DONE )
{
if ( _CurlWWW & & _CurlWWW - > Request & & _CurlWWW - > Request = = msg - > easy_handle )
{
CURLcode res = msg - > data . result ;
long code ;
curl_easy_getinfo ( _CurlWWW - > Request , CURLINFO_RESPONSE_CODE , & code ) ;
# ifdef LOG_DL
nlwarning ( " (%s) web transfer '%p' completed with status %d, http %d, url (len %d) '%s' " , _Id . c_str ( ) , _CurlWWW - > Request , res , code , _CurlWWW - > Url . size ( ) , _CurlWWW - > Url . c_str ( ) ) ;
# endif
if ( res ! = CURLE_OK )
{
browseError ( string ( " Connection failed with curl error " + string ( curl_easy_strerror ( res ) ) ) . c_str ( ) ) ;
}
else
if ( ( code > = 301 & & code < = 303 ) | | code = = 307 | | code = = 308 )
{
if ( _RedirectsRemaining < 0 )
{
browseError ( string ( " Redirect limit reached : " + _URL ) . c_str ( ) ) ;
}
else
{
receiveCookies ( _CurlWWW - > Request , HTTPCurrentDomain , _TrustedDomain ) ;
// redirect, get the location and try browse again
// we cant use curl redirection because 'addHTTPGetParams()' must be called on new destination
std : : string location ( _CurlWWW - > getLocationHeader ( ) ) ;
if ( location . size ( ) > 0 )
{
# ifdef LOG_DL
nlwarning ( " (%s) request (%d) redirected to (len %d) '%s' " , _Id . c_str ( ) , _RedirectsRemaining , location . size ( ) , location . c_str ( ) ) ;
# endif
location = getAbsoluteUrl ( location ) ;
// throw away this handle and start with new one (easier than reusing)
requestTerminated ( ) ;
_PostNextTime = false ;
_RedirectsRemaining - - ;
doBrowse ( location . c_str ( ) ) ;
}
else
{
browseError ( string ( " Request was redirected, but location was not set : " + _URL ) . c_str ( ) ) ;
}
}
}
else
{
receiveCookies ( _CurlWWW - > Request , HTTPCurrentDomain , _TrustedDomain ) ;
_RedirectsRemaining = DEFAULT_RYZOM_REDIRECT_LIMIT ;
if ( ( code < 200 | | code > = 300 ) )
{
browseError ( string ( " Connection failed (curl code " + toString ( ( sint32 ) res ) + " ), http code " + toString ( ( sint32 ) code ) + " ) : " + _CurlWWW - > Url ) . c_str ( ) ) ;
}
else
{
char * ch ;
std : : string contentType ;
res = curl_easy_getinfo ( _CurlWWW - > Request , CURLINFO_CONTENT_TYPE , & ch ) ;
if ( res = = CURLE_OK )
{
contentType = ch ;
}
htmlDownloadFinished ( _CurlWWW - > Content , contentType , code ) ;
}
requestTerminated ( ) ;
}
}
for ( vector < CDataDownload > : : iterator it = Curls . begin ( ) ; it < Curls . end ( ) ; it + + )
{
if ( msg - > easy_handle = = it - > curl )
{
CURLcode res = msg - > data . result ;
long r ;
curl_easy_getinfo ( it - > curl , CURLINFO_RESPONSE_CODE , & r ) ;
fclose ( it - > fp ) ;
# ifdef LOG_DL
nlwarning ( " (%s) transfer '%p' completed with status %d, http %d, url (len %d) '%s' " , _Id . c_str ( ) , it - > curl , res , r , it - > url . size ( ) , it - > url . c_str ( ) ) ;
# endif
curl_multi_remove_handle ( MultiCurl , it - > curl ) ;
curl_easy_cleanup ( it - > curl ) ;
string tmpfile = it - > dest + " .tmp " ;
if ( res ! = CURLE_OK | | r < 200 | | r > = 300 | | ( ( it - > md5sum ! = " " ) & & ( it - > md5sum ! = getMD5 ( tmpfile ) . toString ( ) ) ) )
{
NLMISC : : CFile : : deleteFile ( tmpfile . c_str ( ) ) ;
}
else
{
string finalUrl ;
if ( it - > type = = ImgType )
{
CFile : : moveFile ( it - > dest , tmpfile ) ;
//if (lookupLocalFile (finalUrl, file.c_str(), false))
{
for ( uint i = 0 ; i < it - > imgs . size ( ) ; i + + )
{
setImage ( it - > imgs [ i ] . Image , it - > dest ) ;
setImageSize ( it - > imgs [ i ] . Image , it - > imgs [ i ] . Style ) ;
}
}
}
else
{
CFile : : moveFile ( it - > dest , tmpfile ) ;
//if (lookupLocalFile (finalUrl, file.c_str(), false))
{
CLuaManager : : getInstance ( ) . executeLuaScript ( it - > luaScript , true ) ;
}
}
}
Curls . erase ( it ) ;
break ;
}
}
}
}
}
RunningCurls = NewRunningCurls ;
# ifdef LOG_DL
if ( RunningCurls > 0 | | Curls . size ( ) > 0 )
nlwarning ( " (%s) RunningCurls %d, _Curls %d " , _Id . c_str ( ) , RunningCurls , Curls . size ( ) ) ;
# endif
}
void CGroupHTML : : releaseDownloads ( )
{
# ifdef LOG_DL
nlwarning ( " Release Downloads " ) ;
# endif
if ( MultiCurl )
curl_multi_cleanup ( MultiCurl ) ;
}
/*
void dolibcurltest ( )
{
nlwarning ( " start libcurl test " ) ;
initImageDownload ( ) ;
addImageDownload ( " http://www.ryzom.com/en/ " ) ;
addImageDownload ( " http://www.ryzom.com/fr/ " ) ;
addImageDownload ( " http://www.ryzom.com/de/ " ) ;
do
{
checkImageDownload ( ) ;
nlwarning ( " continue to sleep " ) ;
nlSleep ( 300 ) ;
}
while ( RunningCurls ) ;
releaseImageDownload ( ) ;
nlwarning ( " end libcurl test " ) ;
}
*/
class CGroupListAdaptor : public CInterfaceGroup
{
public :
CGroupListAdaptor ( const TCtorParam & param )
: CInterfaceGroup ( param )
{ }
private :
void updateCoords ( )
{
if ( _Parent )
{
// Get the W max from the parent
_W = std : : min ( _Parent - > getMaxWReal ( ) , _Parent - > getWReal ( ) ) ;
_WReal = _W ;
}
CInterfaceGroup : : updateCoords ( ) ;
}
} ;
// ***************************************************************************
template < class A > void popIfNotEmpty ( A & vect ) { if ( ! vect . empty ( ) ) vect . pop_back ( ) ; }
// ***************************************************************************
void CGroupHTML : : beginBuild ( )
{
if ( _Browsing )
{
_Connecting = false ;
removeContent ( ) ;
}
else
nlwarning ( " _Browsing = FALSE " ) ;
}
TStyle CGroupHTML : : parseStyle ( const string & str_styles )
{
TStyle styles ;
vector < string > elements ;
NLMISC : : splitString ( str_styles , " ; " , elements ) ;
for ( uint i = 0 ; i < elements . size ( ) ; + + i )
{
vector < string > style ;
NLMISC : : splitString ( elements [ i ] , " : " , style ) ;
if ( style . size ( ) > = 2 )
{
string fullstyle = style [ 1 ] ;
for ( uint j = 2 ; j < style . size ( ) ; j + + )
fullstyle + = " : " + style [ j ] ;
styles [ trim ( style [ 0 ] ) ] = trim ( fullstyle ) ;
}
}
return styles ;
}
// ***************************************************************************
void CGroupHTML : : addText ( const char * buf , int len )
{
if ( _Browsing )
{
if ( _IgnoreText )
return ;
// Build a UTF8 string
string inputString ( buf , buf + len ) ;
// inputString.resize (len);
// uint i;
// for (i=0; i<(uint)len; i++)
// inputString[i] = buf[i];
if ( _ParsingLua & & _TrustedDomain )
{
// we are parsing a lua script
_LuaScript + = inputString ;
// no more to do
return ;
}
// Build a unicode string
ucstring inputUCString ;
inputUCString . fromUtf8 ( inputString ) ;
// Build the final unicode string
ucstring tmp ;
tmp . reserve ( len ) ;
uint ucLen = ( uint ) inputUCString . size ( ) ;
//uint ucLenWithoutSpace = 0;
for ( uint i = 0 ; i < ucLen ; i + + )
{
ucchar output ;
bool keep ;
// special treatment for 'nbsp' (which is returned as a discreet space)
if ( inputString . size ( ) = = 1 & & inputString [ 0 ] = = 32 )
{
// this is a nbsp entity
output = inputUCString [ i ] ;
keep = true ;
}
else
{
// not nbsp, use normal white space removal routine
keep = translateChar ( output , inputUCString [ i ] , ( tmp . empty ( ) ) ? 0 : tmp [ tmp . size ( ) - 1 ] ) ;
}
if ( keep )
{
tmp . push_back ( output ) ;
/*
// Break if the string is more than 50 chars long without space
if ( output ! = ucchar ( ' ' ) )
{
ucLenWithoutSpace + + ;
if ( ucLenWithoutSpace = = 50 )
{
tmp . push_back ( ucchar ( ' ' ) ) ;
ucLenWithoutSpace = 0 ;
}
}
else
{
ucLenWithoutSpace = 0 ;
}
*/ }
}
if ( ! tmp . empty ( ) )
addString ( tmp ) ;
}
}
// ***************************************************************************
# define registerAnchorName(prefix) \
{ \
if ( present [ prefix # # _ID ] & & value [ prefix # # _ID ] ) \
_AnchorName . push_back ( value [ prefix # # _ID ] ) ; \
}
// ***************************************************************************
void CGroupHTML : : addLink ( uint element_number , const std : : vector < bool > & present , const std : : vector < const char * > & value )
{
if ( _Browsing )
{
if ( element_number = = HTML_A )
{
registerAnchorName ( MY_HTML_A ) ;
// #fragment works with both ID and NAME so register both
if ( present [ MY_HTML_A_NAME ] & & value [ MY_HTML_A_NAME ] )
_AnchorName . push_back ( value [ MY_HTML_A_NAME ] ) ;
if ( present [ MY_HTML_A_HREF ] & & value [ MY_HTML_A_HREF ] )
{
string suri = value [ MY_HTML_A_HREF ] ;
if ( suri . find ( " ah: " ) = = 0 )
{
if ( _TrustedDomain )
_Link . push_back ( suri ) ;
else
_Link . push_back ( " " ) ;
}
else if ( _TrustedDomain & & suri [ 0 ] = = ' # ' & & _LuaHrefHack )
{
// Direct url (hack for lua beginElement)
_Link . push_back ( suri . substr ( 1 ) ) ;
}
else
{
// convert href from "?key=val" into "http://domain.com/?key=val"
_Link . push_back ( getAbsoluteUrl ( suri ) ) ;
}
for ( uint8 i = MY_HTML_A_ACCESSKEY ; i < MY_HTML_A_Z_ACTION_SHORTCUT ; i + + )
{
if ( present [ i ] & & value [ i ] )
{
string title = value [ i ] ;
// nlinfo("key %d = %s", i, title.c_str());
}
}
//nlinfo("key of TITLE is : %d", MY_HTML_A_Z_ACTION_PARAMS);
if ( present [ MY_HTML_A_Z_ACTION_PARAMS ] & & value [ MY_HTML_A_Z_ACTION_PARAMS ] )
{
string title = value [ MY_HTML_A_Z_ACTION_PARAMS ] ;
_LinkTitle . push_back ( title ) ;
}
else
_LinkTitle . push_back ( " " ) ;
}
else
{
_Link . push_back ( " " ) ;
_LinkTitle . push_back ( " " ) ;
}
}
}
}
// ***************************************************************************
# define getCellsParameters(prefix,inherit) \
{ \
CGroupHTML : : CCellParams cellParams ; \
if ( ! _CellParams . empty ( ) & & inherit ) \
{ \
cellParams = _CellParams . back ( ) ; \
} \
if ( present [ prefix # # _BGCOLOR ] & & value [ prefix # # _BGCOLOR ] ) \
cellParams . BgColor = getColor ( value [ prefix # # _BGCOLOR ] ) ; \
if ( present [ prefix # # _L_MARGIN ] & & value [ prefix # # _L_MARGIN ] ) \
fromString ( value [ prefix # # _L_MARGIN ] , cellParams . LeftMargin ) ; \
if ( present [ prefix # # _NOWRAP ] ) \
cellParams . NoWrap = true ; \
if ( present [ prefix # # _ALIGN ] & & value [ prefix # # _ALIGN ] ) \
{ \
string align = toLower ( value [ prefix # # _ALIGN ] ) ; \
if ( align = = " left " ) \
cellParams . Align = CGroupCell : : Left ; \
if ( align = = " center " ) \
cellParams . Align = CGroupCell : : Center ; \
if ( align = = " right " ) \
cellParams . Align = CGroupCell : : Right ; \
} \
if ( present [ prefix # # _VALIGN ] & & value [ prefix # # _VALIGN ] ) \
{ \
string align = toLower ( value [ prefix # # _VALIGN ] ) ; \
if ( align = = " top " ) \
cellParams . VAlign = CGroupCell : : Top ; \
if ( align = = " middle " ) \
cellParams . VAlign = CGroupCell : : Middle ; \
if ( align = = " bottom " ) \
cellParams . VAlign = CGroupCell : : Bottom ; \
} \
_CellParams . push_back ( cellParams ) ; \
}
static bool isHexa ( char c )
{
return isdigit ( c ) | | ( tolower ( c ) > = ' a ' & & tolower ( c ) < = ' f ' ) ;
}
static uint8 convertHexa ( char c )
{
return ( uint8 ) ( tolower ( c ) - ( isdigit ( c ) ? ' 0 ' : ( ' a ' - 10 ) ) ) ;
}
// scan a color component, and return pointer to next position
static const char * scanColorComponent ( const char * src , uint8 & intensity )
{
if ( ! src ) return NULL ;
if ( ! isHexa ( * src ) ) return NULL ;
uint8 value = convertHexa ( * src + + ) < < 4 ;
if ( ! isHexa ( * src ) ) return NULL ;
value + = convertHexa ( * src + + ) ;
intensity = value ;
return src ;
}
class CNameToCol
{
public :
const char * Name ;
CRGBA Color ;
CNameToCol ( const char * name , CRGBA color ) : Name ( name ) , Color ( color ) { }
} ;
static CNameToCol htmlColorNameToRGBA [ ] =
{
CNameToCol ( " AliceBlue " , CRGBA ( 0xF0 , 0xF8 , 0xFF ) ) ,
CNameToCol ( " AntiqueWhite " , CRGBA ( 0xFA , 0xEB , 0xD7 ) ) ,
CNameToCol ( " Aqua " , CRGBA ( 0x00 , 0xFF , 0xFF ) ) ,
CNameToCol ( " Aquamarine " , CRGBA ( 0x7F , 0xFF , 0xD4 ) ) ,
CNameToCol ( " Azure " , CRGBA ( 0xF0 , 0xFF , 0xFF ) ) ,
CNameToCol ( " Beige " , CRGBA ( 0xF5 , 0xF5 , 0xDC ) ) ,
CNameToCol ( " Bisque " , CRGBA ( 0xFF , 0xE4 , 0xC4 ) ) ,
CNameToCol ( " Black " , CRGBA ( 0x00 , 0x00 , 0x00 ) ) ,
CNameToCol ( " BlanchedAlmond " , CRGBA ( 0xFF , 0xEB , 0xCD ) ) ,
CNameToCol ( " Blue " , CRGBA ( 0x00 , 0x00 , 0xFF ) ) ,
CNameToCol ( " BlueViolet " , CRGBA ( 0x8A , 0x2B , 0xE2 ) ) ,
CNameToCol ( " Brown " , CRGBA ( 0xA5 , 0x2A , 0x2A ) ) ,
CNameToCol ( " BurlyWood " , CRGBA ( 0xDE , 0xB8 , 0x87 ) ) ,
CNameToCol ( " CadetBlue " , CRGBA ( 0x5F , 0x9E , 0xA0 ) ) ,
CNameToCol ( " Chartreuse " , CRGBA ( 0x7F , 0xFF , 0x00 ) ) ,
CNameToCol ( " Chocolate " , CRGBA ( 0xD2 , 0x69 , 0x1E ) ) ,
CNameToCol ( " Coral " , CRGBA ( 0xFF , 0x7F , 0x50 ) ) ,
CNameToCol ( " CornflowerBlue " , CRGBA ( 0x64 , 0x95 , 0xED ) ) ,
CNameToCol ( " Cornsilk " , CRGBA ( 0xFF , 0xF8 , 0xDC ) ) ,
CNameToCol ( " Crimson " , CRGBA ( 0xDC , 0x14 , 0x3C ) ) ,
CNameToCol ( " Cyan " , CRGBA ( 0x00 , 0xFF , 0xFF ) ) ,
CNameToCol ( " DarkBlue " , CRGBA ( 0x00 , 0x00 , 0x8B ) ) ,
CNameToCol ( " DarkCyan " , CRGBA ( 0x00 , 0x8B , 0x8B ) ) ,
CNameToCol ( " DarkGoldenRod " , CRGBA ( 0xB8 , 0x86 , 0x0B ) ) ,
CNameToCol ( " DarkGray " , CRGBA ( 0xA9 , 0xA9 , 0xA9 ) ) ,
CNameToCol ( " DarkGreen " , CRGBA ( 0x00 , 0x64 , 0x00 ) ) ,
CNameToCol ( " DarkKhaki " , CRGBA ( 0xBD , 0xB7 , 0x6B ) ) ,
CNameToCol ( " DarkMagenta " , CRGBA ( 0x8B , 0x00 , 0x8B ) ) ,
CNameToCol ( " DarkOliveGreen " , CRGBA ( 0x55 , 0x6B , 0x2F ) ) ,
CNameToCol ( " Darkorange " , CRGBA ( 0xFF , 0x8C , 0x00 ) ) ,
CNameToCol ( " DarkOrchid " , CRGBA ( 0x99 , 0x32 , 0xCC ) ) ,
CNameToCol ( " DarkRed " , CRGBA ( 0x8B , 0x00 , 0x00 ) ) ,
CNameToCol ( " DarkSalmon " , CRGBA ( 0xE9 , 0x96 , 0x7A ) ) ,
CNameToCol ( " DarkSeaGreen " , CRGBA ( 0x8F , 0xBC , 0x8F ) ) ,
CNameToCol ( " DarkSlateBlue " , CRGBA ( 0x48 , 0x3D , 0x8B ) ) ,
CNameToCol ( " DarkSlateGray " , CRGBA ( 0x2F , 0x4F , 0x4F ) ) ,
CNameToCol ( " DarkTurquoise " , CRGBA ( 0x00 , 0xCE , 0xD1 ) ) ,
CNameToCol ( " DarkViolet " , CRGBA ( 0x94 , 0x00 , 0xD3 ) ) ,
CNameToCol ( " DeepPink " , CRGBA ( 0xFF , 0x14 , 0x93 ) ) ,
CNameToCol ( " DeepSkyBlue " , CRGBA ( 0x00 , 0xBF , 0xFF ) ) ,
CNameToCol ( " DimGray " , CRGBA ( 0x69 , 0x69 , 0x69 ) ) ,
CNameToCol ( " DodgerBlue " , CRGBA ( 0x1E , 0x90 , 0xFF ) ) ,
CNameToCol ( " Feldspar " , CRGBA ( 0xD1 , 0x92 , 0x75 ) ) ,
CNameToCol ( " FireBrick " , CRGBA ( 0xB2 , 0x22 , 0x22 ) ) ,
CNameToCol ( " FloralWhite " , CRGBA ( 0xFF , 0xFA , 0xF0 ) ) ,
CNameToCol ( " ForestGreen " , CRGBA ( 0x22 , 0x8B , 0x22 ) ) ,
CNameToCol ( " Fuchsia " , CRGBA ( 0xFF , 0x00 , 0xFF ) ) ,
CNameToCol ( " Gainsboro " , CRGBA ( 0xDC , 0xDC , 0xDC ) ) ,
CNameToCol ( " GhostWhite " , CRGBA ( 0xF8 , 0xF8 , 0xFF ) ) ,
CNameToCol ( " Gold " , CRGBA ( 0xFF , 0xD7 , 0x00 ) ) ,
CNameToCol ( " GoldenRod " , CRGBA ( 0xDA , 0xA5 , 0x20 ) ) ,
CNameToCol ( " Gray " , CRGBA ( 0x80 , 0x80 , 0x80 ) ) ,
CNameToCol ( " Green " , CRGBA ( 0x00 , 0x80 , 0x00 ) ) ,
CNameToCol ( " GreenYellow " , CRGBA ( 0xAD , 0xFF , 0x2F ) ) ,
CNameToCol ( " HoneyDew " , CRGBA ( 0xF0 , 0xFF , 0xF0 ) ) ,
CNameToCol ( " HotPink " , CRGBA ( 0xFF , 0x69 , 0xB4 ) ) ,
CNameToCol ( " IndianRed " , CRGBA ( 0xCD , 0x5C , 0x5C ) ) ,
CNameToCol ( " Indigo " , CRGBA ( 0x4B , 0x00 , 0x82 ) ) ,
CNameToCol ( " Ivory " , CRGBA ( 0xFF , 0xFF , 0xF0 ) ) ,
CNameToCol ( " Khaki " , CRGBA ( 0xF0 , 0xE6 , 0x8C ) ) ,
CNameToCol ( " Lavender " , CRGBA ( 0xE6 , 0xE6 , 0xFA ) ) ,
CNameToCol ( " LavenderBlush " , CRGBA ( 0xFF , 0xF0 , 0xF5 ) ) ,
CNameToCol ( " LawnGreen " , CRGBA ( 0x7C , 0xFC , 0x00 ) ) ,
CNameToCol ( " LemonChiffon " , CRGBA ( 0xFF , 0xFA , 0xCD ) ) ,
CNameToCol ( " LightBlue " , CRGBA ( 0xAD , 0xD8 , 0xE6 ) ) ,
CNameToCol ( " LightCoral " , CRGBA ( 0xF0 , 0x80 , 0x80 ) ) ,
CNameToCol ( " LightCyan " , CRGBA ( 0xE0 , 0xFF , 0xFF ) ) ,
CNameToCol ( " LightGoldenRodYellow " , CRGBA ( 0xFA , 0xFA , 0xD2 ) ) ,
CNameToCol ( " LightGrey " , CRGBA ( 0xD3 , 0xD3 , 0xD3 ) ) ,
CNameToCol ( " LightGreen " , CRGBA ( 0x90 , 0xEE , 0x90 ) ) ,
CNameToCol ( " LightPink " , CRGBA ( 0xFF , 0xB6 , 0xC1 ) ) ,
CNameToCol ( " LightSalmon " , CRGBA ( 0xFF , 0xA0 , 0x7A ) ) ,
CNameToCol ( " LightSeaGreen " , CRGBA ( 0x20 , 0xB2 , 0xAA ) ) ,
CNameToCol ( " LightSkyBlue " , CRGBA ( 0x87 , 0xCE , 0xFA ) ) ,
CNameToCol ( " LightSlateBlue " , CRGBA ( 0x84 , 0x70 , 0xFF ) ) ,
CNameToCol ( " LightSlateGray " , CRGBA ( 0x77 , 0x88 , 0x99 ) ) ,
CNameToCol ( " LightSteelBlue " , CRGBA ( 0xB0 , 0xC4 , 0xDE ) ) ,
CNameToCol ( " LightYellow " , CRGBA ( 0xFF , 0xFF , 0xE0 ) ) ,
CNameToCol ( " Lime " , CRGBA ( 0x00 , 0xFF , 0x00 ) ) ,
CNameToCol ( " LimeGreen " , CRGBA ( 0x32 , 0xCD , 0x32 ) ) ,
CNameToCol ( " Linen " , CRGBA ( 0xFA , 0xF0 , 0xE6 ) ) ,
CNameToCol ( " Magenta " , CRGBA ( 0xFF , 0x00 , 0xFF ) ) ,
CNameToCol ( " Maroon " , CRGBA ( 0x80 , 0x00 , 0x00 ) ) ,
CNameToCol ( " MediumAquaMarine " , CRGBA ( 0x66 , 0xCD , 0xAA ) ) ,
CNameToCol ( " MediumBlue " , CRGBA ( 0x00 , 0x00 , 0xCD ) ) ,
CNameToCol ( " MediumOrchid " , CRGBA ( 0xBA , 0x55 , 0xD3 ) ) ,
CNameToCol ( " MediumPurple " , CRGBA ( 0x93 , 0x70 , 0xD8 ) ) ,
CNameToCol ( " MediumSeaGreen " , CRGBA ( 0x3C , 0xB3 , 0x71 ) ) ,
CNameToCol ( " MediumSlateBlue " , CRGBA ( 0x7B , 0x68 , 0xEE ) ) ,
CNameToCol ( " MediumSpringGreen " , CRGBA ( 0x00 , 0xFA , 0x9A ) ) ,
CNameToCol ( " MediumTurquoise " , CRGBA ( 0x48 , 0xD1 , 0xCC ) ) ,
CNameToCol ( " MediumVioletRed " , CRGBA ( 0xC7 , 0x15 , 0x85 ) ) ,
CNameToCol ( " MidnightBlue " , CRGBA ( 0x19 , 0x19 , 0x70 ) ) ,
CNameToCol ( " MintCream " , CRGBA ( 0xF5 , 0xFF , 0xFA ) ) ,
CNameToCol ( " MistyRose " , CRGBA ( 0xFF , 0xE4 , 0xE1 ) ) ,
CNameToCol ( " Moccasin " , CRGBA ( 0xFF , 0xE4 , 0xB5 ) ) ,
CNameToCol ( " NavajoWhite " , CRGBA ( 0xFF , 0xDE , 0xAD ) ) ,
CNameToCol ( " Navy " , CRGBA ( 0x00 , 0x00 , 0x80 ) ) ,
CNameToCol ( " OldLace " , CRGBA ( 0xFD , 0xF5 , 0xE6 ) ) ,
CNameToCol ( " Olive " , CRGBA ( 0x80 , 0x80 , 0x00 ) ) ,
CNameToCol ( " OliveDrab " , CRGBA ( 0x6B , 0x8E , 0x23 ) ) ,
CNameToCol ( " Orange " , CRGBA ( 0xFF , 0xA5 , 0x00 ) ) ,
CNameToCol ( " OrangeRed " , CRGBA ( 0xFF , 0x45 , 0x00 ) ) ,
CNameToCol ( " Orchid " , CRGBA ( 0xDA , 0x70 , 0xD6 ) ) ,
CNameToCol ( " PaleGoldenRod " , CRGBA ( 0xEE , 0xE8 , 0xAA ) ) ,
CNameToCol ( " PaleGreen " , CRGBA ( 0x98 , 0xFB , 0x98 ) ) ,
CNameToCol ( " PaleTurquoise " , CRGBA ( 0xAF , 0xEE , 0xEE ) ) ,
CNameToCol ( " PaleVioletRed " , CRGBA ( 0xD8 , 0x70 , 0x93 ) ) ,
CNameToCol ( " PapayaWhip " , CRGBA ( 0xFF , 0xEF , 0xD5 ) ) ,
CNameToCol ( " PeachPuff " , CRGBA ( 0xFF , 0xDA , 0xB9 ) ) ,
CNameToCol ( " Peru " , CRGBA ( 0xCD , 0x85 , 0x3F ) ) ,
CNameToCol ( " Pink " , CRGBA ( 0xFF , 0xC0 , 0xCB ) ) ,
CNameToCol ( " Plum " , CRGBA ( 0xDD , 0xA0 , 0xDD ) ) ,
CNameToCol ( " PowderBlue " , CRGBA ( 0xB0 , 0xE0 , 0xE6 ) ) ,
CNameToCol ( " Purple " , CRGBA ( 0x80 , 0x00 , 0x80 ) ) ,
CNameToCol ( " Red " , CRGBA ( 0xFF , 0x00 , 0x00 ) ) ,
CNameToCol ( " RosyBrown " , CRGBA ( 0xBC , 0x8F , 0x8F ) ) ,
CNameToCol ( " RoyalBlue " , CRGBA ( 0x41 , 0x69 , 0xE1 ) ) ,
CNameToCol ( " SaddleBrown " , CRGBA ( 0x8B , 0x45 , 0x13 ) ) ,
CNameToCol ( " Salmon " , CRGBA ( 0xFA , 0x80 , 0x72 ) ) ,
CNameToCol ( " SandyBrown " , CRGBA ( 0xF4 , 0xA4 , 0x60 ) ) ,
CNameToCol ( " SeaGreen " , CRGBA ( 0x2E , 0x8B , 0x57 ) ) ,
CNameToCol ( " SeaShell " , CRGBA ( 0xFF , 0xF5 , 0xEE ) ) ,
CNameToCol ( " Sienna " , CRGBA ( 0xA0 , 0x52 , 0x2D ) ) ,
CNameToCol ( " Silver " , CRGBA ( 0xC0 , 0xC0 , 0xC0 ) ) ,
CNameToCol ( " SkyBlue " , CRGBA ( 0x87 , 0xCE , 0xEB ) ) ,
CNameToCol ( " SlateBlue " , CRGBA ( 0x6A , 0x5A , 0xCD ) ) ,
CNameToCol ( " SlateGray " , CRGBA ( 0x70 , 0x80 , 0x90 ) ) ,
CNameToCol ( " Snow " , CRGBA ( 0xFF , 0xFA , 0xFA ) ) ,
CNameToCol ( " SpringGreen " , CRGBA ( 0x00 , 0xFF , 0x7F ) ) ,
CNameToCol ( " SteelBlue " , CRGBA ( 0x46 , 0x82 , 0xB4 ) ) ,
CNameToCol ( " Tan " , CRGBA ( 0xD2 , 0xB4 , 0x8C ) ) ,
CNameToCol ( " Teal " , CRGBA ( 0x00 , 0x80 , 0x80 ) ) ,
CNameToCol ( " Thistle " , CRGBA ( 0xD8 , 0xBF , 0xD8 ) ) ,
CNameToCol ( " Tomato " , CRGBA ( 0xFF , 0x63 , 0x47 ) ) ,
CNameToCol ( " Turquoise " , CRGBA ( 0x40 , 0xE0 , 0xD0 ) ) ,
CNameToCol ( " Violet " , CRGBA ( 0xEE , 0x82 , 0xEE ) ) ,
CNameToCol ( " VioletRed " , CRGBA ( 0xD0 , 0x20 , 0x90 ) ) ,
CNameToCol ( " Wheat " , CRGBA ( 0xF5 , 0xDE , 0xB3 ) ) ,
CNameToCol ( " White " , CRGBA ( 0xFF , 0xFF , 0xFF ) ) ,
CNameToCol ( " WhiteSmoke " , CRGBA ( 0xF5 , 0xF5 , 0xF5 ) ) ,
CNameToCol ( " Yellow " , CRGBA ( 0xFF , 0xFF , 0x00 ) ) ,
CNameToCol ( " YellowGreen " , CRGBA ( 0x9A , 0xCD , 0x32 ) )
} ;
// scan a color from a HTML form (#rrggbb format)
bool scanHTMLColor ( const char * src , CRGBA & dest )
{
if ( ! src | | * src = = ' \0 ' ) return false ;
if ( * src = = ' # ' )
{
+ + src ;
CRGBA result ;
src = scanColorComponent ( src , result . R ) ; if ( ! src ) return false ;
src = scanColorComponent ( src , result . G ) ; if ( ! src ) return false ;
src = scanColorComponent ( src , result . B ) ; if ( ! src ) return false ;
src = scanColorComponent ( src , result . A ) ;
if ( ! src )
{
// Alpha is optional
result . A = 255 ;
}
dest = result ;
return true ;
}
else
{
// slow but should suffice for now
for ( uint k = 0 ; k < sizeofarray ( htmlColorNameToRGBA ) ; + + k )
{
if ( nlstricmp ( src , htmlColorNameToRGBA [ k ] . Name ) = = 0 )
{
dest = htmlColorNameToRGBA [ k ] . Color ;
return true ;
}
}
return false ;
}
}
// ***************************************************************************
void CGroupHTML : : beginElement ( uint element_number , const std : : vector < bool > & present , const std : : vector < const char * > & value )
{
if ( _Browsing )
{
// Paragraph ?
switch ( element_number )
{
case HTML_A :
{
CStyleParams style ;
style . FontSize = getFontSize ( ) ;
style . TextColor = LinkColor ;
style . Underlined = true ;
style . StrikeThrough = getFontStrikeThrough ( ) ;
if ( present [ HTML_A_STYLE ] & & value [ HTML_A_STYLE ] )
getStyleParams ( value [ HTML_A_STYLE ] , style ) ;
_FontSize . push_back ( style . FontSize ) ;
_TextColor . push_back ( style . TextColor ) ;
_FontUnderlined . push_back ( style . Underlined ) ;
_FontStrikeThrough . push_back ( style . StrikeThrough ) ;
_GlobalColor . push_back ( LinkColorGlobalColor ) ;
_A . push_back ( true ) ;
if ( present [ MY_HTML_A_TITLE ] & & value [ MY_HTML_A_TITLE ] )
_LinkTitle . push_back ( value [ MY_HTML_A_TITLE ] ) ;
if ( present [ MY_HTML_A_CLASS ] & & value [ MY_HTML_A_CLASS ] )
_LinkClass . push_back ( value [ MY_HTML_A_CLASS ] ) ;
}
break ;
case HTML_DIV :
{
registerAnchorName ( MY_HTML_DIV ) ;
if ( present [ MY_HTML_DIV_NAME ] & & value [ MY_HTML_DIV_NAME ] )
_DivName = value [ MY_HTML_DIV_NAME ] ;
string instClass ;
if ( present [ MY_HTML_DIV_CLASS ] & & value [ MY_HTML_DIV_CLASS ] )
instClass = value [ MY_HTML_DIV_CLASS ] ;
// use generic template system
if ( _TrustedDomain & & ! instClass . empty ( ) & & instClass = = " ryzom-ui-grouptemplate " )
{
string id ;
if ( present [ MY_HTML_DIV_ID ] & & value [ MY_HTML_DIV_ID ] )
id = value [ MY_HTML_DIV_ID ] ;
string style ;
if ( present [ MY_HTML_DIV_STYLE ] & & value [ MY_HTML_DIV_STYLE ] )
style = value [ MY_HTML_DIV_STYLE ] ;
typedef pair < string , string > TTmplParam ;
vector < TTmplParam > tmplParams ;
string templateName ;
if ( ! style . empty ( ) )
{
TStyle styles = parseStyle ( style ) ;
TStyle : : iterator it ;
for ( it = styles . begin ( ) ; it ! = styles . end ( ) ; it + + )
{
if ( ( * it ) . first = = " template " )
templateName = ( * it ) . second ;
else
tmplParams . push_back ( TTmplParam ( ( * it ) . first , ( * it ) . second ) ) ;
}
}
if ( ! templateName . empty ( ) )
{
string parentId ;
bool haveParentDiv = getDiv ( ) ! = NULL ;
if ( haveParentDiv )
parentId = getDiv ( ) - > getId ( ) ;
else
parentId = _Paragraph - > getId ( ) ;
CInterfaceGroup * inst = CWidgetManager : : getInstance ( ) - > getParser ( ) - > createGroupInstance ( templateName , parentId + " : " + id , tmplParams ) ;
if ( inst )
{
inst - > setId ( parentId + " : " + id ) ;
inst - > updateCoords ( ) ;
if ( haveParentDiv )
{
inst - > setParent ( getDiv ( ) ) ;
inst - > setParentSize ( getDiv ( ) ) ;
inst - > setParentPos ( getDiv ( ) ) ;
inst - > setPosRef ( Hotspot_TL ) ;
inst - > setParentPosRef ( Hotspot_TL ) ;
getDiv ( ) - > addGroup ( inst ) ;
}
else
{
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
getParagraph ( ) - > addChild ( inst ) ;
paragraphChange ( ) ;
}
_Divs . push_back ( inst ) ;
}
}
}
}
break ;
case HTML_FONT :
{
bool found = false ;
if ( present [ HTML_FONT_COLOR ] & & value [ HTML_FONT_COLOR ] )
{
CRGBA color ;
if ( scanHTMLColor ( value [ HTML_FONT_COLOR ] , color ) )
{
_TextColor . push_back ( color ) ;
found = true ;
}
}
if ( ! found )
{
_TextColor . push_back ( _TextColor . empty ( ) ? CRGBA : : White : _TextColor . back ( ) ) ;
}
if ( present [ HTML_FONT_SIZE ] & & value [ HTML_FONT_SIZE ] )
{
uint fontsize ;
fromString ( value [ HTML_FONT_SIZE ] , fontsize ) ;
_FontSize . push_back ( fontsize ) ;
}
else
{
_FontSize . push_back ( _FontSize . empty ( ) ? TextFontSize : _FontSize . back ( ) ) ;
}
}
break ;
case HTML_BR :
addString ( ucstring ( " \n " ) ) ;
break ;
case HTML_BODY :
{
if ( present [ HTML_BODY_BGCOLOR ] & & value [ HTML_BODY_BGCOLOR ] )
{
CRGBA bgColor = getColor ( value [ HTML_BODY_BGCOLOR ] ) ;
setBackgroundColor ( bgColor ) ;
}
string style ;
if ( present [ HTML_BODY_STYLE ] & & value [ HTML_BODY_STYLE ] )
style = value [ HTML_BODY_STYLE ] ;
if ( ! style . empty ( ) )
{
TStyle styles = parseStyle ( style ) ;
TStyle : : iterator it ;
it = styles . find ( " background-repeat " ) ;
bool repeat = ( it ! = styles . end ( ) & & it - > second = = " 1 " ) ;
// Webig only
it = styles . find ( " background-scale " ) ;
bool scale = ( it ! = styles . end ( ) & & it - > second = = " 1 " ) ;
it = styles . find ( " background-image " ) ;
if ( it ! = styles . end ( ) )
{
string image = it - > second ;
string : : size_type texExt = toLower ( image ) . find ( " url( " ) ;
// Url image
if ( texExt ! = string : : npos )
// Remove url()
image = image . substr ( 4 , image . size ( ) - 5 ) ;
setBackground ( image , scale , repeat ) ;
}
}
}
break ;
case HTML_FORM :
{
// Build the form
CGroupHTML : : CForm form ;
// Get the action name
if ( present [ HTML_FORM_ACTION ] & & value [ HTML_FORM_ACTION ] )
{
form . Action = getAbsoluteUrl ( string ( value [ HTML_FORM_ACTION ] ) ) ;
}
else
{
form . Action = _URL ;
}
_Forms . push_back ( form ) ;
}
break ;
case HTML_H1 :
registerAnchorName ( MY_HTML_H1 ) ;
newParagraph ( PBeginSpace ) ;
_FontSize . push_back ( H1FontSize ) ;
_TextColor . push_back ( H1Color ) ;
_GlobalColor . push_back ( H1ColorGlobalColor ) ;
break ;
case HTML_H2 :
registerAnchorName ( MY_HTML_H2 ) ;
newParagraph ( PBeginSpace ) ;
_FontSize . push_back ( H2FontSize ) ;
_TextColor . push_back ( H2Color ) ;
_GlobalColor . push_back ( H2ColorGlobalColor ) ;
break ;
case HTML_H3 :
registerAnchorName ( MY_HTML_H3 ) ;
newParagraph ( PBeginSpace ) ;
_FontSize . push_back ( H3FontSize ) ;
_TextColor . push_back ( H3Color ) ;
_GlobalColor . push_back ( H3ColorGlobalColor ) ;
break ;
case HTML_H4 :
registerAnchorName ( MY_HTML_H4 ) ;
newParagraph ( PBeginSpace ) ;
_FontSize . push_back ( H4FontSize ) ;
_TextColor . push_back ( H4Color ) ;
_GlobalColor . push_back ( H4ColorGlobalColor ) ;
break ;
case HTML_H5 :
registerAnchorName ( MY_HTML_H5 ) ;
newParagraph ( PBeginSpace ) ;
_FontSize . push_back ( H5FontSize ) ;
_TextColor . push_back ( H5Color ) ;
_GlobalColor . push_back ( H5ColorGlobalColor ) ;
break ;
case HTML_H6 :
registerAnchorName ( MY_HTML_H6 ) ;
newParagraph ( PBeginSpace ) ;
_FontSize . push_back ( H6FontSize ) ;
_TextColor . push_back ( H6Color ) ;
_GlobalColor . push_back ( H6ColorGlobalColor ) ;
break ;
case HTML_IMG :
{
// Get the string name
if ( present [ MY_HTML_IMG_SRC ] & & value [ MY_HTML_IMG_SRC ] )
{
CStyleParams style ;
float tmpf ;
if ( present [ MY_HTML_IMG_WIDTH ] & & value [ MY_HTML_IMG_WIDTH ] )
getPercentage ( style . Width , tmpf , value [ MY_HTML_IMG_WIDTH ] ) ;
if ( present [ MY_HTML_IMG_HEIGHT ] & & value [ MY_HTML_IMG_HEIGHT ] )
getPercentage ( style . Height , tmpf , value [ MY_HTML_IMG_HEIGHT ] ) ;
// width, height from inline css
if ( present [ MY_HTML_IMG_STYLE ] & & value [ MY_HTML_IMG_STYLE ] )
getStyleParams ( value [ MY_HTML_IMG_STYLE ] , style ) ;
// Get the global color name
bool globalColor = false ;
if ( present [ MY_HTML_IMG_GLOBAL_COLOR ] )
globalColor = true ;
if ( getA ( ) & & getParent ( ) & & getParent ( ) - > getParent ( ) )
{
// Tooltip
const char * tooltip = NULL ;
if ( present [ MY_HTML_IMG_ALT ] & & value [ MY_HTML_IMG_ALT ] )
tooltip = value [ MY_HTML_IMG_ALT ] ;
string params = " name= " + getId ( ) + " |url= " + getLink ( ) ;
addButton ( CCtrlButton : : PushButton , value [ MY_HTML_IMG_SRC ] , value [ MY_HTML_IMG_SRC ] , value [ MY_HTML_IMG_SRC ] ,
" " , globalColor , " browse " , params . c_str ( ) , tooltip , style ) ;
}
else
{
// Get the option to reload (class==reload)
bool reloadImg = false ;
string styleString ;
if ( present [ MY_HTML_IMG_STYLE ] & & value [ MY_HTML_IMG_STYLE ] )
styleString = value [ MY_HTML_IMG_STYLE ] ;
if ( ! styleString . empty ( ) )
{
TStyle styles = parseStyle ( styleString ) ;
TStyle : : iterator it ;
it = styles . find ( " reload " ) ;
if ( it ! = styles . end ( ) & & ( * it ) . second = = " 1 " )
reloadImg = true ;
}
addImage ( value [ MY_HTML_IMG_SRC ] , globalColor , reloadImg , style ) ;
}
}
}
break ;
case HTML_INPUT :
// Got one form ?
if ( ! ( _Forms . empty ( ) ) )
{
// read general property
string templateName ;
string minWidth ;
// Widget template name
if ( present [ MY_HTML_INPUT_Z_BTN_TMPL ] & & value [ MY_HTML_INPUT_Z_BTN_TMPL ] )
templateName = value [ MY_HTML_INPUT_Z_BTN_TMPL ] ;
// Input name is the new
if ( present [ MY_HTML_INPUT_Z_INPUT_TMPL ] & & value [ MY_HTML_INPUT_Z_INPUT_TMPL ] )
templateName = value [ MY_HTML_INPUT_Z_INPUT_TMPL ] ;
// Widget minimal width
if ( present [ MY_HTML_INPUT_Z_INPUT_WIDTH ] & & value [ MY_HTML_INPUT_Z_INPUT_WIDTH ] )
minWidth = value [ MY_HTML_INPUT_Z_INPUT_WIDTH ] ;
// Get the type
if ( present [ MY_HTML_INPUT_TYPE ] & & value [ MY_HTML_INPUT_TYPE ] )
{
// Global color flag
bool globalColor = false ;
if ( present [ MY_HTML_INPUT_GLOBAL_COLOR ] )
globalColor = true ;
// Tooltip
const char * tooltip = NULL ;
if ( present [ MY_HTML_INPUT_ALT ] & & value [ MY_HTML_INPUT_ALT ] )
tooltip = value [ MY_HTML_INPUT_ALT ] ;
string type = toLower ( value [ MY_HTML_INPUT_TYPE ] ) ;
if ( type = = " image " )
{
CStyleParams style ;
// width, height from inline css
if ( present [ MY_HTML_INPUT_STYLE ] & & value [ MY_HTML_INPUT_STYLE ] )
getStyleParams ( value [ MY_HTML_INPUT_STYLE ] , style ) ;
// The submit button
string name ;
string normal ;
string pushed ;
string over ;
if ( present [ MY_HTML_INPUT_NAME ] & & value [ MY_HTML_INPUT_NAME ] )
name = value [ MY_HTML_INPUT_NAME ] ;
if ( present [ MY_HTML_INPUT_SRC ] & & value [ MY_HTML_INPUT_SRC ] )
normal = value [ MY_HTML_INPUT_SRC ] ;
// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
string param = " name= " + getId ( ) + " |form= " + toString ( _Forms . size ( ) - 1 ) + " |submit_button= " + name + " |submit_button_type=image " ;
// Add the ctrl button
addButton ( CCtrlButton : : PushButton , name , normal , pushed . empty ( ) ? normal : pushed , over ,
globalColor , " html_submit_form " , param . c_str ( ) , tooltip , style ) ;
}
if ( type = = " button " | | type = = " submit " )
{
// The submit button
string name ;
string text ;
string normal ;
string pushed ;
string over ;
string buttonTemplate ( ! templateName . empty ( ) ? templateName : DefaultButtonGroup ) ;
if ( present [ MY_HTML_INPUT_NAME ] & & value [ MY_HTML_INPUT_NAME ] )
name = value [ MY_HTML_INPUT_NAME ] ;
if ( present [ MY_HTML_INPUT_SRC ] & & value [ MY_HTML_INPUT_SRC ] )
normal = value [ MY_HTML_INPUT_SRC ] ;
if ( present [ MY_HTML_INPUT_VALUE ] & & value [ MY_HTML_INPUT_VALUE ] )
text = value [ MY_HTML_INPUT_VALUE ] ;
// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
string param = " name= " + getId ( ) + " |form= " + toString ( _Forms . size ( ) - 1 ) + " |submit_button= " + name + " |submit_button_type=submit " ;
if ( text . size ( ) > 0 )
{
// escape AH param separator
string tmp = text ;
while ( NLMISC : : strFindReplace ( tmp , " | " , " | " ) )
;
param = param + " |submit_button_value= " + tmp ;
}
// Add the ctrl button
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
typedef pair < string , string > TTmplParam ;
vector < TTmplParam > tmplParams ;
tmplParams . push_back ( TTmplParam ( " id " , name ) ) ;
tmplParams . push_back ( TTmplParam ( " onclick " , " html_submit_form " ) ) ;
tmplParams . push_back ( TTmplParam ( " onclick_param " , param ) ) ;
//tmplParams.push_back(TTmplParam("text", text));
tmplParams . push_back ( TTmplParam ( " active " , " true " ) ) ;
if ( ! minWidth . empty ( ) )
tmplParams . push_back ( TTmplParam ( " wmin " , minWidth ) ) ;
CInterfaceGroup * buttonGroup = CWidgetManager : : getInstance ( ) - > getParser ( ) - > createGroupInstance ( buttonTemplate , _Paragraph - > getId ( ) , tmplParams ) ;
if ( buttonGroup )
{
// Add the ctrl button
CCtrlTextButton * ctrlButton = dynamic_cast < CCtrlTextButton * > ( buttonGroup - > getCtrl ( " button " ) ) ;
if ( ! ctrlButton ) ctrlButton = dynamic_cast < CCtrlTextButton * > ( buttonGroup - > getCtrl ( " b " ) ) ;
if ( ctrlButton )
{
ctrlButton - > setModulateGlobalColorAll ( globalColor ) ;
// Translate the tooltip
if ( tooltip )
{
if ( CI18N : : hasTranslation ( tooltip ) )
{
ctrlButton - > setDefaultContextHelp ( CI18N : : get ( tooltip ) ) ;
}
else
{
ctrlButton - > setDefaultContextHelp ( ucstring ( tooltip ) ) ;
}
}
ctrlButton - > setText ( ucstring : : makeFromUtf8 ( text ) ) ;
}
getParagraph ( ) - > addChild ( buttonGroup ) ;
paragraphChange ( ) ;
}
// addButton (CCtrlTextButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
// globalColor, "html_submit_form", param.c_str(), tooltip);
}
else if ( type = = " text " )
{
// Get the string name
string name ;
ucstring ucValue ;
uint size = 120 ;
uint maxlength = 1024 ;
if ( present [ MY_HTML_INPUT_NAME ] & & value [ MY_HTML_INPUT_NAME ] )
name = value [ MY_HTML_INPUT_NAME ] ;
if ( present [ MY_HTML_INPUT_SIZE ] & & value [ MY_HTML_INPUT_SIZE ] )
fromString ( value [ MY_HTML_INPUT_SIZE ] , size ) ;
if ( present [ MY_HTML_INPUT_VALUE ] & & value [ MY_HTML_INPUT_VALUE ] )
ucValue . fromUtf8 ( value [ MY_HTML_INPUT_VALUE ] ) ;
if ( present [ MY_HTML_INPUT_MAXLENGTH ] & & value [ MY_HTML_INPUT_MAXLENGTH ] )
fromString ( value [ MY_HTML_INPUT_MAXLENGTH ] , maxlength ) ;
string textTemplate ( ! templateName . empty ( ) ? templateName : DefaultFormTextGroup ) ;
// Add the editbox
CInterfaceGroup * textArea = addTextArea ( textTemplate , name . c_str ( ) , 1 , size / 12 , false , ucValue , maxlength ) ;
if ( textArea )
{
// Add the text area to the form
CGroupHTML : : CForm : : CEntry entry ;
entry . Name = name ;
entry . TextArea = textArea ;
_Forms . back ( ) . Entries . push_back ( entry ) ;
}
}
else if ( type = = " checkbox " | | type = = " radio " )
{
CCtrlButton : : EType btnType ;
string name ;
string normal ;
string pushed ;
string over ;
ucstring ucValue = ucstring ( " on " ) ;
bool checked = false ;
if ( type = = " radio " )
{
btnType = CCtrlButton : : RadioButton ;
normal = DefaultRadioButtonBitmapNormal ;
pushed = DefaultRadioButtonBitmapPushed ;
over = DefaultRadioButtonBitmapOver ;
}
else
{
btnType = CCtrlButton : : ToggleButton ;
normal = DefaultCheckBoxBitmapNormal ;
pushed = DefaultCheckBoxBitmapPushed ;
over = DefaultCheckBoxBitmapOver ;
}
if ( present [ MY_HTML_INPUT_NAME ] & & value [ MY_HTML_INPUT_NAME ] )
name = value [ MY_HTML_INPUT_NAME ] ;
if ( present [ MY_HTML_INPUT_SRC ] & & value [ MY_HTML_INPUT_SRC ] )
normal = value [ MY_HTML_INPUT_SRC ] ;
if ( present [ MY_HTML_INPUT_VALUE ] & & value [ MY_HTML_INPUT_VALUE ] )
ucValue . fromUtf8 ( value [ MY_HTML_INPUT_VALUE ] ) ;
checked = ( present [ MY_HTML_INPUT_CHECKED ] & & value [ MY_HTML_INPUT_CHECKED ] ) ;
// Add the ctrl button
CCtrlButton * checkbox = addButton ( btnType , name , normal , pushed , over ,
globalColor , " " , " " , tooltip ) ;
if ( checkbox )
{
if ( btnType = = CCtrlButton : : RadioButton )
{
// group together buttons with same name
CForm & form = _Forms . back ( ) ;
bool notfound = true ;
for ( uint i = 0 ; i < form . Entries . size ( ) ; i + + )
{
if ( form . Entries [ i ] . Name = = name & & form . Entries [ i ] . Checkbox - > getType ( ) = = CCtrlButton : : RadioButton )
{
checkbox - > initRBRefFromRadioButton ( form . Entries [ i ] . Checkbox ) ;
notfound = false ;
break ;
}
}
if ( notfound )
{
// this will start a new group (initRBRef() would take first button in group container otherwise)
checkbox - > initRBRefFromRadioButton ( checkbox ) ;
}
}
checkbox - > setPushed ( checked ) ;
// Add the button to the form
CGroupHTML : : CForm : : CEntry entry ;
entry . Name = name ;
entry . Value = decodeHTMLEntities ( ucValue ) ;
entry . Checkbox = checkbox ;
_Forms . back ( ) . Entries . push_back ( entry ) ;
}
}
else if ( type = = " hidden " )
{
if ( present [ MY_HTML_INPUT_NAME ] & & value [ MY_HTML_INPUT_NAME ] )
{
// Get the name
string name = value [ MY_HTML_INPUT_NAME ] ;
// Get the value
ucstring ucValue ;
if ( present [ MY_HTML_INPUT_VALUE ] & & value [ MY_HTML_INPUT_VALUE ] )
ucValue . fromUtf8 ( value [ MY_HTML_INPUT_VALUE ] ) ;
// Add an entry
CGroupHTML : : CForm : : CEntry entry ;
entry . Name = name ;
entry . Value = decodeHTMLEntities ( ucValue ) ;
_Forms . back ( ) . Entries . push_back ( entry ) ;
}
}
}
}
break ;
case HTML_SELECT :
if ( ! ( _Forms . empty ( ) ) )
{
// A select box
string name ;
if ( present [ HTML_SELECT_NAME ] & & value [ HTML_SELECT_NAME ] )
name = value [ HTML_SELECT_NAME ] ;
CDBGroupComboBox * cb = addComboBox ( DefaultFormSelectGroup , name . c_str ( ) ) ;
CGroupHTML : : CForm : : CEntry entry ;
entry . Name = name ;
entry . ComboBox = cb ;
_Forms . back ( ) . Entries . push_back ( entry ) ;
}
break ;
case HTML_OPTION :
// Got one form ?
if ( ! ( _Forms . empty ( ) ) )
{
if ( ! _Forms . back ( ) . Entries . empty ( ) )
{
// clear the option string
_SelectOptionStr . clear ( ) ;
std : : string optionValue ;
bool selected = false ;
if ( present [ HTML_OPTION_VALUE ] & & value [ HTML_OPTION_VALUE ] )
optionValue = value [ HTML_OPTION_VALUE ] ;
if ( present [ HTML_OPTION_SELECTED ] & & value [ HTML_OPTION_SELECTED ] )
selected = nlstricmp ( value [ HTML_OPTION_SELECTED ] , " selected " ) = = 0 ;
_Forms . back ( ) . Entries . back ( ) . SelectValues . push_back ( optionValue ) ;
if ( selected )
{
_Forms . back ( ) . Entries . back ( ) . InitialSelection = ( sint ) _Forms . back ( ) . Entries . back ( ) . SelectValues . size ( ) - 1 ;
}
}
}
_SelectOption = true ;
break ;
case HTML_LI :
if ( getUL ( ) )
{
// First LI ?
if ( ! _LI )
{
_LI = true ;
newParagraph ( ULBeginSpace ) ;
}
else
{
newParagraph ( LIBeginSpace ) ;
}
ucstring str ;
str + = ( ucchar ) 0x2219 ;
str + = ( ucchar ) ' ' ;
addString ( str ) ;
flushString ( ) ;
getParagraph ( ) - > setFirstViewIndent ( LIIndent ) ;
}
2015-12-18 12:29:40 +00:00
else if ( ! _OL . empty ( ) )
{
if ( _OL . back ( ) . First )
{
_OL . back ( ) . First = false ;
newParagraph ( ULBeginSpace ) ;
}
else
{
newParagraph ( LIBeginSpace ) ;
}
// OL list index can be overridden by <li value="1"> attribute
if ( present [ HTML_LI_VALUE ] & & value [ HTML_LI_VALUE ] )
fromString ( value [ HTML_LI_VALUE ] , _OL . back ( ) . Value ) ;
ucstring str ;
str . fromUtf8 ( _OL . back ( ) . getListMarkerText ( ) + " . " ) ;
addString ( str ) ;
flushString ( ) ;
getParagraph ( ) - > setFirstViewIndent ( LIIndent ) ;
_OL . back ( ) . Value + + ;
}
2015-12-13 19:23:08 +00:00
break ;
case HTML_P :
newParagraph ( PBeginSpace ) ;
break ;
case HTML_PRE :
_PRE . push_back ( true ) ;
break ;
case HTML_TABLE :
{
registerAnchorName ( MY_HTML_TABLE ) ;
// Get cells parameters
getCellsParameters ( MY_HTML_TABLE , false ) ;
CGroupTable * table = new CGroupTable ( TCtorParam ( ) ) ;
table - > BgColor = _CellParams . back ( ) . BgColor ;
if ( present [ MY_HTML_TABLE_WIDTH ] & & value [ MY_HTML_TABLE_WIDTH ] )
getPercentage ( table - > ForceWidthMin , table - > TableRatio , value [ MY_HTML_TABLE_WIDTH ] ) ;
if ( present [ MY_HTML_TABLE_BORDER ] & & value [ MY_HTML_TABLE_BORDER ] )
fromString ( value [ MY_HTML_TABLE_BORDER ] , table - > Border ) ;
if ( present [ MY_HTML_TABLE_BORDERCOLOR ] & & value [ MY_HTML_TABLE_BORDERCOLOR ] )
table - > BorderColor = getColor ( value [ MY_HTML_TABLE_BORDERCOLOR ] ) ;
if ( present [ MY_HTML_TABLE_CELLSPACING ] & & value [ MY_HTML_TABLE_CELLSPACING ] )
fromString ( value [ MY_HTML_TABLE_CELLSPACING ] , table - > CellSpacing ) ;
if ( present [ MY_HTML_TABLE_CELLPADDING ] & & value [ MY_HTML_TABLE_CELLPADDING ] )
fromString ( value [ MY_HTML_TABLE_CELLPADDING ] , table - > CellPadding ) ;
// Table must fit the container size
addGroup ( table , 0 ) ;
_Tables . push_back ( table ) ;
// Add a cell pointer
_Cells . push_back ( NULL ) ;
_TR . push_back ( false ) ;
}
break ;
case HTML_TD :
{
// Get cells parameters
getCellsParameters ( MY_HTML_TD , true ) ;
CGroupTable * table = getTable ( ) ;
if ( table )
{
if ( ! _Cells . empty ( ) )
{
_Cells . back ( ) = new CGroupCell ( CViewBase : : TCtorParam ( ) ) ;
string style ;
if ( present [ MY_HTML_TD_STYLE ] & & value [ MY_HTML_TD_STYLE ] )
style = value [ MY_HTML_TD_STYLE ] ;
// Set the cell parameters
if ( ! style . empty ( ) )
{
TStyle styles = parseStyle ( style ) ;
TStyle : : iterator it ;
it = styles . find ( " background-repeat " ) ;
_Cells . back ( ) - > setTextureTile ( it ! = styles . end ( ) ) ;
// Webig only
it = styles . find ( " background-scale " ) ;
_Cells . back ( ) - > setTextureScale ( it ! = styles . end ( ) ) ;
it = styles . find ( " background-image " ) ;
if ( it ! = styles . end ( ) )
{
nlinfo ( " found background-image %s " , it - > second . c_str ( ) ) ;
string image = ( * it ) . second ;
string : : size_type texExt = toLower ( image ) . find ( " url( " ) ;
// Url image
if ( texExt ! = string : : npos )
{
// Remove url()
image = image . substr ( 4 , image . size ( ) - 5 ) ;
addImageDownload ( image , _Cells . back ( ) ) ;
// Image in BNP
}
else
{
_Cells . back ( ) - > setTexture ( image ) ;
}
}
}
if ( present [ MY_HTML_TD_COLSPAN ] & & value [ MY_HTML_TD_COLSPAN ] )
fromString ( value [ MY_HTML_TD_COLSPAN ] , _Cells . back ( ) - > ColSpan ) ;
if ( present [ MY_HTML_TD_ROWSPAN ] & & value [ MY_HTML_TD_ROWSPAN ] )
fromString ( value [ MY_HTML_TD_ROWSPAN ] , _Cells . back ( ) - > RowSpan ) ;
_Cells . back ( ) - > BgColor = _CellParams . back ( ) . BgColor ;
_Cells . back ( ) - > Align = _CellParams . back ( ) . Align ;
_Cells . back ( ) - > VAlign = _CellParams . back ( ) . VAlign ;
_Cells . back ( ) - > LeftMargin = _CellParams . back ( ) . LeftMargin ;
_Cells . back ( ) - > NoWrap = _CellParams . back ( ) . NoWrap ;
_Cells . back ( ) - > ColSpan = std : : max ( 1 , _Cells . back ( ) - > ColSpan ) ;
_Cells . back ( ) - > RowSpan = std : : max ( 1 , _Cells . back ( ) - > RowSpan ) ;
float temp ;
if ( present [ MY_HTML_TD_WIDTH ] & & value [ MY_HTML_TD_WIDTH ] )
getPercentage ( _Cells . back ( ) - > WidthWanted , _Cells . back ( ) - > TableRatio , value [ MY_HTML_TD_WIDTH ] ) ;
if ( present [ MY_HTML_TD_HEIGHT ] & & value [ MY_HTML_TD_HEIGHT ] )
getPercentage ( _Cells . back ( ) - > Height , temp , value [ MY_HTML_TD_HEIGHT ] ) ;
_Cells . back ( ) - > NewLine = getTR ( ) ;
table - > addChild ( _Cells . back ( ) ) ;
newParagraph ( TDBeginSpace ) ;
// Reset TR flag
if ( ! _TR . empty ( ) )
_TR . back ( ) = false ;
}
}
}
break ;
case HTML_TEXTAREA :
// Got one form ?
if ( ! ( _Forms . empty ( ) ) )
{
// read general property
string templateName ;
// Widget template name
if ( present [ MY_HTML_TEXTAREA_Z_INPUT_TMPL ] & & value [ MY_HTML_TEXTAREA_Z_INPUT_TMPL ] )
templateName = value [ MY_HTML_TEXTAREA_Z_INPUT_TMPL ] ;
// Get the string name
_TextAreaName = " " ;
_TextAreaRow = 1 ;
_TextAreaCols = 10 ;
_TextAreaContent = " " ;
_TextAreaMaxLength = 1024 ;
if ( present [ MY_HTML_TEXTAREA_NAME ] & & value [ MY_HTML_TEXTAREA_NAME ] )
_TextAreaName = value [ MY_HTML_TEXTAREA_NAME ] ;
if ( present [ MY_HTML_TEXTAREA_ROWS ] & & value [ MY_HTML_TEXTAREA_ROWS ] )
fromString ( value [ MY_HTML_TEXTAREA_ROWS ] , _TextAreaRow ) ;
if ( present [ MY_HTML_TEXTAREA_COLS ] & & value [ MY_HTML_TEXTAREA_COLS ] )
fromString ( value [ MY_HTML_TEXTAREA_COLS ] , _TextAreaCols ) ;
if ( present [ MY_HTML_TEXTAREA_MAXLENGTH ] & & value [ MY_HTML_TEXTAREA_MAXLENGTH ] )
fromString ( value [ MY_HTML_TEXTAREA_MAXLENGTH ] , _TextAreaMaxLength ) ;
_TextAreaTemplate = ! templateName . empty ( ) ? templateName : DefaultFormTextAreaGroup ;
_TextArea = true ;
}
break ;
case HTML_TITLE :
{
if ( ! _TitlePrefix . empty ( ) )
_TitleString = _TitlePrefix + " - " ;
else
_TitleString = " " ;
_Title = true ;
}
break ;
case HTML_I :
{
_Localize = true ;
}
break ;
case HTML_TR :
{
// Get cells parameters
getCellsParameters ( MY_HTML_TR , true ) ;
// Set TR flag
if ( ! _TR . empty ( ) )
_TR . back ( ) = true ;
}
break ;
case HTML_UL :
_Indent + = ULIndent ;
_LI = false ;
endParagraph ( ) ;
_UL . push_back ( true ) ;
break ;
case HTML_OBJECT :
_ObjectType = " " ;
_ObjectData = " " ;
_ObjectMD5Sum = " " ;
_ObjectAction = " " ;
if ( present [ HTML_OBJECT_TYPE ] & & value [ HTML_OBJECT_TYPE ] )
_ObjectType = value [ HTML_OBJECT_TYPE ] ;
if ( present [ HTML_OBJECT_DATA ] & & value [ HTML_OBJECT_DATA ] )
_ObjectData = value [ HTML_OBJECT_DATA ] ;
if ( present [ HTML_OBJECT_ID ] & & value [ HTML_OBJECT_ID ] )
_ObjectMD5Sum = value [ HTML_OBJECT_ID ] ;
if ( present [ HTML_OBJECT_STANDBY ] & & value [ HTML_OBJECT_STANDBY ] )
_ObjectAction = value [ HTML_OBJECT_STANDBY ] ;
_Object = true ;
break ;
case HTML_SPAN :
{
CStyleParams style ;
style . TextColor = getTextColor ( ) ;
style . FontSize = getFontSize ( ) ;
style . FontWeight = getFontWeight ( ) ;
style . FontOblique = getFontOblique ( ) ;
style . Underlined = getFontUnderlined ( ) ;
style . StrikeThrough = getFontStrikeThrough ( ) ;
if ( present [ MY_HTML_SPAN_STYLE ] & & value [ MY_HTML_SPAN_STYLE ] )
getStyleParams ( value [ MY_HTML_SPAN_STYLE ] , style ) ;
_TextColor . push_back ( style . TextColor ) ;
_FontSize . push_back ( style . FontSize ) ;
_FontWeight . push_back ( style . FontWeight ) ;
_FontOblique . push_back ( style . FontOblique ) ;
_FontUnderlined . push_back ( style . Underlined ) ;
_FontStrikeThrough . push_back ( style . StrikeThrough ) ;
}
break ;
case HTML_DEL :
_FontStrikeThrough . push_back ( true ) ;
break ;
case HTML_U :
_FontUnderlined . push_back ( true ) ;
break ;
case HTML_EM :
_FontOblique . push_back ( true ) ;
break ;
case HTML_STRONG :
_FontWeight . push_back ( FONT_WEIGHT_BOLD ) ;
break ;
case HTML_SMALL :
_FontSize . push_back ( getFontSizeSmaller ( ) ) ;
break ;
case HTML_STYLE :
case HTML_SCRIPT :
_IgnoreText = true ;
break ;
case HTML_DL :
_DL . push_back ( true ) ;
endParagraph ( ) ;
break ;
case HTML_DT :
if ( getDL ( ) )
{
newParagraph ( 0 ) ;
// see if this is the first <dt>, closing tag not required
if ( ! _DT )
{
_DT = true ;
_FontWeight . push_back ( FONT_WEIGHT_BOLD ) ;
}
if ( _DL . size ( ) > 1 )
{
uint indent = ( _DL . size ( ) - 1 ) * ULIndent ;
getParagraph ( ) - > setFirstViewIndent ( indent ) ;
}
}
break ;
case HTML_DD :
if ( getDL ( ) )
{
newParagraph ( 0 ) ;
// if there was no closing tag for <dt>, then remove <dt> style
if ( _DT )
{
_DT = false ;
popIfNotEmpty ( _FontWeight ) ;
}
uint indent = _DL . size ( ) * ULIndent ;
getParagraph ( ) - > setFirstViewIndent ( indent ) ;
}
break ;
2015-12-18 12:29:40 +00:00
case HTML_OL :
{
sint32 start = 1 ;
std : : string type ( " 1 " ) ;
if ( present [ HTML_OL_START ] & & value [ HTML_OL_START ] )
fromString ( value [ HTML_OL_START ] , start ) ;
if ( present [ HTML_OL_TYPE ] & & value [ HTML_OL_TYPE ] )
type = value [ HTML_OL_TYPE ] ;
_OL . push_back ( HTMLOListElement ( start , type ) ) ;
_Indent + = ULIndent ;
endParagraph ( ) ;
}
break ;
2015-12-18 12:29:40 +00:00
case HTML_HR :
{
newParagraph ( 0 ) ;
CInterfaceGroup * sep = CWidgetManager : : getInstance ( ) - > getParser ( ) - > createGroupInstance ( " html_hr " , " " , NULL , 0 ) ;
if ( sep )
{
CStyleParams style ;
style . TextColor = CRGBA ( 120 , 120 , 120 , 255 ) ;
style . Height = 0 ;
style . Width = 0 ;
if ( present [ HTML_HR_STYLE ] & & value [ HTML_HR_STYLE ] )
getStyleParams ( value [ HTML_HR_STYLE ] , style ) ;
CViewBitmap * bitmap = dynamic_cast < CViewBitmap * > ( sep - > getView ( " hr " ) ) ;
if ( bitmap )
{
bitmap - > setColor ( style . TextColor ) ;
if ( style . Width > 0 )
{
clamp ( style . Width , 1 , 32000 ) ;
bitmap - > setW ( style . Width ) ;
bitmap - > setSizeRef ( CInterfaceElement : : none ) ;
}
if ( style . Height > 0 )
{
clamp ( style . Height , 1 , 1000 ) ;
bitmap - > setH ( style . Height ) ;
}
}
getParagraph ( ) - > addChild ( sep ) ;
endParagraph ( ) ;
}
}
break ;
2015-12-13 19:23:08 +00:00
}
}
}
// ***************************************************************************
void CGroupHTML : : endElement ( uint element_number )
{
if ( _Browsing )
{
// Paragraph ?
switch ( element_number )
{
case HTML_FONT :
popIfNotEmpty ( _TextColor ) ;
popIfNotEmpty ( _FontSize ) ;
break ;
case HTML_A :
popIfNotEmpty ( _FontSize ) ;
popIfNotEmpty ( _TextColor ) ;
popIfNotEmpty ( _FontUnderlined ) ;
popIfNotEmpty ( _FontStrikeThrough ) ;
popIfNotEmpty ( _GlobalColor ) ;
popIfNotEmpty ( _A ) ;
popIfNotEmpty ( _Link ) ;
popIfNotEmpty ( _LinkTitle ) ;
popIfNotEmpty ( _LinkClass ) ;
break ;
case HTML_H1 :
case HTML_H2 :
case HTML_H3 :
case HTML_H4 :
case HTML_H5 :
case HTML_H6 :
popIfNotEmpty ( _FontSize ) ;
popIfNotEmpty ( _TextColor ) ;
popIfNotEmpty ( _GlobalColor ) ;
endParagraph ( ) ;
break ;
case HTML_PRE :
popIfNotEmpty ( _PRE ) ;
break ;
case HTML_DIV :
_DivName = " " ;
popIfNotEmpty ( _Divs ) ;
break ;
case HTML_TABLE :
popIfNotEmpty ( _CellParams ) ;
popIfNotEmpty ( _TR ) ;
popIfNotEmpty ( _Cells ) ;
popIfNotEmpty ( _Tables ) ;
endParagraph ( ) ;
// Add a cell
break ;
case HTML_TD :
popIfNotEmpty ( _CellParams ) ;
if ( ! _Cells . empty ( ) )
_Cells . back ( ) = NULL ;
break ;
case HTML_TR :
popIfNotEmpty ( _CellParams ) ;
break ;
case HTML_TEXTAREA :
{
_TextArea = false ;
if ( ! ( _Forms . empty ( ) ) )
{
CInterfaceGroup * textArea = addTextArea ( _TextAreaTemplate , _TextAreaName . c_str ( ) , _TextAreaRow , _TextAreaCols , true , _TextAreaContent , _TextAreaMaxLength ) ;
if ( textArea )
{
// Add the text area to the form
CGroupHTML : : CForm : : CEntry entry ;
entry . Name = _TextAreaName ;
entry . TextArea = textArea ;
_Forms . back ( ) . Entries . push_back ( entry ) ;
}
}
}
break ;
case HTML_TITLE :
{
_Title = false ;
// Get the parent container
setTitle ( _TitleString ) ;
}
break ;
case HTML_SELECT :
{
_SelectOption = false ;
if ( ! ( _Forms . empty ( ) ) )
{
if ( ! _Forms . back ( ) . Entries . empty ( ) )
{
CDBGroupComboBox * cb = _Forms . back ( ) . Entries . back ( ) . ComboBox ;
if ( cb )
{
cb - > setSelectionNoTrigger ( _Forms . back ( ) . Entries . back ( ) . InitialSelection ) ;
cb - > setW ( cb - > evalContentWidth ( ) + 16 ) ;
}
}
}
}
break ;
case HTML_OPTION :
{
// insert the parsed text into the select control
CDBGroupComboBox * cb = _Forms . back ( ) . Entries . back ( ) . ComboBox ;
if ( cb )
{
cb - > addText ( _SelectOptionStr ) ;
}
}
break ;
case HTML_I :
{
_Localize = false ;
}
break ;
2015-12-18 12:29:40 +00:00
case HTML_OL :
if ( ! _OL . empty ( ) )
{
_Indent - = ULIndent ;
_Indent = std : : max ( _Indent , ( uint ) 0 ) ;
endParagraph ( ) ;
popIfNotEmpty ( _OL ) ;
}
break ;
2015-12-13 19:23:08 +00:00
case HTML_UL :
if ( getUL ( ) )
{
_Indent - = ULIndent ;
_Indent = std : : max ( _Indent , ( uint ) 0 ) ;
endParagraph ( ) ;
popIfNotEmpty ( _UL ) ;
}
break ;
case HTML_DL :
if ( getDL ( ) )
{
endParagraph ( ) ;
popIfNotEmpty ( _DL ) ;
if ( _DT ) {
_DT = false ;
popIfNotEmpty ( _FontWeight ) ;
}
}
break ;
case HTML_DT :
if ( getDL ( ) )
{
if ( _DT )
{
_DT = false ;
popIfNotEmpty ( _FontWeight ) ;
}
}
break ;
case HTML_DD :
// style not changed
break ;
case HTML_SPAN :
popIfNotEmpty ( _FontSize ) ;
popIfNotEmpty ( _FontWeight ) ;
popIfNotEmpty ( _FontOblique ) ;
popIfNotEmpty ( _TextColor ) ;
popIfNotEmpty ( _FontUnderlined ) ;
popIfNotEmpty ( _FontStrikeThrough ) ;
break ;
case HTML_DEL :
popIfNotEmpty ( _FontStrikeThrough ) ;
break ;
case HTML_U :
popIfNotEmpty ( _FontUnderlined ) ;
break ;
case HTML_EM :
popIfNotEmpty ( _FontOblique ) ;
break ;
case HTML_STRONG :
popIfNotEmpty ( _FontWeight ) ;
break ;
case HTML_SMALL :
popIfNotEmpty ( _FontSize ) ;
break ;
case HTML_STYLE :
case HTML_SCRIPT :
_IgnoreText = false ;
break ;
case HTML_OBJECT :
if ( _TrustedDomain )
{
if ( _ObjectType = = " application/ryzom-data " )
{
if ( ! _ObjectData . empty ( ) )
{
if ( addBnpDownload ( _ObjectData , _ObjectAction , _ObjectScript , _ObjectMD5Sum ) )
{
CLuaManager : : getInstance ( ) . executeLuaScript ( " \n local __ALLREADYDL__=true \n " + _ObjectScript , true ) ;
}
_ObjectScript = " " ;
}
}
_Object = false ;
}
break ;
}
}
}
// ***************************************************************************
void CGroupHTML : : beginUnparsedElement ( const char * buffer , int length )
{
string str ( buffer , buffer + length ) ;
if ( stricmp ( str . c_str ( ) , " lua " ) = = 0 )
{
// we receive an embeded lua script
_ParsingLua = _TrustedDomain ; // Only parse lua if TrustedDomain
_LuaScript = " " ;
}
}
// ***************************************************************************
void CGroupHTML : : endUnparsedElement ( const char * buffer , int length )
{
string str ( buffer , buffer + length ) ;
if ( stricmp ( str . c_str ( ) , " lua " ) = = 0 )
{
if ( _ParsingLua & & _TrustedDomain )
{
_ParsingLua = false ;
// execute the embeded lua script
_LuaScript = " \n local __CURRENT_WINDOW__= \" " + this - > _Id + " \" \n " + _LuaScript ;
CLuaManager : : getInstance ( ) . executeLuaScript ( _LuaScript , true ) ;
}
}
}
// ***************************************************************************
NLMISC_REGISTER_OBJECT ( CViewBase , CGroupHTML , std : : string , " html " ) ;
// ***************************************************************************
uint32 CGroupHTML : : _GroupHtmlUIDPool = 0 ;
CGroupHTML : : TGroupHtmlByUIDMap CGroupHTML : : _GroupHtmlByUID ;
// ***************************************************************************
CGroupHTML : : CGroupHTML ( const TCtorParam & param )
: CGroupScrollText ( param ) ,
_TimeoutValue ( DEFAULT_RYZOM_CONNECTION_TIMEOUT ) ,
_RedirectsRemaining ( DEFAULT_RYZOM_REDIRECT_LIMIT )
{
// add it to map of group html created
_GroupHtmlUID = + + _GroupHtmlUIDPool ; // valid assigned Id begin to 1!
_GroupHtmlByUID [ _GroupHtmlUID ] = this ;
// init
_TrustedDomain = false ;
_ParsingLua = false ;
_LuaHrefHack = false ;
_IgnoreText = false ;
_BrowseNextTime = false ;
_PostNextTime = false ;
_Browsing = false ;
_Connecting = false ;
_CurrentViewLink = NULL ;
_CurrentViewImage = NULL ;
_Indent = 0 ;
_LI = false ;
_DT = false ;
_SelectOption = false ;
_GroupListAdaptor = NULL ;
_UrlFragment . clear ( ) ;
// Register
CWidgetManager : : getInstance ( ) - > registerClockMsgTarget ( this ) ;
// HTML parameters
BgColor = CRGBA : : Black ;
ErrorColor = CRGBA ( 255 , 0 , 0 ) ;
LinkColor = CRGBA ( 0 , 0 , 255 ) ;
TextColor = CRGBA ( 255 , 255 , 255 ) ;
H1Color = CRGBA ( 255 , 255 , 255 ) ;
H2Color = CRGBA ( 255 , 255 , 255 ) ;
H3Color = CRGBA ( 255 , 255 , 255 ) ;
H4Color = CRGBA ( 255 , 255 , 255 ) ;
H5Color = CRGBA ( 255 , 255 , 255 ) ;
H6Color = CRGBA ( 255 , 255 , 255 ) ;
ErrorColorGlobalColor = false ;
LinkColorGlobalColor = false ;
TextColorGlobalColor = false ;
H1ColorGlobalColor = false ;
H2ColorGlobalColor = false ;
H3ColorGlobalColor = false ;
H4ColorGlobalColor = false ;
H5ColorGlobalColor = false ;
H6ColorGlobalColor = false ;
TextFontSize = 9 ;
H1FontSize = 18 ;
H2FontSize = 15 ;
H3FontSize = 12 ;
H4FontSize = 9 ;
H5FontSize = 9 ;
H6FontSize = 9 ;
LIBeginSpace = 4 ;
ULBeginSpace = 12 ;
PBeginSpace = 12 ;
TDBeginSpace = 0 ;
LIIndent = - 10 ;
ULIndent = 30 ;
LineSpaceFontFactor = 0.5f ;
DefaultButtonGroup = " html_text_button " ;
DefaultFormTextGroup = " edit_box_widget " ;
DefaultFormTextAreaGroup = " edit_box_widget_multiline " ;
DefaultFormSelectGroup = " html_form_select_widget " ;
DefaultCheckBoxBitmapNormal = " checkbox_normal.tga " ;
DefaultCheckBoxBitmapPushed = " checkbox_pushed.tga " ;
DefaultCheckBoxBitmapOver = " checkbox_over.tga " ;
DefaultRadioButtonBitmapNormal = " w_radiobutton.png " ;
DefaultRadioButtonBitmapPushed = " w_radiobutton_pushed.png " ;
DefaultRadioButtonBitmapOver = " " ;
DefaultBackgroundBitmapView = " bg " ;
clearContext ( ) ;
MultiCurl = curl_multi_init ( ) ;
# ifdef CURLMOPT_MAX_HOST_CONNECTIONS
if ( MultiCurl )
{
// added in libcurl 7.30.0
curl_multi_setopt ( MultiCurl , CURLMOPT_MAX_HOST_CONNECTIONS , options . curlMaxConnections ) ;
curl_multi_setopt ( MultiCurl , CURLMOPT_PIPELINING , 1 ) ;
}
# endif
RunningCurls = 0 ;
_CurlWWW = NULL ;
initImageDownload ( ) ;
initBnpDownload ( ) ;
initLibWWW ( ) ;
}
// ***************************************************************************
CGroupHTML : : ~ CGroupHTML ( )
{
//releaseImageDownload();
// TestYoyo
//nlinfo("** CGroupHTML Destroy: %x, %s, uid%d", this, _Id.c_str(), _GroupHtmlUID);
/* Erase from map of Group HTML (thus requestTerminated() callback won't be called)
Do it first , just because don ' t want requestTerminated ( ) to be called while I ' m destroying
( useless and may be dangerous )
*/
_GroupHtmlByUID . erase ( _GroupHtmlUID ) ;
// stop browsing
stopBrowse ( ) ; // NB : we don't call updateRefreshButton here, because :
// 1) it is useless,
// 2) it crashed before when it called getElementFromId (that didn't work when a master group was being removed...). Btw it should work now
// this is why the call to 'updateRefreshButton' has been removed from stopBrowse
clearContext ( ) ;
if ( _CurlWWW )
delete _CurlWWW ;
}
std : : string CGroupHTML : : getProperty ( const std : : string & name ) const
{
if ( name = = " url " )
{
return _URL ;
}
else
if ( name = = " title_prefix " )
{
return _TitlePrefix . toString ( ) ;
}
else
if ( name = = " background_color " )
{
return toString ( BgColor ) ;
}
else
if ( name = = " error_color " )
{
return toString ( ErrorColor ) ;
}
else
if ( name = = " link_color " )
{
return toString ( LinkColor ) ;
}
else
if ( name = = " h1_color " )
{
return toString ( H1Color ) ;
}
else
if ( name = = " h2_color " )
{
return toString ( H2Color ) ;
}
else
if ( name = = " h3_color " )
{
return toString ( H3Color ) ;
}
else
if ( name = = " h4_color " )
{
return toString ( H4Color ) ;
}
else
if ( name = = " h5_color " )
{
return toString ( H5Color ) ;
}
else
if ( name = = " h6_color " )
{
return toString ( H6Color ) ;
}
else
if ( name = = " error_color_global_color " )
{
return toString ( ErrorColorGlobalColor ) ;
}
else
if ( name = = " link_color_global_color " )
{
return toString ( LinkColorGlobalColor ) ;
}
else
if ( name = = " text_color_global_color " )
{
return toString ( TextColorGlobalColor ) ;
}
else
if ( name = = " h1_color_global_color " )
{
return toString ( H1ColorGlobalColor ) ;
}
else
if ( name = = " h2_color_global_color " )
{
return toString ( H2ColorGlobalColor ) ;
}
else
if ( name = = " h3_color_global_color " )
{
return toString ( H3ColorGlobalColor ) ;
}
else
if ( name = = " h4_color_global_color " )
{
return toString ( H4ColorGlobalColor ) ;
}
else
if ( name = = " h5_color_global_color " )
{
return toString ( H5ColorGlobalColor ) ;
}
else
if ( name = = " h6_color_global_color " )
{
return toString ( H6ColorGlobalColor ) ;
}
else
if ( name = = " text_font_size " )
{
return toString ( TextFontSize ) ;
}
else
if ( name = = " h1_font_size " )
{
return toString ( H1FontSize ) ;
}
else
if ( name = = " h2_font_size " )
{
return toString ( H2FontSize ) ;
}
else
if ( name = = " h3_font_size " )
{
return toString ( H3FontSize ) ;
}
else
if ( name = = " h4_font_size " )
{
return toString ( H4FontSize ) ;
}
else
if ( name = = " h5_font_size " )
{
return toString ( H5FontSize ) ;
}
else
if ( name = = " h6_font_size " )
{
return toString ( H6FontSize ) ;
}
else
if ( name = = " td_begin_space " )
{
return toString ( TDBeginSpace ) ;
}
else
if ( name = = " paragraph_begin_space " )
{
return toString ( PBeginSpace ) ;
}
else
if ( name = = " li_begin_space " )
{
return toString ( LIBeginSpace ) ;
}
else
if ( name = = " ul_begin_space " )
{
return toString ( ULBeginSpace ) ;
}
else
if ( name = = " li_indent " )
{
return toString ( LIIndent ) ;
}
else
if ( name = = " ul_indent " )
{
return toString ( ULIndent ) ;
}
else
if ( name = = " multi_line_space_factor " )
{
return toString ( LineSpaceFontFactor ) ;
}
else
if ( name = = " form_text_area_group " )
{
return DefaultFormTextGroup ;
}
else
if ( name = = " form_select_group " )
{
return DefaultFormSelectGroup ;
}
else
if ( name = = " checkbox_bitmap_normal " )
{
return DefaultCheckBoxBitmapNormal ;
}
else
if ( name = = " checkbox_bitmap_pushed " )
{
return DefaultCheckBoxBitmapPushed ;
}
else
if ( name = = " checkbox_bitmap_over " )
{
return DefaultCheckBoxBitmapOver ;
}
else
if ( name = = " radiobutton_bitmap_normal " )
{
return DefaultRadioButtonBitmapNormal ;
}
else
if ( name = = " radiobutton_bitmap_pushed " )
{
return DefaultRadioButtonBitmapPushed ;
}
else
if ( name = = " radiobutton_bitmap_over " )
{
return DefaultRadioButtonBitmapOver ;
}
else
if ( name = = " background_bitmap_view " )
{
return DefaultBackgroundBitmapView ;
}
else
if ( name = = " home " )
{
return Home ;
}
else
if ( name = = " browse_next_time " )
{
return toString ( _BrowseNextTime ) ;
}
else
if ( name = = " browse_tree " )
{
return _BrowseTree ;
}
else
if ( name = = " browse_undo " )
{
return _BrowseUndoButton ;
}
else
if ( name = = " browse_redo " )
{
return _BrowseRedoButton ;
}
else
if ( name = = " browse_refresh " )
{
return _BrowseRefreshButton ;
}
else
if ( name = = " timeout " )
{
return toString ( _TimeoutValue ) ;
}
else
return CGroupScrollText : : getProperty ( name ) ;
}
void CGroupHTML : : setProperty ( const std : : string & name , const std : : string & value )
{
if ( name = = " url " )
{
_URL = value ;
return ;
}
else
if ( name = = " title_prefix " )
{
_TitlePrefix = value ;
return ;
}
else
if ( name = = " background_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
BgColor = c ;
return ;
}
else
if ( name = = " error_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
ErrorColor = c ;
return ;
}
else
if ( name = = " link_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
LinkColor = c ;
return ;
}
else
if ( name = = " h1_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
H1Color = c ;
return ;
}
else
if ( name = = " h2_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
H2Color = c ;
return ;
}
else
if ( name = = " h3_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
H3Color = c ;
return ;
}
else
if ( name = = " h4_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
H4Color = c ;
return ;
}
else
if ( name = = " h5_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
H5Color = c ;
return ;
}
else
if ( name = = " h6_color " )
{
CRGBA c ;
if ( fromString ( value , c ) )
H6Color = c ;
return ;
}
else
if ( name = = " error_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
ErrorColorGlobalColor = b ;
return ;
}
else
if ( name = = " link_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
LinkColorGlobalColor = b ;
return ;
}
else
if ( name = = " text_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
TextColorGlobalColor = b ;
return ;
}
else
if ( name = = " h1_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
H1ColorGlobalColor = b ;
return ;
}
else
if ( name = = " h2_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
H2ColorGlobalColor = b ;
return ;
}
else
if ( name = = " h3_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
H3ColorGlobalColor = b ;
return ;
}
else
if ( name = = " h4_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
H4ColorGlobalColor = b ;
return ;
}
else
if ( name = = " h5_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
H5ColorGlobalColor = b ;
return ;
}
else
if ( name = = " h6_color_global_color " )
{
bool b ;
if ( fromString ( value , b ) )
H6ColorGlobalColor = b ;
return ;
}
else
if ( name = = " text_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
TextFontSize = i ;
return ;
}
else
if ( name = = " h1_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
H1FontSize = i ;
return ;
}
else
if ( name = = " h2_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
H2FontSize = i ;
return ;
}
else
if ( name = = " h3_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
H3FontSize = i ;
return ;
}
else
if ( name = = " h4_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
H4FontSize = i ;
return ;
}
else
if ( name = = " h5_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
H5FontSize = i ;
return ;
}
else
if ( name = = " h6_font_size " )
{
uint i ;
if ( fromString ( value , i ) )
H6FontSize = i ;
return ;
}
else
if ( name = = " td_begin_space " )
{
uint i ;
if ( fromString ( value , i ) )
TDBeginSpace = i ;
return ;
}
else
if ( name = = " paragraph_begin_space " )
{
uint i ;
if ( fromString ( value , i ) )
PBeginSpace = i ;
return ;
}
else
if ( name = = " li_begin_space " )
{
uint i ;
if ( fromString ( value , i ) )
LIBeginSpace = i ;
return ;
}
else
if ( name = = " ul_begin_space " )
{
uint i ;
if ( fromString ( value , i ) )
ULBeginSpace = i ;
return ;
}
else
if ( name = = " li_indent " )
{
uint i ;
if ( fromString ( value , i ) )
LIIndent = i ;
return ;
}
else
if ( name = = " ul_indent " )
{
uint i ;
if ( fromString ( value , i ) )
ULIndent = i ;
return ;
}
else
if ( name = = " multi_line_space_factor " )
{
float f ;
if ( fromString ( value , f ) )
LineSpaceFontFactor = f ;
return ;
}
else
if ( name = = " form_text_area_group " )
{
DefaultFormTextGroup = value ;
return ;
}
else
if ( name = = " form_select_group " )
{
DefaultFormSelectGroup = value ;
return ;
}
else
if ( name = = " checkbox_bitmap_normal " )
{
DefaultCheckBoxBitmapNormal = value ;
return ;
}
else
if ( name = = " checkbox_bitmap_pushed " )
{
DefaultCheckBoxBitmapPushed = value ;
return ;
}
else
if ( name = = " checkbox_bitmap_over " )
{
DefaultCheckBoxBitmapOver = value ;
return ;
}
else
if ( name = = " radiobutton_bitmap_normal " )
{
DefaultRadioButtonBitmapNormal = value ;
return ;
}
else
if ( name = = " radiobutton_bitmap_pushed " )
{
DefaultRadioButtonBitmapPushed = value ;
return ;
}
else
if ( name = = " radiobutton_bitmap_over " )
{
DefaultRadioButtonBitmapOver = value ;
return ;
}
else
if ( name = = " background_bitmap_view " )
{
DefaultBackgroundBitmapView = value ;
return ;
}
else
if ( name = = " home " )
{
Home = value ;
return ;
}
else
if ( name = = " browse_next_time " )
{
bool b ;
if ( fromString ( value , b ) )
_BrowseNextTime = b ;
return ;
}
else
if ( name = = " browse_tree " )
{
_BrowseTree = value ;
return ;
}
else
if ( name = = " browse_undo " )
{
_BrowseUndoButton = value ;
return ;
}
else
if ( name = = " browse_redo " )
{
_BrowseRedoButton = value ;
return ;
}
else
if ( name = = " browse_refresh " )
{
_BrowseRefreshButton = value ;
return ;
}
else
if ( name = = " timeout " )
{
double d ;
if ( fromString ( value , d ) )
_TimeoutValue = d ;
return ;
}
else
CGroupScrollText : : setProperty ( name , value ) ;
}
xmlNodePtr CGroupHTML : : serialize ( xmlNodePtr parentNode , const char * type ) const
{
xmlNodePtr node = CGroupScrollText : : serialize ( parentNode , type ) ;
if ( node = = NULL )
return NULL ;
xmlSetProp ( node , BAD_CAST " type " , BAD_CAST " html " ) ;
xmlSetProp ( node , BAD_CAST " url " , BAD_CAST _URL . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " title_prefix " , BAD_CAST _TitlePrefix . toString ( ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " background_color " , BAD_CAST toString ( BgColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " error_color " , BAD_CAST toString ( ErrorColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " link_color " , BAD_CAST toString ( LinkColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " background_color " , BAD_CAST toString ( BgColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h1_color " , BAD_CAST toString ( H1Color ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h2_color " , BAD_CAST toString ( H2Color ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h3_color " , BAD_CAST toString ( H3Color ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h4_color " , BAD_CAST toString ( H4Color ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h5_color " , BAD_CAST toString ( H5Color ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h6_color " , BAD_CAST toString ( H6Color ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " error_color_global_color " ,
BAD_CAST toString ( ErrorColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " link_color_global_color " ,
BAD_CAST toString ( LinkColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " text_color_global_color " ,
BAD_CAST toString ( TextColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h1_color_global_color " ,
BAD_CAST toString ( H1ColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h2_color_global_color " ,
BAD_CAST toString ( H2ColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h3_color_global_color " ,
BAD_CAST toString ( H3ColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h4_color_global_color " ,
BAD_CAST toString ( H4ColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h5_color_global_color " ,
BAD_CAST toString ( H5ColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h6_color_global_color " ,
BAD_CAST toString ( H6ColorGlobalColor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " text_font_size " , BAD_CAST toString ( TextFontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h1_font_size " , BAD_CAST toString ( H1FontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h2_font_size " , BAD_CAST toString ( H2FontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h3_font_size " , BAD_CAST toString ( H3FontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h4_font_size " , BAD_CAST toString ( H4FontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h5_font_size " , BAD_CAST toString ( H5FontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " h6_font_size " , BAD_CAST toString ( H6FontSize ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " td_begin_space " , BAD_CAST toString ( TDBeginSpace ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " paragraph_begin_space " , BAD_CAST toString ( PBeginSpace ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " li_begin_space " , BAD_CAST toString ( LIBeginSpace ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " ul_begin_space " , BAD_CAST toString ( ULBeginSpace ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " li_indent " , BAD_CAST toString ( LIIndent ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " ul_indent " , BAD_CAST toString ( ULIndent ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " multi_line_space_factor " , BAD_CAST toString ( LineSpaceFontFactor ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " form_text_area_group " , BAD_CAST DefaultFormTextGroup . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " form_select_group " , BAD_CAST DefaultFormSelectGroup . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " checkbox_bitmap_normal " , BAD_CAST DefaultCheckBoxBitmapNormal . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " checkbox_bitmap_pushed " , BAD_CAST DefaultCheckBoxBitmapPushed . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " checkbox_bitmap_over " , BAD_CAST DefaultCheckBoxBitmapOver . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " radiobutton_bitmap_normal " , BAD_CAST DefaultRadioButtonBitmapNormal . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " radiobutton_bitmap_pushed " , BAD_CAST DefaultRadioButtonBitmapPushed . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " radiobutton_bitmap_over " , BAD_CAST DefaultRadioButtonBitmapOver . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " background_bitmap_view " , BAD_CAST DefaultBackgroundBitmapView . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " home " , BAD_CAST Home . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " browse_next_time " , BAD_CAST toString ( _BrowseNextTime ) . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " browse_tree " , BAD_CAST _BrowseTree . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " browse_undo " , BAD_CAST _BrowseUndoButton . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " browse_redo " , BAD_CAST _BrowseRedoButton . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " browse_refresh " , BAD_CAST _BrowseRefreshButton . c_str ( ) ) ;
xmlSetProp ( node , BAD_CAST " timeout " , BAD_CAST toString ( _TimeoutValue ) . c_str ( ) ) ;
return node ;
}
// ***************************************************************************
bool CGroupHTML : : parse ( xmlNodePtr cur , CInterfaceGroup * parentGroup )
{
nlassert ( CWidgetManager : : getInstance ( ) - > isClockMsgTarget ( this ) ) ;
if ( ! CGroupScrollText : : parse ( cur , parentGroup ) )
return false ;
// TestYoyo
//nlinfo("** CGroupHTML parsed Ok: %x, %s, %s, uid%d", this, _Id.c_str(), typeid(this).name(), _GroupHtmlUID);
CXMLAutoPtr ptr ;
// Get the url
ptr = xmlGetProp ( cur , ( xmlChar * ) " url " ) ;
if ( ptr )
_URL = ( const char * ) ptr ;
// Bkup default for undo/redo
_AskedUrl = _URL ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " title_prefix " ) ;
if ( ptr )
_TitlePrefix = CI18N : : get ( ( const char * ) ptr ) ;
// Parameters
ptr = xmlGetProp ( cur , ( xmlChar * ) " background_color " ) ;
if ( ptr )
BgColor = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " error_color " ) ;
if ( ptr )
ErrorColor = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " link_color " ) ;
if ( ptr )
LinkColor = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " text_color " ) ;
if ( ptr )
TextColor = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h1_color " ) ;
if ( ptr )
H1Color = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h2_color " ) ;
if ( ptr )
H2Color = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h3_color " ) ;
if ( ptr )
H3Color = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h4_color " ) ;
if ( ptr )
H4Color = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h5_color " ) ;
if ( ptr )
H5Color = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h6_color " ) ;
if ( ptr )
H6Color = convertColor ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " error_color_global_color " ) ;
if ( ptr )
ErrorColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " link_color_global_color " ) ;
if ( ptr )
LinkColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " text_color_global_color " ) ;
if ( ptr )
TextColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h1_color_global_color " ) ;
if ( ptr )
H1ColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h2_color_global_color " ) ;
if ( ptr )
H2ColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h3_color_global_color " ) ;
if ( ptr )
H3ColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h4_color_global_color " ) ;
if ( ptr )
H4ColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h5_color_global_color " ) ;
if ( ptr )
H5ColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h6_color_global_color " ) ;
if ( ptr )
H6ColorGlobalColor = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " text_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , TextFontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h1_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , H1FontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h2_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , H2FontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h3_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , H3FontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h4_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , H4FontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h5_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , H5FontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " h6_font_size " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , H6FontSize ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " td_begin_space " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , TDBeginSpace ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " paragraph_begin_space " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , PBeginSpace ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " li_begin_space " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , LIBeginSpace ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " ul_begin_space " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , ULBeginSpace ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " li_indent " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , LIIndent ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " ul_indent " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , ULIndent ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " multi_line_space_factor " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , LineSpaceFontFactor ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " form_text_group " ) ;
if ( ptr )
DefaultFormTextGroup = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " form_text_area_group " ) ;
if ( ptr )
DefaultFormTextAreaGroup = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " form_select_group " ) ;
if ( ptr )
DefaultFormSelectGroup = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " checkbox_bitmap_normal " ) ;
if ( ptr )
DefaultCheckBoxBitmapNormal = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " checkbox_bitmap_pushed " ) ;
if ( ptr )
DefaultCheckBoxBitmapPushed = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " checkbox_bitmap_over " ) ;
if ( ptr )
DefaultCheckBoxBitmapOver = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " radiobutton_bitmap_normal " ) ;
if ( ptr )
DefaultRadioButtonBitmapNormal = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " radiobutton_bitmap_pushed " ) ;
if ( ptr )
DefaultRadioButtonBitmapPushed = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " radiobutton_bitmap_over " ) ;
if ( ptr )
DefaultRadioButtonBitmapOver = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " background_bitmap_view " ) ;
if ( ptr )
DefaultBackgroundBitmapView = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " home " ) ;
if ( ptr )
Home = ( const char * ) ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " browse_next_time " ) ;
if ( ptr )
_BrowseNextTime = convertBool ( ptr ) ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " browse_tree " ) ;
if ( ptr )
_BrowseTree = ( const char * ) ptr ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " browse_undo " ) ;
if ( ptr )
_BrowseUndoButton = ( const char * ) ptr ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " browse_redo " ) ;
if ( ptr )
_BrowseRedoButton = ( const char * ) ptr ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " browse_refresh " ) ;
if ( ptr )
_BrowseRefreshButton = ( const char * ) ptr ;
ptr = xmlGetProp ( cur , ( xmlChar * ) " timeout " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , _TimeoutValue ) ;
return true ;
}
// ***************************************************************************
bool CGroupHTML : : handleEvent ( const NLGUI : : CEventDescriptor & eventDesc )
{
bool traited = CGroupScrollText : : handleEvent ( eventDesc ) ;
if ( eventDesc . getType ( ) = = NLGUI : : CEventDescriptor : : system )
{
const NLGUI : : CEventDescriptorSystem & systemEvent = ( const NLGUI : : CEventDescriptorSystem & ) eventDesc ;
if ( systemEvent . getEventTypeExtended ( ) = = NLGUI : : CEventDescriptorSystem : : clocktick )
{
// Handle now
handle ( ) ;
}
}
return traited ;
}
// ***************************************************************************
void CGroupHTML : : endParagraph ( )
{
// Remove previous paragraph if empty
if ( _Paragraph & & ( _Paragraph - > getNumChildren ( ) = = 0 ) )
{
_Paragraph - > getParent ( ) - > delGroup ( _Paragraph ) ;
_Paragraph = NULL ;
}
_Paragraph = NULL ;
paragraphChange ( ) ;
}
// ***************************************************************************
void CGroupHTML : : newParagraph ( uint beginSpace )
{
// Remove previous paragraph if empty
if ( _Paragraph & & ( _Paragraph - > getNumChildren ( ) = = 0 ) )
{
_Paragraph - > getParent ( ) - > delGroup ( _Paragraph ) ;
_Paragraph = NULL ;
}
// Add a new paragraph
CGroupParagraph * newParagraph = new CGroupParagraph ( CViewBase : : TCtorParam ( ) ) ;
newParagraph - > setResizeFromChildH ( true ) ;
newParagraph - > setBrowseGroup ( this ) ;
newParagraph - > setIndent ( _Indent ) ;
// Add to the group
addGroup ( newParagraph , beginSpace ) ;
_Paragraph = newParagraph ;
paragraphChange ( ) ;
}
// ***************************************************************************
void CGroupHTML : : browse ( const char * url )
{
// modify undo/redo
pushUrlUndoRedo ( url ) ;
// do the browse, with no undo/redo
doBrowse ( url ) ;
}
// ***************************************************************************
void CGroupHTML : : refresh ( )
{
if ( ! _URL . empty ( ) )
doBrowse ( _URL . c_str ( ) , true ) ;
}
// ***************************************************************************
void CGroupHTML : : doBrowse ( const char * url , bool force )
{
// Stop previous browse
if ( _Browsing )
{
// Clear all the context
clearContext ( ) ;
_Browsing = false ;
updateRefreshButton ( ) ;
# ifdef LOG_DL
nlwarning ( " (%s) *** ALREADY BROWSING, break first " , _Id . c_str ( ) ) ;
# endif
}
# ifdef LOG_DL
nlwarning ( " (%s) Browsing URL : '%s' " , _Id . c_str ( ) , url ) ;
# endif
CUrlParser uri ( url ) ;
if ( uri . hash . size ( ) > 0 )
{
// Anchor to scroll after page has loaded
_UrlFragment = uri . hash ;
uri . inherit ( _URL ) ;
uri . hash . clear ( ) ;
// compare urls and see if we only navigating to new anchor
if ( ! force & & _URL = = uri . toString ( ) )
{
// scroll happens in updateCoords()
invalidateCoords ( ) ;
return ;
}
}
else
_UrlFragment . clear ( ) ;
// go
_URL = uri . toString ( ) ;
_Connecting = false ;
_BrowseNextTime = true ;
// if a BrowseTree is bound to us, try to select the node that opens this URL (auto-locate)
if ( ! _BrowseTree . empty ( ) )
{
CGroupTree * groupTree = dynamic_cast < CGroupTree * > ( CWidgetManager : : getInstance ( ) - > getElementFromId ( _BrowseTree ) ) ;
if ( groupTree )
{
string nodeId = selectTreeNodeRecurs ( groupTree - > getRootNode ( ) , url ) ;
// select the node
if ( ! nodeId . empty ( ) )
{
groupTree - > selectNodeById ( nodeId ) ;
}
}
}
}
// ***************************************************************************
void CGroupHTML : : browseError ( const char * msg )
{
// Get the list group from CGroupScrollText
removeContent ( ) ;
newParagraph ( 0 ) ;
CViewText * viewText = new CViewText ( " " , ( string ( " Error : " ) + msg ) . c_str ( ) ) ;
viewText - > setColor ( ErrorColor ) ;
viewText - > setModulateGlobalColor ( ErrorColorGlobalColor ) ;
getParagraph ( ) - > addChild ( viewText ) ;
if ( ! _TitlePrefix . empty ( ) )
setTitle ( _TitlePrefix ) ;
stopBrowse ( ) ;
updateRefreshButton ( ) ;
}
// ***************************************************************************
bool CGroupHTML : : isBrowsing ( )
{
return _Browsing ;
}
void CGroupHTML : : stopBrowse ( )
{
# ifdef LOG_DL
nlwarning ( " *** STOP BROWSE (%s) " , _Id . c_str ( ) ) ;
# endif
// Clear all the context
clearContext ( ) ;
_Browsing = false ;
requestTerminated ( ) ;
}
// ***************************************************************************
void CGroupHTML : : updateCoords ( )
{
CGroupScrollText : : updateCoords ( ) ;
// all elements are in their correct place, tell scrollbar to scroll to anchor
if ( ! _Browsing & & ! _UrlFragment . empty ( ) )
{
doBrowseAnchor ( _UrlFragment ) ;
_UrlFragment . clear ( ) ;
}
}
// ***************************************************************************
bool CGroupHTML : : translateChar ( ucchar & output , ucchar input , ucchar lastCharParam ) const
{
// Keep this char ?
bool keep = true ;
switch ( input )
{
// Return / tab only in <PRE> mode
case ' \t ' :
case ' \n ' :
{
// Get the last char
ucchar lastChar = lastCharParam ;
if ( lastChar = = 0 )
lastChar = getLastChar ( ) ;
keep = ( ( lastChar ! = ( ucchar ) ' ' ) & &
( lastChar ! = 0 ) ) | | getPRE ( ) | | ( _CurrentViewImage & & ( lastChar = = 0 ) ) ;
if ( ! getPRE ( ) )
input = ' ' ;
}
break ;
case ' ' :
{
// Get the last char
ucchar lastChar = lastCharParam ;
if ( lastChar = = 0 )
lastChar = getLastChar ( ) ;
keep = ( ( lastChar ! = ( ucchar ) ' ' ) & &
( lastChar ! = ( ucchar ) ' \n ' ) & &
( lastChar ! = 0 ) ) | | getPRE ( ) | | ( _CurrentViewImage & & ( lastChar = = 0 ) ) ;
}
break ;
case 0xd :
keep = false ;
break ;
}
if ( keep )
{
output = input ;
}
return keep ;
}
// ***************************************************************************
void CGroupHTML : : registerAnchor ( CInterfaceElement * elm )
{
if ( _AnchorName . size ( ) > 0 )
{
for ( uint32 i = 0 ; i < _AnchorName . size ( ) ; + + i )
{
// filter out duplicates and register only first
if ( ! _AnchorName [ i ] . empty ( ) & & _Anchors . count ( _AnchorName [ i ] ) = = 0 )
{
_Anchors [ _AnchorName [ i ] ] = elm ;
}
}
_AnchorName . clear ( ) ;
}
}
// ***************************************************************************
void CGroupHTML : : addString ( const ucstring & str )
{
ucstring tmpStr = str ;
if ( _Localize )
{
string _str = tmpStr . toString ( ) ;
string : : size_type p = _str . find ( ' # ' ) ;
if ( p = = string : : npos )
{
tmpStr = CI18N : : get ( _str ) ;
}
else
{
string cmd = _str . substr ( 0 , p ) ;
string arg = _str . substr ( p + 1 ) ;
if ( cmd = = " date " )
{
uint year , month , day ;
sscanf ( arg . c_str ( ) , " %d/%d/%d " , & year , & month , & day ) ;
tmpStr = CI18N : : get ( " uiMFIDate " ) ;
year + = ( year > 70 ? 1900 : 2000 ) ;
strFindReplace ( tmpStr , " %year " , toString ( " %d " , year ) ) ;
strFindReplace ( tmpStr , " %month " , CI18N : : get ( toString ( " uiMonth%02d " , month ) ) ) ;
strFindReplace ( tmpStr , " %day " , toString ( " %d " , day ) ) ;
}
else
{
tmpStr = arg ;
}
}
}
// In title ?
if ( _Title )
{
_TitleString + = tmpStr ;
}
else if ( _TextArea )
{
_TextAreaContent + = tmpStr ;
}
else if ( _Object )
{
_ObjectScript + = tmpStr . toString ( ) ;
}
else if ( _SelectOption )
{
if ( ! ( _Forms . empty ( ) ) )
{
if ( ! _Forms . back ( ) . Entries . empty ( ) )
{
_SelectOptionStr + = tmpStr ;
}
}
}
else
{
// In a paragraph ?
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
// Text added ?
bool added = false ;
bool embolden = getFontWeight ( ) > = FONT_WEIGHT_BOLD ;
// Number of child in this paragraph
if ( _CurrentViewLink )
{
bool skipLine = ! _CurrentViewLink - > getText ( ) . empty ( ) & & * ( _CurrentViewLink - > getText ( ) . rbegin ( ) ) = = ( ucchar ) ' \n ' ;
// Compatible with current parameters ?
if ( ! skipLine & &
( getTextColor ( ) = = _CurrentViewLink - > getColor ( ) ) & &
( getFontSize ( ) = = ( uint ) _CurrentViewLink - > getFontSize ( ) ) & &
( getFontUnderlined ( ) = = _CurrentViewLink - > getUnderlined ( ) ) & &
( getFontStrikeThrough ( ) = = _CurrentViewLink - > getStrikeThrough ( ) ) & &
( embolden = = _CurrentViewLink - > getEmbolden ( ) ) & &
( getFontOblique ( ) = = _CurrentViewLink - > getOblique ( ) ) & &
( getLink ( ) = = _CurrentViewLink - > Link ) & &
( getGlobalColor ( ) = = _CurrentViewLink - > getModulateGlobalColor ( ) ) )
{
// Concat the text
_CurrentViewLink - > setText ( _CurrentViewLink - > getText ( ) + tmpStr ) ;
_CurrentViewLink - > invalidateContent ( ) ;
added = true ;
}
}
// Not added ?
if ( ! added )
{
if ( getA ( ) & & string ( getLinkClass ( ) ) = = " ryzom-ui-button " )
{
string buttonTemplate = DefaultButtonGroup ;
// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
string param = " name= " + this - > _Id + " |url= " + getLink ( ) ;
typedef pair < string , string > TTmplParam ;
vector < TTmplParam > tmplParams ;
tmplParams . push_back ( TTmplParam ( " id " , " " ) ) ;
tmplParams . push_back ( TTmplParam ( " onclick " , " browse " ) ) ;
tmplParams . push_back ( TTmplParam ( " onclick_param " , param ) ) ;
tmplParams . push_back ( TTmplParam ( " active " , " true " ) ) ;
CInterfaceGroup * buttonGroup = CWidgetManager : : getInstance ( ) - > getParser ( ) - > createGroupInstance ( buttonTemplate , _Paragraph - > getId ( ) , tmplParams ) ;
if ( buttonGroup )
{
// Add the ctrl button
CCtrlTextButton * ctrlButton = dynamic_cast < CCtrlTextButton * > ( buttonGroup - > getCtrl ( " button " ) ) ;
if ( ! ctrlButton ) ctrlButton = dynamic_cast < CCtrlTextButton * > ( buttonGroup - > getCtrl ( " b " ) ) ;
if ( ctrlButton )
{
ctrlButton - > setModulateGlobalColorAll ( false ) ;
// Translate the tooltip
ctrlButton - > setDefaultContextHelp ( ucstring : : makeFromUtf8 ( getLinkTitle ( ) ) ) ;
ctrlButton - > setText ( tmpStr ) ;
}
getParagraph ( ) - > addChild ( buttonGroup ) ;
paragraphChange ( ) ;
}
}
else
{
CViewLink * newLink = new CViewLink ( CViewBase : : TCtorParam ( ) ) ;
if ( getA ( ) )
{
newLink - > Link = getLink ( ) ;
newLink - > LinkTitle = getLinkTitle ( ) ;
if ( ! newLink - > Link . empty ( ) )
{
newLink - > setHTMLView ( this ) ;
}
}
newLink - > setText ( tmpStr ) ;
newLink - > setColor ( getTextColor ( ) ) ;
newLink - > setFontSize ( getFontSize ( ) ) ;
newLink - > setEmbolden ( embolden ) ;
newLink - > setOblique ( getFontOblique ( ) ) ;
newLink - > setUnderlined ( getFontUnderlined ( ) ) ;
newLink - > setStrikeThrough ( getFontStrikeThrough ( ) ) ;
newLink - > setMultiLineSpace ( ( uint ) ( ( float ) getFontSize ( ) * LineSpaceFontFactor ) ) ;
newLink - > setMultiLine ( true ) ;
newLink - > setModulateGlobalColor ( getGlobalColor ( ) ) ;
// newLink->setLineAtBottom (true);
registerAnchor ( newLink ) ;
if ( getA ( ) & & ! newLink - > Link . empty ( ) )
{
getParagraph ( ) - > addChildLink ( newLink ) ;
}
else
{
getParagraph ( ) - > addChild ( newLink ) ;
}
paragraphChange ( ) ;
}
}
}
}
// ***************************************************************************
void CGroupHTML : : addImage ( const char * img , bool globalColor , bool reloadImg , const CStyleParams & style )
{
// In a paragraph ?
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
string finalUrl ;
// No more text in this text view
_CurrentViewLink = NULL ;
// Not added ?
CViewBitmap * newImage = new CViewBitmap ( TCtorParam ( ) ) ;
//
// 1/ try to load the image with the old system (local files in bnp)
//
string image = CFile : : getPath ( img ) + CFile : : getFilenameWithoutExtension ( img ) + " .tga " ;
if ( lookupLocalFile ( finalUrl , image . c_str ( ) , false ) )
{
newImage - > setRenderLayer ( getRenderLayer ( ) + 1 ) ;
image = finalUrl ;
}
else
{
//
// 2/ if it doesn't work, try to load the image in cache
//
image = localImageName ( img ) ;
if ( ! reloadImg & & lookupLocalFile ( finalUrl , image . c_str ( ) , false ) )
{
// don't display image that are not power of 2
uint32 w , h ;
CBitmap : : loadSize ( image , w , h ) ;
if ( w = = 0 | | h = = 0 | | ( ( ! NLMISC : : isPowerOf2 ( w ) | | ! NLMISC : : isPowerOf2 ( h ) ) & & ! NL3D : : CTextureFile : : supportNonPowerOfTwoTextures ( ) ) )
image . clear ( ) ;
}
else
{
//
// 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache
//
image = " web_del.tga " ;
addImageDownload ( img , newImage , style ) ;
}
}
newImage - > setTexture ( image ) ;
newImage - > setModulateGlobalColor ( globalColor ) ;
getParagraph ( ) - > addChild ( newImage ) ;
paragraphChange ( ) ;
setImageSize ( newImage , style ) ;
}
// ***************************************************************************
CInterfaceGroup * CGroupHTML : : addTextArea ( const std : : string & templateName , const char * name , uint /* rows */ , uint cols , bool multiLine , const ucstring & content , uint maxlength )
{
// In a paragraph ?
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
// No more text in this text view
_CurrentViewLink = NULL ;
{
// Not added ?
std : : vector < std : : pair < std : : string , std : : string > > templateParams ;
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " w " , toString ( cols * 12 ) ) ) ;
//templateParams.push_back (std::pair<std::string,std::string> ("h", toString (rows*12)));
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " id " , name ) ) ;
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " prompt " , " " ) ) ;
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " multiline " , multiLine ? " true " : " false " ) ) ;
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " want_return " , multiLine ? " true " : " false " ) ) ;
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " enter_recover_focus " , " false " ) ) ;
if ( maxlength > 0 )
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " max_num_chars " , toString ( maxlength ) ) ) ;
CInterfaceGroup * textArea = CWidgetManager : : getInstance ( ) - > getParser ( ) - > createGroupInstance ( templateName . c_str ( ) ,
getParagraph ( ) - > getId ( ) , templateParams . empty ( ) ? NULL : & ( templateParams [ 0 ] ) , ( uint ) templateParams . size ( ) ) ;
// Group created ?
if ( textArea )
{
// Set the content
CGroupEditBox * eb = dynamic_cast < CGroupEditBox * > ( textArea - > getGroup ( " eb " ) ) ;
if ( eb )
eb - > setInputString ( decodeHTMLEntities ( content ) ) ;
textArea - > invalidateCoords ( ) ;
getParagraph ( ) - > addChild ( textArea ) ;
paragraphChange ( ) ;
return textArea ;
}
}
// Not group created
return NULL ;
}
// ***************************************************************************
CDBGroupComboBox * CGroupHTML : : addComboBox ( const std : : string & templateName , const char * name )
{
// In a paragraph ?
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
{
// Not added ?
std : : vector < std : : pair < std : : string , std : : string > > templateParams ;
templateParams . push_back ( std : : pair < std : : string , std : : string > ( " id " , name ) ) ;
CInterfaceGroup * group = CWidgetManager : : getInstance ( ) - > getParser ( ) - > createGroupInstance ( templateName . c_str ( ) ,
getParagraph ( ) - > getId ( ) , templateParams . empty ( ) ? NULL : & ( templateParams [ 0 ] ) , ( uint ) templateParams . size ( ) ) ;
// Group created ?
if ( group )
{
// Set the content
CDBGroupComboBox * cb = dynamic_cast < CDBGroupComboBox * > ( group ) ;
if ( ! cb )
{
nlwarning ( " '%s' template has bad type, combo box expected " , templateName . c_str ( ) ) ;
delete cb ;
return NULL ;
}
else
{
getParagraph ( ) - > addChild ( cb ) ;
paragraphChange ( ) ;
return cb ;
}
}
}
// Not group created
return NULL ;
}
// ***************************************************************************
CCtrlButton * CGroupHTML : : addButton ( CCtrlButton : : EType type , const std : : string & /* name */ , const std : : string & normalBitmap , const std : : string & pushedBitmap ,
const std : : string & overBitmap , bool useGlobalColor , const char * actionHandler , const char * actionHandlerParams ,
const char * tooltip , const CStyleParams & style )
{
// In a paragraph ?
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
// Add the ctrl button
CCtrlButton * ctrlButton = new CCtrlButton ( TCtorParam ( ) ) ;
// Load only tga files.. (conversion in dds filename is done in the lookup procedure)
string normal = normalBitmap . empty ( ) ? " " : CFile : : getPath ( normalBitmap ) + CFile : : getFilenameWithoutExtension ( normalBitmap ) + " .tga " ;
// if the image doesn't exist on local, we check in the cache
// if(!CFile::fileExists(normal))
if ( ! CPath : : exists ( normal ) )
{
// search in the compressed texture
CViewRenderer & rVR = * CViewRenderer : : getInstance ( ) ;
sint32 id = rVR . getTextureIdFromName ( normal ) ;
if ( id = = - 1 )
{
normal = localImageName ( normalBitmap ) ;
if ( ! CFile : : fileExists ( normal ) )
{
normal = " web_del.tga " ;
addImageDownload ( normalBitmap , ctrlButton , style ) ;
}
}
}
string pushed = pushedBitmap . empty ( ) ? " " : CFile : : getPath ( pushedBitmap ) + CFile : : getFilenameWithoutExtension ( pushedBitmap ) + " .tga " ;
// if the image doesn't exist on local, we check in the cache, don't download it because the "normal" will already setuped it
// if(!CFile::fileExists(pushed))
if ( ! CPath : : exists ( pushed ) )
{
// search in the compressed texture
CViewRenderer & rVR = * CViewRenderer : : getInstance ( ) ;
sint32 id = rVR . getTextureIdFromName ( pushed ) ;
if ( id = = - 1 )
{
pushed = localImageName ( pushedBitmap ) ;
}
}
string over = overBitmap . empty ( ) ? " " : CFile : : getPath ( overBitmap ) + CFile : : getFilenameWithoutExtension ( overBitmap ) + " .tga " ;
ctrlButton - > setType ( type ) ;
if ( ! normal . empty ( ) )
ctrlButton - > setTexture ( normal ) ;
if ( ! pushed . empty ( ) )
ctrlButton - > setTexturePushed ( pushed ) ;
if ( ! over . empty ( ) )
ctrlButton - > setTextureOver ( over ) ;
ctrlButton - > setModulateGlobalColorAll ( useGlobalColor ) ;
ctrlButton - > setActionOnLeftClick ( actionHandler ) ;
ctrlButton - > setParamsOnLeftClick ( actionHandlerParams ) ;
// Translate the tooltip or display raw text (tooltip from webig)
if ( tooltip )
{
if ( CI18N : : hasTranslation ( tooltip ) )
{
ctrlButton - > setDefaultContextHelp ( CI18N : : get ( tooltip ) ) ;
//ctrlButton->setOnContextHelp(CI18N::get(tooltip).toString());
}
else
{
ctrlButton - > setDefaultContextHelp ( ucstring : : makeFromUtf8 ( tooltip ) ) ;
//ctrlButton->setOnContextHelp(string(tooltip));
}
ctrlButton - > setInstantContextHelp ( true ) ;
ctrlButton - > setToolTipParent ( TTMouse ) ;
ctrlButton - > setToolTipParentPosRef ( Hotspot_TTAuto ) ;
ctrlButton - > setToolTipPosRef ( Hotspot_TTAuto ) ;
ctrlButton - > setActionOnLeftClickParams ( tooltip ) ;
}
getParagraph ( ) - > addChild ( ctrlButton ) ;
paragraphChange ( ) ;
setImageSize ( ctrlButton , style ) ;
return ctrlButton ;
}
// ***************************************************************************
void CGroupHTML : : flushString ( )
{
_CurrentViewLink = NULL ;
}
// ***************************************************************************
void CGroupHTML : : clearContext ( )
{
_Paragraph = NULL ;
_PRE . clear ( ) ;
_TextColor . clear ( ) ;
_GlobalColor . clear ( ) ;
_FontSize . clear ( ) ;
_FontWeight . clear ( ) ;
_FontOblique . clear ( ) ;
_FontUnderlined . clear ( ) ;
_FontStrikeThrough . clear ( ) ;
_Indent = 0 ;
_LI = false ;
_DT = false ;
_UL . clear ( ) ;
_DL . clear ( ) ;
2015-12-18 12:29:40 +00:00
_OL . clear ( ) ;
2015-12-13 19:23:08 +00:00
_A . clear ( ) ;
_Link . clear ( ) ;
_LinkTitle . clear ( ) ;
_Tables . clear ( ) ;
_Cells . clear ( ) ;
_TR . clear ( ) ;
_Forms . clear ( ) ;
_Groups . clear ( ) ;
_Anchors . clear ( ) ;
_AnchorName . clear ( ) ;
_CellParams . clear ( ) ;
_Title = false ;
_TextArea = false ;
_Object = false ;
_Localize = false ;
// TR
paragraphChange ( ) ;
// clear the pointer to the current image download since all the button are deleted
# ifdef LOG_DL
nlwarning ( " Clear pointers to %d curls " , Curls . size ( ) ) ;
# endif
for ( uint i = 0 ; i < Curls . size ( ) ; i + + )
{
Curls [ i ] . imgs . clear ( ) ;
}
}
// ***************************************************************************
ucchar CGroupHTML : : getLastChar ( ) const
{
if ( _CurrentViewLink )
{
const ucstring & str = _CurrentViewLink - > getText ( ) ;
if ( ! str . empty ( ) )
return str [ str . length ( ) - 1 ] ;
}
return 0 ;
}
// ***************************************************************************
void CGroupHTML : : paragraphChange ( )
{
_CurrentViewLink = NULL ;
_CurrentViewImage = NULL ;
CGroupParagraph * paragraph = getParagraph ( ) ;
if ( paragraph )
{
// Number of child in this paragraph
uint numChild = paragraph - > getNumChildren ( ) ;
if ( numChild )
{
// Get the last child
CViewBase * child = paragraph - > getChild ( numChild - 1 ) ;
// Is this a string view ?
_CurrentViewLink = dynamic_cast < CViewLink * > ( child ) ;
_CurrentViewImage = dynamic_cast < CViewBitmap * > ( child ) ;
}
}
}
// ***************************************************************************
CInterfaceGroup * CGroupHTML : : getCurrentGroup ( )
{
if ( ! _Cells . empty ( ) & & _Cells . back ( ) )
return _Cells . back ( ) - > Group ;
else
return _GroupListAdaptor ;
}
// ***************************************************************************
void CGroupHTML : : addGroup ( CInterfaceGroup * group , uint beginSpace )
{
if ( ! group )
return ;
// Remove previous paragraph if empty
if ( _Paragraph & & ( _Paragraph - > getNumChildren ( ) = = 0 ) )
{
_Paragraph - > getParent ( ) - > delGroup ( _Paragraph ) ;
_Paragraph = NULL ;
}
registerAnchor ( group ) ;
if ( ! _DivName . empty ( ) )
{
group - > setName ( _DivName ) ;
_Groups . push_back ( group ) ;
}
group - > setSizeRef ( CInterfaceElement : : width ) ;
// Compute begin space between paragraph and tables
// * If first in group, no begin space
// * If behind a paragraph, take the biggest begin space between the previous paragraph and current one.
// Pointer on the current paragraph (can be a table too)
CGroupParagraph * p = dynamic_cast < CGroupParagraph * > ( group ) ;
CInterfaceGroup * parentGroup = CGroupHTML : : getCurrentGroup ( ) ;
const std : : vector < CInterfaceGroup * > & groups = parentGroup - > getGroups ( ) ;
group - > setParent ( parentGroup ) ;
group - > setParentSize ( parentGroup ) ;
if ( groups . empty ( ) )
{
group - > setParentPos ( parentGroup ) ;
group - > setPosRef ( Hotspot_TL ) ;
group - > setParentPosRef ( Hotspot_TL ) ;
beginSpace = 0 ;
}
else
{
// Last is a paragraph ?
group - > setParentPos ( groups . back ( ) ) ;
group - > setPosRef ( Hotspot_TL ) ;
group - > setParentPosRef ( Hotspot_BL ) ;
// Begin space for previous paragraph
CGroupParagraph * previous = dynamic_cast < CGroupParagraph * > ( groups . back ( ) ) ;
if ( previous )
beginSpace = std : : max ( beginSpace , previous - > getTopSpace ( ) ) ;
}
// Set the begin space
if ( p )
p - > setTopSpace ( beginSpace ) ;
else
group - > setY ( - ( sint32 ) beginSpace ) ;
parentGroup - > addGroup ( group ) ;
}
// ***************************************************************************
void CGroupHTML : : setTitle ( const ucstring & title )
{
CInterfaceElement * parent = getParent ( ) ;
if ( parent )
{
if ( ( parent = parent - > getParent ( ) ) )
{
CGroupContainer * container = dynamic_cast < CGroupContainer * > ( parent ) ;
if ( container )
{
container - > setUCTitle ( title ) ;
}
}
}
}
// ***************************************************************************
bool CGroupHTML : : lookupLocalFile ( string & result , const char * url , bool isUrl )
{
result = url ;
string tmp ;
// folder used for images cache
static const string cacheDir = " cache " ;
string : : size_type protocolPos = toLower ( result ) . find ( " :// " ) ;
if ( protocolPos ! = string : : npos )
{
// protocol present, it's an url so file must be searched in cache folder
// TODO: case of special characters & and ?
result = cacheDir + result . substr ( protocolPos + 2 ) ;
// if the file is already cached, use it
if ( CFile : : fileExists ( result ) ) tmp = result ;
}
else
{
// Url is a file ?
if ( toLower ( result ) . find ( " file: " ) = = 0 )
{
result = result . substr ( 5 , result . size ( ) - 5 ) ;
}
tmp = CPath : : lookup ( CFile : : getFilename ( result ) , false , false , false ) ;
if ( tmp . empty ( ) )
{
// try to find in local directory
tmp = CPath : : lookup ( result , false , false , true ) ;
}
}
if ( ! tmp . empty ( ) )
{
// Normalize the path
if ( isUrl )
//result = "file:"+toLower(CPath::standardizePath (CPath::getFullPath (CFile::getPath(result)))+CFile::getFilename(result));*/
result = " file:/ " + tmp ;
else
result = tmp ;
return true ;
}
else
{
// Is it a texture in the big texture ?
if ( CViewRenderer : : getInstance ( ) - > getTextureIdFromName ( result ) > = 0 )
{
return true ;
}
else
{
// This is not a file in the CPath, let libwww open this URL
result = url ;
return false ;
}
}
}
// ***************************************************************************
void CGroupHTML : : submitForm ( uint formId , const char * submitButtonType , const char * submitButtonName , const char * submitButtonValue , sint32 x , sint32 y )
{
// Form id valid ?
if ( formId < _Forms . size ( ) )
{
_PostNextTime = true ;
_PostFormId = formId ;
_PostFormSubmitType = submitButtonType ;
_PostFormSubmitButton = submitButtonName ;
_PostFormSubmitValue = submitButtonValue ;
_PostFormSubmitX = x ;
_PostFormSubmitY = y ;
}
}
// ***************************************************************************
void CGroupHTML : : setBackgroundColor ( const CRGBA & bgcolor )
{
// Should have a child named bg
CViewBase * view = getView ( DefaultBackgroundBitmapView ) ;
if ( view )
{
CViewBitmap * bitmap = dynamic_cast < CViewBitmap * > ( view ) ;
if ( bitmap )
{
// Change the background color
bitmap - > setColor ( bgcolor ) ;
bitmap - > setModulateGlobalColor ( false ) ;
}
}
}
// ***************************************************************************
void CGroupHTML : : setBackground ( const string & bgtex , bool scale , bool tile )
{
// Should have a child named bg
CViewBase * view = getView ( DefaultBackgroundBitmapView ) ;
if ( view )
{
CViewBitmap * bitmap = dynamic_cast < CViewBitmap * > ( view ) ;
if ( bitmap )
{
bitmap - > setParentPosRef ( Hotspot_TL ) ;
bitmap - > setPosRef ( Hotspot_TL ) ;
bitmap - > setX ( 0 ) ;
bitmap - > setY ( 0 ) ;
bitmap - > setRenderLayer ( - 2 ) ;
bitmap - > setScale ( scale ) ;
bitmap - > setTile ( tile ) ;
addImageDownload ( bgtex , view ) ;
}
}
}
struct CButtonFreezer : public CInterfaceElementVisitor
{
virtual void visitCtrl ( CCtrlBase * ctrl )
{
CCtrlBaseButton * textButt = dynamic_cast < CCtrlTextButton * > ( ctrl ) ;
if ( textButt )
{
textButt - > setFrozen ( true ) ;
}
}
} ;
// ***************************************************************************
void CGroupHTML : : handle ( )
{
H_AUTO ( RZ_Interface_Html_handle )
const CWidgetManager : : SInterfaceTimes & times = CWidgetManager : : getInstance ( ) - > getInterfaceTimes ( ) ;
// handle curl downloads
checkDownloads ( ) ;
if ( _Connecting )
{
// Check timeout if needed
if ( _TimeoutValue ! = 0 & & _ConnectingTimeout < = ( times . thisFrameMs / 1000.0f ) )
{
browseError ( ( " Connection timeout : " + _URL ) . c_str ( ) ) ;
_Connecting = false ;
}
}
else
if ( _BrowseNextTime | | _PostNextTime )
{
// Set timeout
_Connecting = true ;
_ConnectingTimeout = ( times . thisFrameMs / 1000.0f ) + _TimeoutValue ;
// freeze form buttons
CButtonFreezer freezer ;
this - > visit ( & freezer ) ;
// Home ?
if ( _URL = = " home " )
_URL = home ( ) ;
string finalUrl ;
bool isLocal = lookupLocalFile ( finalUrl , _URL . c_str ( ) , true ) ;
// Save new url
_URL = finalUrl ;
// file is probably from bnp (ingame help)
if ( isLocal )
{
doBrowseLocalFile ( finalUrl ) ;
}
else
{
_TrustedDomain = isTrustedDomain ( setCurrentDomain ( finalUrl ) ) ;
SFormFields formfields ;
if ( _PostNextTime )
{
buildHTTPPostParams ( formfields ) ;
// _URL is set from form.Action
finalUrl = _URL ;
}
else
{
// Add custom get params from child classes
addHTTPGetParams ( finalUrl , _TrustedDomain ) ;
}
doBrowseRemoteUrl ( finalUrl , " " , _PostNextTime , formfields ) ;
}
_BrowseNextTime = false ;
_PostNextTime = false ;
}
}
// ***************************************************************************
void CGroupHTML : : buildHTTPPostParams ( SFormFields & formfields )
{
// Add text area text
uint i ;
if ( _PostFormId > = _Forms . size ( ) )
{
nlwarning ( " (%s) invalid form index %d, _Forms %d " , _Id . c_str ( ) , _PostFormId , _Forms . size ( ) ) ;
return ;
}
// Ref the form
CForm & form = _Forms [ _PostFormId ] ;
// Save new url
_URL = form . Action ;
_TrustedDomain = isTrustedDomain ( setCurrentDomain ( _URL ) ) ;
for ( i = 0 ; i < form . Entries . size ( ) ; i + + )
{
// Text area ?
bool addEntry = false ;
ucstring entryData ;
if ( form . Entries [ i ] . TextArea )
{
// Get the edit box view
CInterfaceGroup * group = form . Entries [ i ] . TextArea - > getGroup ( " eb " ) ;
if ( group )
{
// Should be a CGroupEditBox
CGroupEditBox * editBox = dynamic_cast < CGroupEditBox * > ( group ) ;
if ( editBox )
{
entryData = editBox - > getViewText ( ) - > getText ( ) ;
addEntry = true ;
}
}
}
else if ( form . Entries [ i ] . Checkbox )
{
// todo handle unicode POST here
if ( form . Entries [ i ] . Checkbox - > getPushed ( ) )
{
entryData = form . Entries [ i ] . Value ;
addEntry = true ;
}
}
else if ( form . Entries [ i ] . ComboBox )
{
CDBGroupComboBox * cb = form . Entries [ i ] . ComboBox ;
entryData . fromUtf8 ( form . Entries [ i ] . SelectValues [ cb - > getSelection ( ) ] ) ;
addEntry = true ;
}
// This is a hidden value
else
{
entryData = form . Entries [ i ] . Value ;
addEntry = true ;
}
// Add this entry
if ( addEntry )
{
formfields . add ( form . Entries [ i ] . Name , CI18N : : encodeUTF8 ( entryData ) ) ;
}
}
if ( _PostFormSubmitType = = " image " )
{
// Add the button coordinates
if ( _PostFormSubmitButton . find_first_of ( " [ " ) = = string : : npos )
{
formfields . add ( _PostFormSubmitButton + " _x " , NLMISC : : toString ( _PostFormSubmitX ) ) ;
formfields . add ( _PostFormSubmitButton + " _y " , NLMISC : : toString ( _PostFormSubmitY ) ) ;
}
else
{
formfields . add ( _PostFormSubmitButton , NLMISC : : toString ( _PostFormSubmitX ) ) ;
formfields . add ( _PostFormSubmitButton , NLMISC : : toString ( _PostFormSubmitY ) ) ;
}
}
else
formfields . add ( _PostFormSubmitButton , _PostFormSubmitValue ) ;
// Add custom params from child classes
addHTTPPostParams ( formfields , _TrustedDomain ) ;
}
// ***************************************************************************
void CGroupHTML : : doBrowseLocalFile ( const std : : string & uri )
{
std : : string filename ;
if ( toLower ( uri ) . find ( " file:/ " ) = = 0 )
{
filename = uri . substr ( 6 , uri . size ( ) - 6 ) ;
}
else
{
filename = uri ;
}
# if LOG_DL
nlwarning ( " (%s) browse local file '%s' " , filename . c_str ( ) ) ;
# endif
_TrustedDomain = true ;
// Stop previous browse, remove content
stopBrowse ( ) ;
_Browsing = true ;
updateRefreshButton ( ) ;
CIFile in ;
if ( in . open ( filename ) )
{
std : : string html ;
while ( ! in . eof ( ) )
{
char buf [ 1024 ] ;
in . getline ( buf , 1024 ) ;
html + = std : : string ( buf ) + " \n " ;
}
in . close ( ) ;
if ( ! renderHtmlString ( html ) )
{
browseError ( ( string ( " Failed to parse html from file : " ) + filename ) . c_str ( ) ) ;
}
}
else
{
browseError ( ( string ( " The page address is malformed : " ) + filename ) . c_str ( ) ) ;
}
}
// ***************************************************************************
void CGroupHTML : : doBrowseRemoteUrl ( const std : : string & url , const std : : string & referer , bool doPost , const SFormFields & formfields )
{
// Stop previous request and remove content
stopBrowse ( ) ;
_Browsing = true ;
updateRefreshButton ( ) ;
// Reset the title
if ( _TitlePrefix . empty ( ) )
setTitle ( CI18N : : get ( " uiPleaseWait " ) ) ;
else
setTitle ( _TitlePrefix + " - " + CI18N : : get ( " uiPleaseWait " ) ) ;
# if LOG_DL
nlwarning ( " (%s) browse url (trusted=%s) '%s', referer='%s', post='%s', nb form values %d " ,
_Id . c_str ( ) , ( _TrustedDomain ? " true " : " false " ) , url . c_str ( ) , referer . c_str ( ) , ( doPost ? " true " : " false " ) , formfields . Values . size ( ) ) ;
# endif
if ( ! MultiCurl )
{
browseError ( string ( " Invalid MultCurl handle, loading url failed : " + url ) . c_str ( ) ) ;
return ;
}
CURL * curl = curl_easy_init ( ) ;
if ( ! curl )
{
nlwarning ( " (%s) failed to create curl handle " , _Id . c_str ( ) ) ;
browseError ( string ( " Failed to create cURL handle : " + url ) . c_str ( ) ) ;
return ;
}
// do not follow redirects, we have own handler
curl_easy_setopt ( curl , CURLOPT_FOLLOWLOCATION , 0 ) ;
// after redirect
curl_easy_setopt ( curl , CURLOPT_FRESH_CONNECT , 1 ) ;
// tell curl to use compression if possible (gzip, deflate)
// leaving this empty allows all encodings that curl supports
//curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
// limit curl to HTTP and HTTPS protocols only
curl_easy_setopt ( curl , CURLOPT_PROTOCOLS , CURLPROTO_HTTP | CURLPROTO_HTTPS ) ;
curl_easy_setopt ( curl , CURLOPT_REDIR_PROTOCOLS , CURLPROTO_HTTP | CURLPROTO_HTTPS ) ;
// Destination
curl_easy_setopt ( curl , CURLOPT_URL , url . c_str ( ) ) ;
// User-Agent:
std : : string userAgent = options . appName + " / " + options . appVersion ;
curl_easy_setopt ( curl , CURLOPT_USERAGENT , userAgent . c_str ( ) ) ;
// Cookies
sendCookies ( curl , HTTPCurrentDomain , _TrustedDomain ) ;
// Referer
if ( ! referer . empty ( ) )
{
curl_easy_setopt ( curl , CURLOPT_REFERER , referer . c_str ( ) ) ;
# ifdef LOG_DL
nlwarning ( " (%s) set referer '%s' " , _Id . c_str ( ) , referer . c_str ( ) ) ;
# endif
}
if ( doPost )
{
// serialize form data and add it to curl
std : : string data ;
for ( uint i = 0 ; i < formfields . Values . size ( ) ; + + i )
{
char * escapedName = curl_easy_escape ( curl , formfields . Values [ i ] . name . c_str ( ) , formfields . Values [ i ] . name . size ( ) ) ;
char * escapedValue = curl_easy_escape ( curl , formfields . Values [ i ] . value . c_str ( ) , formfields . Values [ i ] . value . size ( ) ) ;
if ( i > 0 )
data + = " & " ;
data + = std : : string ( escapedName ) + " = " + escapedValue ;
curl_free ( escapedName ) ;
curl_free ( escapedValue ) ;
}
curl_easy_setopt ( curl , CURLOPT_POST , 1 ) ;
curl_easy_setopt ( curl , CURLOPT_POSTFIELDSIZE , data . size ( ) ) ;
curl_easy_setopt ( curl , CURLOPT_COPYPOSTFIELDS , data . c_str ( ) ) ;
}
else
{
curl_easy_setopt ( curl , CURLOPT_HTTPGET , 1 ) ;
}
// transfer handle
_CurlWWW = new CCurlWWWData ( curl , url ) ;
// set the language code used by the client
std : : vector < std : : string > headers ;
headers . push_back ( " Accept-Language: " + options . languageCode ) ;
headers . push_back ( " Accept-Charset: utf-8 " ) ;
for ( uint i = 0 ; i < headers . size ( ) ; + + i )
{
_CurlWWW - > HeadersSent = curl_slist_append ( _CurlWWW - > HeadersSent , headers [ i ] . c_str ( ) ) ;
}
curl_easy_setopt ( curl , CURLOPT_HTTPHEADER , _CurlWWW - > HeadersSent ) ;
// catch headers for redirect
curl_easy_setopt ( curl , CURLOPT_HEADERFUNCTION , curlHeaderCallback ) ;
curl_easy_setopt ( curl , CURLOPT_WRITEHEADER , _CurlWWW ) ;
// catch body
curl_easy_setopt ( curl , CURLOPT_WRITEFUNCTION , curlDataCallback ) ;
curl_easy_setopt ( curl , CURLOPT_WRITEDATA , _CurlWWW ) ;
# if LOG_DL
// progress callback
curl_easy_setopt ( curl , CURLOPT_NOPROGRESS , 0 ) ;
curl_easy_setopt ( curl , CURLOPT_XFERINFOFUNCTION , curlProgressCallback ) ;
curl_easy_setopt ( curl , CURLOPT_XFERINFODATA , _CurlWWW ) ;
# else
// progress off
curl_easy_setopt ( curl , CURLOPT_NOPROGRESS , 1 ) ;
# endif
//
curl_multi_add_handle ( MultiCurl , curl ) ;
// start the transfer
int NewRunningCurls = 0 ;
curl_multi_perform ( MultiCurl , & NewRunningCurls ) ;
RunningCurls + + ;
}
// ***************************************************************************
void CGroupHTML : : htmlDownloadFinished ( const std : : string & content , const std : : string & type , long code )
{
# ifdef LOG_DL
nlwarning ( " (%s) HTML download finished, content length %d, type '%s', code %d " , _Id . c_str ( ) , content . size ( ) , type . c_str ( ) , code ) ;
# endif
// set trusted domain for parsing
_TrustedDomain = isTrustedDomain ( setCurrentDomain ( _URL ) ) ;
// create <html> markup for image downloads
if ( type . find ( " image/ " ) = = 0 & & content . size ( ) > 0 )
{
try
{
std : : string dest = localImageName ( _URL ) ;
COFile out ;
out . open ( dest ) ;
out . serialBuffer ( ( uint8 * ) ( content . c_str ( ) ) , content . size ( ) ) ;
out . close ( ) ;
# ifdef LOG_DL
nlwarning ( " (%s) image saved to '%s', url '%s' " , _Id . c_str ( ) , dest . c_str ( ) , _URL . c_str ( ) ) ;
# endif
}
catch ( . . . ) { }
// create html code with image url inside and do the request again
renderHtmlString ( " <html><head><title> " + _URL + " </title></head><body><img src= \" " + _URL + " \" ></body></html> " ) ;
}
else
{
renderHtmlString ( content ) ;
}
}
// ***************************************************************************
bool CGroupHTML : : renderHtmlString ( const std : : string & html )
{
bool success ;
//
_Browsing = true ;
// clear content
beginBuild ( ) ;
success = parseHtml ( html ) ;
// invalidate coords
endBuild ( ) ;
// set the browser as complete
_Browsing = false ;
updateRefreshButton ( ) ;
// check that the title is set, or reset it (in the case the page
// does not provide a title)
if ( _TitleString . empty ( ) )
{
setTitle ( _TitlePrefix ) ;
}
return success ;
}
// ***************************************************************************
void CGroupHTML : : doBrowseAnchor ( const std : : string & anchor )
{
CInterfaceElement * pIE = _Anchors . find ( anchor ) - > second ;
if ( pIE )
{
// hotspot depends on vertical/horizontal scrollbar
CCtrlScroll * pSB = getScrollBar ( ) ;
if ( pSB )
{
pSB - > ensureVisible ( pIE , Hotspot_Tx , Hotspot_Tx ) ;
}
}
}
// ***************************************************************************
void CGroupHTML : : draw ( )
{
CGroupScrollText : : draw ( ) ;
}
// ***************************************************************************
void CGroupHTML : : endBuild ( )
{
invalidateCoords ( ) ;
}
// ***************************************************************************
void CGroupHTML : : addHTTPGetParams ( string & /* url */ , bool /*trustedDomain*/ )
{
}
// ***************************************************************************
void CGroupHTML : : addHTTPPostParams ( SFormFields & /* formfields */ , bool /*trustedDomain*/ )
{
}
// ***************************************************************************
void CGroupHTML : : requestTerminated ( )
{
if ( _CurlWWW )
{
# if LOG_DL
nlwarning ( " (%s) stop curl, url '%s' " , _Id . c_str ( ) , _CurlWWW - > Url . c_str ( ) ) ;
# endif
if ( MultiCurl )
curl_multi_remove_handle ( MultiCurl , _CurlWWW - > Request ) ;
delete _CurlWWW ;
_CurlWWW = NULL ;
_Connecting = false ;
}
}
// ***************************************************************************
string CGroupHTML : : home ( )
{
return Home ;
}
// ***************************************************************************
void CGroupHTML : : removeContent ( )
{
// Remove old document
if ( ! _GroupListAdaptor )
{
_GroupListAdaptor = new CGroupListAdaptor ( CViewBase : : TCtorParam ( ) ) ; // deleted by the list
_GroupListAdaptor - > setResizeFromChildH ( true ) ;
getList ( ) - > addChild ( _GroupListAdaptor , true ) ;
}
// Group list adaptor not exist ?
_GroupListAdaptor - > clearGroups ( ) ;
_GroupListAdaptor - > clearControls ( ) ;
_GroupListAdaptor - > clearViews ( ) ;
CWidgetManager : : getInstance ( ) - > clearViewUnders ( ) ;
CWidgetManager : : getInstance ( ) - > clearCtrlsUnders ( ) ;
// Clear all the context
clearContext ( ) ;
// Reset default background color
setBackgroundColor ( BgColor ) ;
paragraphChange ( ) ;
}
// ***************************************************************************
const std : : string & CGroupHTML : : selectTreeNodeRecurs ( CGroupTree : : SNode * node , const std : : string & url )
{
static std : : string emptyString ;
if ( ! node )
{
return emptyString ;
}
// if this node match
if ( actionLaunchUrlRecurs ( node - > AHName , node - > AHParams , url ) )
{
return node - > Id ;
}
// fails => look into children
else
{
for ( uint i = 0 ; i < node - > Children . size ( ) ; i + + )
{
const string & childRes = selectTreeNodeRecurs ( node - > Children [ i ] , url ) ;
if ( ! childRes . empty ( ) )
return childRes ;
}
// none match...
return emptyString ;
}
}
// ***************************************************************************
bool CGroupHTML : : actionLaunchUrlRecurs ( const std : : string & ah , const std : : string & params , const std : : string & url )
{
// check if this action match
if ( ( ah = = " launch_help " | | ah = = " browse " ) & & IActionHandler : : getParam ( params , " url " ) = = url )
{
return true ;
}
// can be a proc that contains launch_help/browse => look recurs
else if ( ah = = " proc " )
{
const std : : string & procName = params ;
// look into this proc
uint numActions = CWidgetManager : : getInstance ( ) - > getParser ( ) - > getProcedureNumActions ( procName ) ;
for ( uint i = 0 ; i < numActions ; i + + )
{
string procAh , procParams ;
if ( CWidgetManager : : getInstance ( ) - > getParser ( ) - > getProcedureAction ( procName , i , procAh , procParams ) )
{
// recurs proc if needed!
if ( actionLaunchUrlRecurs ( procAh , procParams , url ) )
return true ;
}
}
}
return false ;
}
// ***************************************************************************
void CGroupHTML : : clearUndoRedo ( )
{
// erase any undo/redo
_BrowseUndo . clear ( ) ;
_BrowseRedo . clear ( ) ;
// update buttons validation
updateUndoRedoButtons ( ) ;
}
// ***************************************************************************
void CGroupHTML : : pushUrlUndoRedo ( const std : : string & url )
{
// if same url, no op
if ( url = = _AskedUrl )
return ;
// erase any redo, push undo, set current
_BrowseRedo . clear ( ) ;
if ( ! _AskedUrl . empty ( ) )
_BrowseUndo . push_back ( _AskedUrl ) ;
_AskedUrl = url ;
// limit undo
while ( _BrowseUndo . size ( ) > MaxUrlUndoRedo )
_BrowseUndo . pop_front ( ) ;
// update buttons validation
updateUndoRedoButtons ( ) ;
}
// ***************************************************************************
void CGroupHTML : : browseUndo ( )
{
if ( _BrowseUndo . empty ( ) )
return ;
// push to redo, pop undo, and set current
_BrowseRedo . push_front ( _AskedUrl ) ;
_AskedUrl = _BrowseUndo . back ( ) ;
_BrowseUndo . pop_back ( ) ;
// update buttons validation
updateUndoRedoButtons ( ) ;
// and then browse the undoed url, with no undo/redo
doBrowse ( _AskedUrl . c_str ( ) ) ;
}
// ***************************************************************************
void CGroupHTML : : browseRedo ( )
{
if ( _BrowseRedo . empty ( ) )
return ;
// push to undo, pop redo, and set current
_BrowseUndo . push_back ( _AskedUrl ) ;
_AskedUrl = _BrowseRedo . front ( ) ;
_BrowseRedo . pop_front ( ) ;
// update buttons validation
updateUndoRedoButtons ( ) ;
// and then browse the redoed url, with no undo/redo
doBrowse ( _AskedUrl . c_str ( ) ) ;
}
// ***************************************************************************
void CGroupHTML : : updateUndoRedoButtons ( )
{
CCtrlBaseButton * butUndo = dynamic_cast < CCtrlBaseButton * > ( CWidgetManager : : getInstance ( ) - > getElementFromId ( _BrowseUndoButton ) ) ;
CCtrlBaseButton * butRedo = dynamic_cast < CCtrlBaseButton * > ( CWidgetManager : : getInstance ( ) - > getElementFromId ( _BrowseRedoButton ) ) ;
// gray according to list size
if ( butUndo )
butUndo - > setFrozen ( _BrowseUndo . empty ( ) ) ;
if ( butRedo )
butRedo - > setFrozen ( _BrowseRedo . empty ( ) ) ;
}
// ***************************************************************************
void CGroupHTML : : updateRefreshButton ( )
{
CCtrlBaseButton * butRefresh = dynamic_cast < CCtrlBaseButton * > ( CWidgetManager : : getInstance ( ) - > getElementFromId ( _BrowseRefreshButton ) ) ;
bool enabled = ! _Browsing & & ! _Connecting ;
if ( butRefresh )
butRefresh - > setFrozen ( ! enabled ) ;
}
// ***************************************************************************
NLMISC_REGISTER_OBJECT ( CViewBase , CGroupHTMLInputOffset , std : : string , " html_input_offset " ) ;
CGroupHTMLInputOffset : : CGroupHTMLInputOffset ( const TCtorParam & param )
: CInterfaceGroup ( param ) ,
Offset ( 0 )
{
}
xmlNodePtr CGroupHTMLInputOffset : : serialize ( xmlNodePtr parentNode , const char * type ) const
{
xmlNodePtr node = CInterfaceGroup : : serialize ( parentNode , type ) ;
if ( node = = NULL )
return NULL ;
xmlSetProp ( node , BAD_CAST " type " , BAD_CAST " html_input_offset " ) ;
xmlSetProp ( node , BAD_CAST " y_offset " , BAD_CAST toString ( Offset ) . c_str ( ) ) ;
return node ;
}
// ***************************************************************************
bool CGroupHTMLInputOffset : : parse ( xmlNodePtr cur , CInterfaceGroup * parentGroup )
{
if ( ! CInterfaceGroup : : parse ( cur , parentGroup ) ) return false ;
CXMLAutoPtr ptr ;
// Get the url
ptr = xmlGetProp ( cur , ( xmlChar * ) " y_offset " ) ;
if ( ptr )
fromString ( ( const char * ) ptr , Offset ) ;
return true ;
}
// ***************************************************************************
int CGroupHTML : : luaBrowse ( CLuaState & ls )
{
const char * funcName = " browse " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
browse ( ls . toString ( 1 ) ) ;
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaRefresh ( CLuaState & ls )
{
const char * funcName = " refresh " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
refresh ( ) ;
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaRemoveContent ( CLuaState & ls )
{
const char * funcName = " removeContent " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
removeContent ( ) ;
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaInsertText ( CLuaState & ls )
{
const char * funcName = " insertText " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TBOOLEAN ) ;
string name = ls . toString ( 1 ) ;
ucstring text ;
text . fromUtf8 ( ls . toString ( 2 ) ) ;
if ( ! _Forms . empty ( ) )
{
for ( uint i = 0 ; i < _Forms . back ( ) . Entries . size ( ) ; i + + )
{
if ( _Forms . back ( ) . Entries [ i ] . TextArea & & _Forms . back ( ) . Entries [ i ] . Name = = name )
{
// Get the edit box view
CInterfaceGroup * group = _Forms . back ( ) . Entries [ i ] . TextArea - > getGroup ( " eb " ) ;
if ( group )
{
// Should be a CGroupEditBox
CGroupEditBox * editBox = dynamic_cast < CGroupEditBox * > ( group ) ;
if ( editBox )
editBox - > writeString ( text , false , ls . toBoolean ( 3 ) ) ;
}
}
}
}
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaAddString ( CLuaState & ls )
{
const char * funcName = " addString " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
addString ( ucstring ( ls . toString ( 1 ) ) ) ;
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaAddImage ( CLuaState & ls )
{
const char * funcName = " addImage " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TBOOLEAN ) ;
if ( ! _Paragraph )
{
newParagraph ( 0 ) ;
paragraphChange ( ) ;
}
string url = getLink ( ) ;
if ( ! url . empty ( ) )
{
string params = " name= " + getId ( ) + " |url= " + getLink ( ) ;
addButton ( CCtrlButton : : PushButton , ls . toString ( 1 ) , ls . toString ( 1 ) , ls . toString ( 1 ) ,
" " , ls . toBoolean ( 2 ) , " browse " , params . c_str ( ) , " " ) ;
}
else
{
addImage ( ls . toString ( 1 ) , ls . toBoolean ( 2 ) ) ;
}
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaBeginElement ( CLuaState & ls )
{
const char * funcName = " beginElement " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TNUMBER ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TTABLE ) ;
uint element_number = ( uint ) ls . toInteger ( 1 ) ;
std : : vector < bool > present ;
std : : vector < const char * > value ;
present . resize ( 30 , false ) ;
value . resize ( 30 ) ;
CLuaObject params ;
params . pop ( ls ) ;
uint max_idx = 0 ;
ENUM_LUA_TABLE ( params , it )
{
if ( ! it . nextKey ( ) . isInteger ( ) )
{
nlwarning ( " %s : bad key encountered with type %s, number expected. " , funcName , it . nextKey ( ) . getTypename ( ) ) ;
continue ;
}
if ( ! it . nextValue ( ) . isString ( ) )
{
nlwarning ( " %s : bad value encountered with type %s for key %s, string expected. " , funcName , it . nextValue ( ) . getTypename ( ) , it . nextKey ( ) . toString ( ) . c_str ( ) ) ;
continue ;
}
uint idx = ( uint ) it . nextKey ( ) . toInteger ( ) ;
present . insert ( present . begin ( ) + ( uint ) it . nextKey ( ) . toInteger ( ) , true ) ;
string str = it . nextValue ( ) . toString ( ) ;
size_t size = str . size ( ) + 1 ;
char * buffer = new char [ size ] ;
strncpy ( buffer , str . c_str ( ) , size ) ;
value . insert ( value . begin ( ) + ( uint ) it . nextKey ( ) . toInteger ( ) , buffer ) ;
}
beginElement ( element_number , present , value ) ;
if ( element_number = = HTML_A )
{
// ingame lua scripts from browser are using <a href="#http://..."> url scheme
// reason unknown
_LuaHrefHack = true ;
addLink ( element_number , present , value ) ;
_LuaHrefHack = false ;
}
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaEndElement ( CLuaState & ls )
{
const char * funcName = " endElement " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TNUMBER ) ;
uint element_number = ( uint ) ls . toInteger ( 1 ) ;
endElement ( element_number ) ;
return 0 ;
}
// ***************************************************************************
int CGroupHTML : : luaShowDiv ( CLuaState & ls )
{
const char * funcName = " showDiv " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TBOOLEAN ) ;
if ( ! _Groups . empty ( ) )
{
for ( uint i = 0 ; i < _Groups . size ( ) ; i + + )
{
CInterfaceGroup * group = _Groups [ i ] ;
if ( group - > getName ( ) = = ls . toString ( 1 ) )
{
group - > setActive ( ls . toBoolean ( 2 ) ) ;
}
}
}
return 0 ;
}
// ***************************************************************************
void CGroupHTML : : setURL ( const std : : string & url )
{
browse ( url . c_str ( ) ) ;
}
// ***************************************************************************
inline bool isDigit ( ucchar c , uint base = 16 )
{
if ( c > = ' 0 ' & & c < = ' 9 ' ) return true ;
if ( base ! = 16 ) return false ;
if ( c > = ' A ' & & c < = ' F ' ) return true ;
if ( c > = ' a ' & & c < = ' f ' ) return true ;
return false ;
}
// ***************************************************************************
inline ucchar convertHexDigit ( ucchar c )
{
if ( c > = ' 0 ' & & c < = ' 9 ' ) return c - ' 0 ' ;
if ( c > = ' A ' & & c < = ' F ' ) return c - ' A ' + 10 ;
if ( c > = ' a ' & & c < = ' f ' ) return c - ' a ' + 10 ;
return 0 ;
}
// ***************************************************************************
ucstring CGroupHTML : : decodeHTMLEntities ( const ucstring & str )
{
ucstring result ;
uint last , pos ;
for ( uint i = 0 ; i < str . length ( ) ; + + i )
{
// HTML entity
if ( str [ i ] = = ' & ' & & ( str . length ( ) - i ) > = 4 )
{
pos = i + 1 ;
// unicode character
if ( str [ pos ] = = ' # ' )
{
+ + pos ;
// using decimal by default
uint base = 10 ;
// using hexadecimal if &#x
if ( str [ pos ] = = ' x ' )
{
base = 16 ;
+ + pos ;
}
// setup "last" to point at the first character following "&#x?[0-9a-f]+"
for ( last = pos ; last < str . length ( ) ; + + last ) if ( ! isDigit ( str [ last ] , base ) ) break ;
// make sure that at least 1 digit was found
// and have the terminating ';' to complete the token: "&#x?[0-9a-f]+;"
if ( last = = pos | | str [ last ] ! = ' ; ' )
{
result + = str [ i ] ;
continue ;
}
ucchar c = 0 ;
// convert digits to unicode character
while ( pos < last ) c = convertHexDigit ( str [ pos + + ] ) + c * ucchar ( base ) ;
// append our new character to the result string
result + = c ;
// move 'i' forward to point at the ';' .. the for(...) will increment i to point to next char
i = last ;
continue ;
}
// special xml characters
if ( str . substr ( i + 1 , 5 ) = = ucstring ( " quot; " ) ) { i + = 5 ; result + = ' \" ' ; continue ; }
if ( str . substr ( i + 1 , 4 ) = = ucstring ( " amp; " ) ) { i + = 4 ; result + = ' & ' ; continue ; }
if ( str . substr ( i + 1 , 3 ) = = ucstring ( " lt; " ) ) { i + = 3 ; result + = ' < ' ; continue ; }
if ( str . substr ( i + 1 , 3 ) = = ucstring ( " gt; " ) ) { i + = 3 ; result + = ' > ' ; continue ; }
}
// all the special cases are catered for... treat this as a normal character
result + = str [ i ] ;
}
return result ;
}
// ***************************************************************************
std : : string CGroupHTML : : getAbsoluteUrl ( const std : : string & url )
{
CUrlParser uri ( url ) ;
if ( uri . isAbsolute ( ) )
return url ;
uri . inherit ( _URL ) ;
return uri . toString ( ) ;
}
// ***************************************************************************
// CGroupHTML::CStyleParams style;
// style.FontSize; // font-size: 10px;
// style.TextColor; // color: #ABCDEF;
// style.Underlined; // text-decoration: underline; text-decoration-line: underline;
// style.StrikeThrough; // text-decoration: line-through; text-decoration-line: line-through;
void CGroupHTML : : getStyleParams ( const std : : string & styleString , CStyleParams & style , bool inherit )
{
float tmpf ;
TStyle styles = parseStyle ( styleString ) ;
TStyle : : iterator it ;
for ( it = styles . begin ( ) ; it ! = styles . end ( ) ; + + it )
{
if ( it - > first = = " font-size " )
{
float tmp ;
sint size = 0 ;
getPercentage ( size , tmp , it - > second . c_str ( ) ) ;
if ( size > 0 )
style . FontSize = size ;
}
else
if ( it - > first = = " font-style " )
{
if ( it - > second = = " italic " | | it - > second = = " oblique " )
style . FontOblique = true ;
}
else
if ( it - > first = = " font-weight " )
{
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
uint weight = 400 ;
if ( it - > second = = " normal " )
weight = 400 ;
else
if ( it - > second = = " bold " )
weight = 700 ;
else
if ( it - > second = = " lighter " )
{
const uint lighter [ ] = { 100 , 100 , 100 , 100 , 100 , 400 , 400 , 700 , 700 } ;
int index = getFontWeight ( ) / 100 - 1 ;
clamp ( index , 1 , 9 ) ;
weight = lighter [ index - 1 ] ;
}
else
if ( it - > second = = " bolder " )
{
const uint bolder [ ] = { 400 , 400 , 400 , 700 , 700 , 900 , 900 , 900 , 900 } ;
uint index = getFontWeight ( ) / 100 + 1 ;
clamp ( index , 1 , 9 ) ;
weight = bolder [ index - 1 ] ;
}
else
if ( fromString ( it - > second , weight ) )
{
weight = ( weight / 100 ) ;
clamp ( weight , 1 , 9 ) ;
weight * = 100 ;
}
style . FontWeight = weight ;
}
else
if ( it - > first = = " color " )
scanHTMLColor ( it - > second . c_str ( ) , style . TextColor ) ;
else
if ( it - > first = = " text-decoration " | | it - > first = = " text-decoration-line " )
{
std : : string prop ( toLower ( it - > second ) ) ;
style . Underlined = ( prop . find ( " underline " ) ! = std : : string : : npos ) ;
style . StrikeThrough = ( prop . find ( " line-through " ) ! = std : : string : : npos ) ;
}
else
if ( it - > first = = " width " )
getPercentage ( style . Width , tmpf , it - > second . c_str ( ) ) ;
else
if ( it - > first = = " height " )
getPercentage ( style . Height , tmpf , it - > second . c_str ( ) ) ;
else
if ( it - > first = = " max-width " )
getPercentage ( style . MaxWidth , tmpf , it - > second . c_str ( ) ) ;
else
if ( it - > first = = " max-height " )
getPercentage ( style . MaxHeight , tmpf , it - > second . c_str ( ) ) ;
}
if ( inherit )
{
style . Underlined = getFontUnderlined ( ) | | style . Underlined ;
style . StrikeThrough = getFontStrikeThrough ( ) | | style . StrikeThrough ;
}
}
// ***************************************************************************
void CGroupHTML : : applyCssMinMax ( sint32 & width , sint32 & height , sint32 minw , sint32 minh , sint32 maxw , sint32 maxh )
{
if ( maxw < = 0 ) maxw = width ;
if ( maxh < = 0 ) maxh = height ;
maxw = std : : max ( minw , maxw ) ;
maxh = std : : max ( minh , maxh ) ;
float ratio = ( float ) width / std : : max ( 1 , height ) ;
if ( width > maxw )
{
width = maxw ;
height = std : : max ( ( sint32 ) ( maxw / ratio ) , minh ) ;
}
if ( width < minw )
{
width = minw ;
height = std : : min ( ( sint32 ) ( minw / ratio ) , maxh ) ;
}
if ( height > maxh )
{
width = std : : max ( ( sint32 ) ( maxh * ratio ) , minw ) ;
height = maxh ;
}
if ( height < minh )
{
width = std : : min ( ( sint32 ) ( minh * ratio ) , maxw ) ;
height = minh ;
}
if ( width > maxw & & height > maxh )
{
if ( maxw / width < = maxh / height )
{
width = maxw ;
height = std : : max ( minh , ( sint32 ) ( maxw / ratio ) ) ;
}
else
{
width = std : : max ( minw , ( sint32 ) ( maxh * ratio ) ) ;
height = maxh ;
}
}
if ( width < minw & & height < minh )
{
if ( minw / width < = minh / height )
{
width = std : : min ( maxw , ( sint32 ) ( minh * ratio ) ) ;
height = minh ;
}
else
{
width = minw ;
height = std : : min ( maxh , ( sint32 ) ( minw / ratio ) ) ;
}
}
if ( width < minw & & height > maxh )
{
width = minw ;
height = maxh ;
}
if ( width > maxw & & height < minh )
{
width = maxw ;
height = minh ;
}
}
// ***************************************************************************
size_t CGroupHTML : : curlHeaderCallback ( char * buffer , size_t size , size_t nmemb , void * pCCurlWWWData )
{
CCurlWWWData * me = static_cast < CCurlWWWData * > ( pCCurlWWWData ) ;
if ( me )
{
std : : string header ;
header . append ( buffer , size * nmemb ) ;
me - > setRecvHeader ( header . substr ( 0 , header . find_first_of ( " \n \r " ) ) ) ;
}
return size * nmemb ;
}
// ***************************************************************************
size_t CGroupHTML : : curlDataCallback ( char * buffer , size_t size , size_t nmemb , void * pCCurlWWWData )
{
CCurlWWWData * me = static_cast < CCurlWWWData * > ( pCCurlWWWData ) ;
if ( me )
me - > Content . append ( buffer , size * nmemb ) ;
return size * nmemb ;
}
// ***************************************************************************
size_t CGroupHTML : : curlProgressCallback ( void * pCCurlWWWData , curl_off_t dltotal , curl_off_t dlnow , curl_off_t ultotal , curl_off_t ulnow )
{
CCurlWWWData * me = static_cast < CCurlWWWData * > ( pCCurlWWWData ) ;
if ( me )
{
if ( dltotal > 0 | | dlnow > 0 | | ultotal > 0 | | ulnow > 0 )
{
nlwarning ( " > dltotal %d, dlnow %d, ultotal %d, ulnow %d, url '%s' " , dltotal , dlnow , ultotal , ulnow , me - > Url . c_str ( ) ) ;
}
}
// return 1 to cancel download
return 0 ;
}
2015-12-18 12:29:40 +00:00
// ***************************************************************************
std : : string CGroupHTML : : HTMLOListElement : : getListMarkerText ( ) const
{
std : : string ret ;
sint32 number = Value ;
bool upper = false ;
if ( Type = = " a " | | Type = = " A " )
{
// @see toAlphabeticOrNumeric in WebKit
static const char lower [ 26 ] = { ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' , ' g ' , ' h ' , ' i ' , ' j ' , ' k ' , ' l ' , ' m ' ,
' n ' , ' o ' , ' p ' , ' q ' , ' r ' , ' s ' , ' t ' , ' u ' , ' v ' , ' w ' , ' x ' , ' y ' , ' z ' } ;
static const char upper [ 26 ] = { ' A ' , ' B ' , ' C ' , ' D ' , ' E ' , ' F ' , ' G ' , ' H ' , ' I ' , ' J ' , ' K ' , ' L ' , ' M ' ,
' N ' , ' O ' , ' P ' , ' Q ' , ' R ' , ' S ' , ' T ' , ' U ' , ' V ' , ' W ' , ' X ' , ' Y ' , ' Z ' } ;
uint size = 26 ;
if ( number < 1 )
{
ret = toString ( number ) ;
}
else
{
const char * digits = ( Type = = " A " ? upper : lower ) ;
while ( number > 0 )
{
- - number ;
ret . insert ( ret . begin ( ) , digits [ number % size ] ) ;
number / = size ;
}
}
}
else if ( Type = = " i " | | Type = = " I " )
{
// @see toRoman in WebKit
static const char lower [ 7 ] = { ' i ' , ' v ' , ' x ' , ' l ' , ' c ' , ' d ' , ' m ' } ;
static const char upper [ 7 ] = { ' I ' , ' V ' , ' X ' , ' L ' , ' C ' , ' D ' , ' M ' } ;
if ( number < 1 | | number > 3999 )
{
ret = toString ( number ) ;
}
else
{
const char * digits = ( Type = = " I " ? upper : lower ) ;
uint8 i , d = 0 ;
do {
uint32 num = number % 10 ;
if ( num % 5 < 4 ) {
for ( i = num % 5 ; i > 0 ; i - - )
{
ret . insert ( ret . begin ( ) , digits [ d ] ) ;
}
}
if ( num > = 4 & & num < = 8 )
{
ret . insert ( ret . begin ( ) , digits [ d + 1 ] ) ;
}
if ( num = = 9 )
{
ret . insert ( ret . begin ( ) , digits [ d + 2 ] ) ;
}
if ( num % 5 = = 4 )
{
ret . insert ( ret . begin ( ) , digits [ d ] ) ;
}
number / = 10 ;
d + = 2 ;
} while ( number > 0 ) ;
if ( Type = = " I " )
{
ret = toUpper ( ret ) ;
}
}
}
else
{
ret = toString ( Value ) ;
}
return ret ;
}
2015-12-13 19:23:08 +00:00
}