(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");
+ #endif
+
+ // Clear all the context
+ clearContext();
+
+ _Browsing = false;
+
+ if (_Connecting)
+ {
+ nlassert (_ConnectingLock == this);
+ _ConnectingLock = NULL;
+ }
+ else
+ nlassert (_ConnectingLock != this);
+ _Connecting = false;
+
+ // Request running ?
+ if (_LibWWW->Request)
+ {
+ // VerifyLibWWW("HTRequest_kill", HTRequest_kill(_LibWWW->Request) == TRUE);
+ HTRequest_kill(_LibWWW->Request);
+ HTRequest_delete(_LibWWW->Request);
+ _LibWWW->Request = NULL;
+ }
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::updateCoords()
+ {
+ CGroupScrollText::updateCoords();
+ }
+
+ // ***************************************************************************
+
+ bool CGroupHTML::translateChar(ucchar &output, ucchar input, ucchar lastCharParam) const
+ {
+ // Keep this char ?
+ bool keep = true;
+
+ switch (input)
+ {
+ // Return / tab only in 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::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;
+
+ // 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()) &&
+ (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 TTmplParam;
+ vector 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::parser->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
+ if (buttonGroup)
+ {
+
+ // Add the ctrl button
+ CCtrlTextButton *ctrlButton = dynamic_cast(buttonGroup->getCtrl("button"));
+ if (!ctrlButton) ctrlButton = dynamic_cast(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->setUnderlined (true);
+ }
+ }
+ newLink->setText(tmpStr);
+ newLink->setColor(getTextColor());
+ newLink->setFontSize(getFontSize());
+ newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor));
+ newLink->setMultiLine(true);
+ newLink->setModulateGlobalColor(getGlobalColor());
+ // newLink->setLineAtBottom (true);
+
+ if (getA() && !newLink->Link.empty())
+ {
+ getParagraph()->addChildLink(newLink);
+ }
+ else
+ {
+ getParagraph()->addChild(newLink);
+ }
+ paragraphChange ();
+ }
+ }
+ }
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg)
+ {
+ // In a paragraph ?
+ if (_Paragraph)
+ {
+ string finalUrl;
+
+ //
+ // 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))
+ {
+ // No more text in this text view
+ _CurrentViewLink = NULL;
+
+ // Not added ?
+ CViewBitmap *newImage = new CViewBitmap (TCtorParam());
+ /* todo link in image
+ if (getA())
+ {
+ newImage->Link = getLink();
+ newImage->setHTMLView (this);
+ }*/
+ newImage->setRenderLayer(getRenderLayer()+1);
+ newImage->setTexture (finalUrl);
+ newImage->setModulateGlobalColor(globalColor);
+
+ /* todo link in image
+ if (getA())
+ getParagraph()->addChildLink(newImage);
+ else*/
+ getParagraph()->addChild(newImage);
+ paragraphChange ();
+ }
+ 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))
+ {
+ // No more text in this text view
+ _CurrentViewLink = NULL;
+
+ // Not added ?
+ CViewBitmap *newImage = new CViewBitmap (TCtorParam());
+ /* todo link in image
+ if (getA())
+ {
+ newImage->Link = getLink();
+ newImage->setHTMLView (this);
+ }*/
+
+ // 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();
+
+ newImage->setTexture (image);
+ // newImage->setTexture (finalUrl);
+ newImage->setModulateGlobalColor(globalColor);
+
+ /* todo link in image
+ if (getA())
+ getParagraph()->addChildLink(newImage);
+ else*/
+ getParagraph()->addChild(newImage);
+ paragraphChange ();
+ }
+ else
+ {
+
+ //
+ // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache
+ //
+ image = "web_del.tga";
+ if (lookupLocalFile (finalUrl, image.c_str(), false))
+ {
+ // No more text in this text view
+ _CurrentViewLink = NULL;
+
+ // Not added ?
+ CViewBitmap *newImage = new CViewBitmap (TCtorParam());
+ /* todo link in image
+ if (getA())
+ {
+ newImage->Link = getLink();
+ newImage->setHTMLView (this);
+ }*/
+ newImage->setTexture (image);
+ // newImage->setTexture (finalUrl);
+ newImage->setModulateGlobalColor(globalColor);
+
+ addImageDownload(img, newImage);
+
+ /* todo link in image
+ if (getA())
+ getParagraph()->addChildLink(newImage);
+ else*/
+ getParagraph()->addChild(newImage);
+ paragraphChange ();
+ }
+ }
+ }
+ }
+ }
+
+ // ***************************************************************************
+
+ CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content)
+ {
+ // In a paragraph ?
+ if (!_Paragraph)
+ {
+ newParagraph (0);
+ paragraphChange ();
+ }
+
+ // No more text in this text view
+ _CurrentViewLink = NULL;
+
+ {
+ // Not added ?
+ std::vector > templateParams;
+ templateParams.push_back (std::pair ("w", toString (cols*12)));
+ //templateParams.push_back (std::pair ("h", toString (rows*12)));
+ templateParams.push_back (std::pair ("id", name));
+ templateParams.push_back (std::pair ("prompt", ""));
+ templateParams.push_back (std::pair ("multiline", multiLine?"true":"false"));
+ templateParams.push_back (std::pair ("want_return", multiLine?"true":"false"));
+ templateParams.push_back (std::pair ("enter_recover_focus", "false"));
+ templateParams.push_back (std::pair ("max_num_chars", "1024"));
+ CInterfaceGroup *textArea = CWidgetManager::parser->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(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 > templateParams;
+ templateParams.push_back (std::pair ("id", name));
+ CInterfaceGroup *group = CWidgetManager::parser->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(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)
+ {
+ // 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);
+ }
+ }
+ }
+
+ 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(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 ();
+
+ return ctrlButton;
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::flushString()
+ {
+ _CurrentViewLink = NULL;
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::clearContext()
+ {
+ _Paragraph = NULL;
+ _PRE.clear();
+ _TextColor.clear();
+ _GlobalColor.clear();
+ _FontSize.clear();
+ _Indent = 0;
+ _LI = false;
+ _UL.clear();
+ _A.clear();
+ _Link.clear();
+ _LinkTitle.clear();
+ _Tables.clear();
+ _Cells.clear();
+ _TR.clear();
+ _Forms.clear();
+ _Groups.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(child);
+ _CurrentViewImage = dynamic_cast(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;
+ }
+
+ 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(group);
+
+ CInterfaceGroup *parentGroup = CGroupHTML::getCurrentGroup();
+ const std::vector &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(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(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 = strlwr(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 (strlwr(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:"+strlwr(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 *submitButtonName)
+ {
+ // Form id valid ?
+ if (formId < _Forms.size())
+ {
+ _PostNextTime = true;
+ _PostFormId = formId;
+ _PostFormSubmitButton = submitButtonName;
+ }
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::setBackgroundColor (const CRGBA &bgcolor)
+ {
+ // Should have a child named bg
+ CViewBase *view = getView (DefaultBackgroundBitmapView);
+ if (view)
+ {
+ CViewBitmap *bitmap = dynamic_cast (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 (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(ctrl);
+ if (textButt)
+ {
+ textButt->setFrozen(true);
+ }
+ }
+ };
+
+ static int timer_called = 0;
+
+ static int
+ timer_callback(HTTimer * const timer ,
+ void * const user_data ,
+ HTEventType const event )
+ {
+ /*----------------------------------------------------------------------------
+ A handy timer callback which cancels the running event loop.
+ -----------------------------------------------------------------------------*/
+ nlassert(event == HTEvent_TIMEOUT);
+ timer_called = 1;
+ HTEventList_stopLoop();
+
+ /* XXX - The meaning of this return value is undocumented, but close
+ ** inspection of libwww's source suggests that we want to return HT_OK. */
+ return HT_OK;
+ }
+
+ static void handleLibwwwEvents()
+ {
+ HTTimer *timer;
+ timer_called = 0;
+ timer = HTTimer_new(NULL, &timer_callback, NULL,
+ 1, YES, NO);
+ if (!timer_called)
+ HTEventList_newLoop();
+ HTTimer_delete(timer);
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::handle ()
+ {
+ H_AUTO(RZ_Interface_Html_handle)
+
+ const CWidgetManager::SInterfaceTimes × = CWidgetManager::getInstance()->getInterfaceTimes();
+
+ if (_Connecting)
+ {
+ nlassert (_ConnectingLock == this);
+
+ // Check timeout if needed
+ if (_TimeoutValue != 0 && _ConnectingTimeout <= ( times.thisFrameMs / 1000.0f ) )
+ {
+ browseError(("Connection timeout : "+_URL).c_str());
+ }
+ }
+ else
+ {
+ if (_ConnectingLock == NULL)
+ {
+ if (_BrowseNextTime)
+ {
+ // Stop browsing now
+ stopBrowse ();
+ updateRefreshButton();
+
+ // Home ?
+ if (_URL == "home")
+ _URL = home();
+
+ string finalUrl;
+ bool isLocal = lookupLocalFile (finalUrl, _URL.c_str(), true);
+
+ // Reset the title
+ if(_TitlePrefix.empty())
+ setTitle (CI18N::get("uiPleaseWait"));
+ else
+ setTitle (_TitlePrefix + " - " + CI18N::get("uiPleaseWait"));
+
+ // Start connecting
+ nlassert (_ConnectingLock == NULL);
+ _ConnectingLock = this;
+ _Connecting = true;
+ _ConnectingTimeout = ( times.thisFrameMs / 1000.0f ) + _TimeoutValue;
+
+
+ CButtonFreezer freezer;
+ this->visit(&freezer);
+
+ // Browsing
+ _Browsing = true;
+ updateRefreshButton();
+
+ // Save new url
+ _URL = finalUrl;
+
+ // display HTTP query
+ //nlinfo("WEB: GET '%s'", finalUrl.c_str());
+
+ // Init LibWWW
+ initLibWWW();
+ _TrustedDomain = isTrustedDomain(setCurrentDomain(finalUrl));
+
+ // Add custom get params
+ addHTTPGetParams (finalUrl, _TrustedDomain);
+
+
+ // Get the final URL
+ C3WSmartPtr uri = HTParse(finalUrl.c_str(), NULL, PARSE_ALL);
+
+ // Create an anchor
+ #ifdef NL_OS_WINDOWS
+ if ((_LibWWW->Anchor = HTAnchor_findAddress(uri)) == NULL)
+ #else
+ // temporarily disable local URL's until LibWWW can be replaced.
+ if (isLocal || ((_LibWWW->Anchor = HTAnchor_findAddress(uri)) == NULL))
+ #endif
+ {
+ browseError((string("The page address is malformed : ")+(const char*)uri).c_str());
+ }
+ else
+ {
+ /* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */
+ HTNet_addAfter(requestTerminater, NULL, (void*)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST);
+
+ /* Set the timeout for long we are going to wait for a response */
+ HTHost_setEventTimeout(60000);
+
+ /* Start the first request */
+
+ // request = Request_new(app);
+ _LibWWW->Request = HTRequest_new();
+ HTRequest_setContext(_LibWWW->Request, this);
+
+ // add supported language header
+ HTList *langs = HTList_new();
+ // set the language code used by the client
+ HTLanguage_add(langs, options.languageCode.c_str(), 1.0);
+ HTRequest_setLanguage (_LibWWW->Request, langs, 1);
+
+ // get_document(_LibWWW->Request, _LibWWW->Anchor);
+ C3WSmartPtr address = HTAnchor_address(_LibWWW->Anchor);
+ HTRequest_setAnchor(_LibWWW->Request, _LibWWW->Anchor);
+ if (HTLoad(_LibWWW->Request, NO))
+ {
+ }
+ else
+ {
+ browseError((string("The page cannot be displayed : ")+(const char*)uri).c_str());
+ }
+ }
+
+ _BrowseNextTime = false;
+ }
+
+ if (_PostNextTime)
+ {
+ /* Create a list to hold the form arguments */
+ HTAssocList * formfields = HTAssocList_new();
+
+ // Add text area text
+ uint i;
+
+ // Ref the form
+ CForm &form = _Forms[_PostFormId];
+
+ // Save new url
+ _URL = form.Action;
+
+ for (i=0; igetGroup ("eb");
+ if (group)
+ {
+ // Should be a CGroupEditBox
+ CGroupEditBox *editBox = dynamic_cast(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 = ucstring ("on");
+ 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)
+ {
+ // Build a utf8 string
+ string uft8 = form.Entries[i].Name + "=" + CI18N::encodeUTF8(entryData);
+
+ /* Parse the content and add it to the association list */
+ HTParseFormInput(formfields, uft8.c_str());
+ }
+ }
+
+ // Add the button coordinates
+ HTParseFormInput(formfields, (_PostFormSubmitButton + "_x=0").c_str());
+ HTParseFormInput(formfields, (_PostFormSubmitButton + "_y=0").c_str());
+
+ // Add custom params
+ addHTTPPostParams(formfields, _TrustedDomain);
+
+ // Reset the title
+ if(_TitlePrefix.empty())
+ setTitle (CI18N::get("uiPleaseWait"));
+ else
+ setTitle (_TitlePrefix + " - " + CI18N::get("uiPleaseWait"));
+
+ // Stop previous browse
+ stopBrowse ();
+
+ // Set timeout
+ nlassert (_ConnectingLock == NULL);
+ _ConnectingLock = this;
+ _Connecting = true;
+ _ConnectingTimeout = ( times.thisFrameMs / 1000.0f ) + _TimeoutValue;
+
+ CButtonFreezer freezer;
+ this->visit(&freezer);
+
+ // Browsing
+ _Browsing = true;
+ updateRefreshButton();
+
+ // display HTTP query with post parameters
+ //nlinfo("WEB: POST %s", _URL.c_str());
+
+ // Init LibWWW
+ initLibWWW();
+ _TrustedDomain = isTrustedDomain(setCurrentDomain(_URL));
+
+ // Get the final URL
+ C3WSmartPtr uri = HTParse(_URL.c_str(), NULL, PARSE_ALL);
+
+ // Create an anchor
+ if ((_LibWWW->Anchor = HTAnchor_findAddress(uri)) == NULL)
+ {
+ browseError((string("The page address is malformed : ")+(const char*)uri).c_str());
+ }
+ else
+ {
+ /* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */
+ HTNet_addAfter(requestTerminater, NULL, (void*)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST);
+
+ /* Start the first request */
+
+ // request = Request_new(app);
+ _LibWWW->Request = HTRequest_new();
+ HTRequest_setContext(_LibWWW->Request, this);
+
+ /*
+ ** Dream up a source anchor (an editor can for example use this).
+ ** After creation we associate the data that we want to post and
+ ** set some metadata about what the data is. More formats can be found
+ ** ../src/HTFormat.html
+ */
+ /*HTParentAnchor *src = HTTmpAnchor(NULL);
+ HTAnchor_setDocument(src, (void*)(data.c_str()));
+ HTAnchor_setFormat(src, WWW_PLAINTEXT);*/
+
+ /*
+ ** If not posting to an HTTP/1.1 server then content length MUST be
+ ** there. If HTTP/1.1 then it doesn't matter as we just use chunked
+ ** encoding under the covers
+ */
+ // HTAnchor_setLength(src, data.size());
+
+ HTParentAnchor *result = HTPostFormAnchor (formfields, _LibWWW->Anchor, _LibWWW->Request);
+ if (result)
+ {
+ }
+ else
+ {
+ browseError((string("The page cannot be displayed : ")+(const char*)uri).c_str());
+ }
+
+ /* POST the source to the dest */
+ /*
+ BOOL status = NO;
+ status = HTPostAnchor(src, _LibWWW->Anchor, _LibWWW->Request);
+ if (status)
+ {
+ }
+ else
+ {
+ browseError((string("The page cannot be displayed : ")+(const char*)uri).c_str());
+ }*/
+ }
+
+ _PostNextTime = false;
+ }
+ }
+ }
+ #ifndef NL_OS_WINDOWS
+ if(isBrowsing())
+ handleLibwwwEvents();
+ #endif
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::draw ()
+ {
+ checkDownloads();
+ CGroupScrollText::draw ();
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::endBuild ()
+ {
+ invalidateCoords();
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::addHTTPGetParams (string &/* url */, bool /*trustedDomain*/)
+ {
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::addHTTPPostParams (HTAssocList * /* formfields */, bool /*trustedDomain*/)
+ {
+ }
+
+ // ***************************************************************************
+
+ void CGroupHTML::requestTerminated(HTRequest * /* request */)
+ {
+ // 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);
+ }
+ }
+
+ // ***************************************************************************
+
+ 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();
+ _Paragraph = NULL;
+
+ // 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;iChildren.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 ¶ms, 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::parser->getProcedureNumActions(procName);
+ for(uint i=0;igetProcedureAction(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(CWidgetManager::getInstance()->getElementFromId(_BrowseUndoButton));
+ CCtrlBaseButton *butRedo= dynamic_cast(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(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 ¶m)
+ : CInterfaceGroup(param),
+ Offset(0)
+ {
+ }
+
+ // ***************************************************************************
+ 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(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.toNumber(1);
+ std::vector present;
+ std::vector 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().isNumber())
+ {
+ 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().toNumber();
+
+ present.insert(present.begin() + (uint)it.nextKey().toNumber(), 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().toNumber(), buffer);
+ }
+
+ beginElement(element_number, &present[0], &value[0]);
+ if (element_number == HTML_A)
+ addLink(element_number, 0, NULL, &present[0], &value[0]);
+
+ 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.toNumber(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= 4)
+ {
+ pos = i+1;
+
+ // unicode character
+ if (str[pos] == '#')
+ {
+ ++pos;
+
+ // using decimal by default
+ uint base = 10;
+
+ // using hexadecimal if
+ if (str[pos] == 'x')
+ {
+ base = 16;
+ ++pos;
+ }
+
+ // setup "last" to point at the first character following "?[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: "?[0-9a-f]+;"
+ if (last == pos || str[last] != ';')
+ {
+ result += str[i];
+ continue;
+ }
+
+ ucchar c = 0;
+
+ // convert digits to unicode character
+ while (pos'; continue; }
+ }
+
+ // all the special cases are catered for... treat this as a normal character
+ result += str[i];
+ }
+
+ return result;
+ }
+}
+
diff --git a/code/nel/src/gui/group_paragraph.cpp b/code/nel/src/gui/group_paragraph.cpp
new file mode 100644
index 000000000..1805b2d47
--- /dev/null
+++ b/code/nel/src/gui/group_paragraph.cpp
@@ -0,0 +1,1228 @@
+// Ryzom - MMORPG Framework
+// 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 .
+
+
+#include "nel/gui/group_paragraph.h"
+#include "nel/gui/group_html.h"
+#include "nel/gui/widget_manager.h"
+#include "nel/gui/interface_element.h"
+#include "nel/gui/view_pointer_base.h"
+#include "nel/gui/view_bitmap.h"
+#include "nel/gui/view_text_id.h"
+#include "nel/gui/group_container.h"
+#include "nel/misc/i_xml.h"
+#include "nel/misc/i18n.h"
+#include "nel/misc/xml_auto_ptr.h"
+
+using namespace std;
+using namespace NLMISC;
+
+NLMISC_REGISTER_OBJECT(CViewBase, CCtrlLink, std::string, "button_link");
+
+namespace NLGUI
+{
+
+ // ----------------------------------------------------------------------------
+ CGroupParagraph::CGroupParagraph(const TCtorParam ¶m)
+ : CInterfaceGroup(param),
+ _Templ(TCtorParam())
+ {
+ _IdCounter = 0;
+ _AddElt = Bottom;
+ _Align = Left;
+ _Space = 0;
+ _MinW= 0;
+ _MinH= 0;
+ _Over = false;
+ _OverColor = CRGBA(255,255,255,32);
+ _OverElt = -1;
+ _LastW = 0;
+ invalidateContent();
+ _TopSpace = 0;
+ _Indent = 0;
+ _FirstViewIndentView = false;
+ _BrowseGroup = NULL;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::addChild (CViewBase* child, bool deleteOnRemove)
+ {
+ if (!child)
+ {
+ nlwarning(" : tried to add a NULL view");
+ return;
+ }
+
+ // add child at last index
+ addChildAtIndex(child, (uint)_Elements.size(), deleteOnRemove);
+ if (_Elements.size() >= 2)
+ {
+ setOrder((uint)_Elements.size() - 1, getOrder((uint)_Elements.size() - 2) + 1);
+ }
+ invalidateContent();
+ }
+
+ // ----------------------------------------------------------------------------
+ CGroupParagraph::~CGroupParagraph()
+ {
+ deleteAllChildren();
+ }
+
+ // ----------------------------------------------------------------------------
+ // Set Hotspot of the first element in reference to the group
+ /*void CGroupParagraph::setHSGroup (CViewBase *child, EAlign addElt, EAlign align)
+ {
+ switch (addElt)
+ {
+ case Bottom:
+ if (align == Left)
+ {
+ child->_ParentPosRef = Hotspot_TL;
+ child->_PosRef = Hotspot_TL;
+ }
+ else // align == Right
+ {
+ child->_ParentPosRef = Hotspot_TR;
+ child->_PosRef = Hotspot_TR;
+ }
+ break;
+ case Left:
+ if (align == Top)
+ {
+ child->_ParentPosRef = Hotspot_TR;
+ child->_PosRef = Hotspot_TR;
+ }
+ else // align == Bottom
+ {
+ child->_ParentPosRef = Hotspot_BR;
+ child->_PosRef = Hotspot_BR;
+ }
+ break;
+ case Top:
+ if (align == Left)
+ {
+ child->_ParentPosRef = Hotspot_BL;
+ child->_PosRef = Hotspot_BL;
+ }
+ else // align == Right
+ {
+ child->_ParentPosRef = Hotspot_BR;
+ child->_PosRef = Hotspot_BR;
+ }
+ break;
+ case Right:
+ if (align == Top)
+ {
+ child->_ParentPosRef = Hotspot_TL;
+ child->_PosRef = Hotspot_TL;
+ }
+ else // align == Bottom
+ {
+ child->_ParentPosRef = Hotspot_BL;
+ child->_PosRef = Hotspot_BL;
+ }
+ break;
+ default:
+ nlassert(false);
+ break;
+ }
+ }*/
+
+ // ----------------------------------------------------------------------------
+ /** align an element towards its parent in the group
+ */
+ /*void CGroupParagraph::setHSParent(CViewBase *view, EAlign addElt, EAlign align, uint space)
+ {
+ if ((addElt == Top) || (addElt == Bottom))
+ {
+ if (addElt == Bottom)
+ {
+ if (_Align == Left)
+ view->_ParentPosRef = Hotspot_BL;
+ else // align == Right
+ view->_ParentPosRef = Hotspot_BR;
+ view->_Y = -abs(space);
+ }
+ else if (addElt == Top)
+ {
+ if (_Align == Left)
+ view->_ParentPosRef = Hotspot_TL;
+ else // align == Right
+ view->_ParentPosRef = Hotspot_TR;
+ view->_Y = abs(space);
+ }
+ }
+ else
+ {
+ if (addElt == Left)
+ {
+ if (_Align == Top)
+ view->_ParentPosRef = Hotspot_TL;
+ else // align == Bottom
+ view->_ParentPosRef = Hotspot_BL;
+ view->_X = -abs(space);
+ }
+ else if (addElt == Right)
+ {
+ if (_Align == Top)
+ view->_ParentPosRef = Hotspot_TR;
+ else // align == Bottom
+ view->_ParentPosRef = Hotspot_BR;
+ view->_X = abs(space);
+ }
+ }
+ }*/
+
+ // ----------------------------------------------------------------------------
+ bool CGroupParagraph::parse (xmlNodePtr cur, CInterfaceGroup * parentGroup)
+ {
+ if (!CInterfaceGroup::parse(cur,parentGroup))
+ return false;
+
+ // Parse location. If these properties are not specified, set them to 0
+
+ CXMLAutoPtr ptr((const char*) xmlGetProp( cur, (xmlChar*)"addelt" ));
+ _AddElt = Bottom;
+ if (ptr)
+ {
+ if (stricmp(ptr,"B") == 0)
+ _AddElt = Bottom;
+ else if (stricmp(ptr,"T") == 0)
+ _AddElt = Top;
+ else if (stricmp(ptr,"L") == 0)
+ _AddElt = Left;
+ else if (stricmp(ptr,"R") == 0)
+ _AddElt = Right;
+ }
+
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"align" );
+ _Align = Left;
+ if (ptr)
+ {
+ if (stricmp(ptr,"B") == 0)
+ _Align = Bottom;
+ else if (stricmp(ptr,"T") == 0)
+ _Align = Top;
+ else if (stricmp(ptr,"L") == 0)
+ _Align = Left;
+ else if (stricmp(ptr,"R") == 0)
+ _Align = Right;
+ }
+
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"space" );
+ _Space = 0;
+ if (ptr)
+ fromString((const char*)ptr, _Space);
+
+ EAlign addElt = _AddElt;
+ // EAlign align = _Align;
+ _GroupSizeRef = _SizeRef;
+ if ((addElt == Top) || (addElt == Bottom))
+ {
+ setMaxW (_W);
+ setMaxH(_H);
+ _H = 0;
+ _SizeRef = _SizeRef&(~2);
+ }
+ else
+ {
+ setMaxW (_W);
+ setMaxH (_H);
+ _W = 0;
+ _SizeRef = _SizeRef&(~1);
+ }
+
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"over" );
+ _Over = false;
+ if (ptr) _Over = convertBool(ptr);
+
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"col_over" );
+ _OverColor = CRGBA(255,255,255,32);
+ if (ptr) _OverColor = convertColor(ptr);
+
+
+ // TEMPLATE TEXT SETUP
+
+ // justification parameters
+ _Templ.parseTextOptions (cur);
+
+ // initial text
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"hardtext" );
+ if (ptr)
+ {
+ const char *propPtr = ptr;
+ ucstring Text = ucstring(propPtr);
+ if ((strlen(propPtr)>2) && (propPtr[0] == 'u') && (propPtr[1] == 'i'))
+ Text = CI18N::get (propPtr);
+
+ addTextChild(Text);
+ }
+ else
+ {
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"textid" );
+ if (ptr)
+ {
+ uint32 textId;
+ fromString((const char*)ptr, textId);
+ addTextChildID(textId);
+ }
+ }
+
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::addTextChild(const ucstring& line, bool multiLine /*= true*/)
+ {
+ const string elid = _Id + ":el" + toString(_IdCounter); ++_IdCounter;
+ CViewText *view= new CViewText (elid, string(""), _Templ.getFontSize(), _Templ.getColor(), _Templ.getShadow());
+ view->_Parent = this;
+ view->setMultiLine (multiLine);
+ view->setTextMode(_Templ.getTextMode());
+ if (multiLine) view->setMultiLineSpace (_Space);
+ view->setText (line);
+ // Herit global-coloring
+ view->setModulateGlobalColor(getModulateGlobalColor());
+ addChild (view);
+ invalidateCoords();
+ }
+
+
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::addTextChild(const ucstring& line, const CRGBA& textColor, bool multiLine /*= true*/)
+ {
+ const string elid = _Id + ":el" + toString(_IdCounter); ++_IdCounter;
+ CViewText *view= new CViewText (elid, string(""), _Templ.getFontSize(), _Templ.getColor(), _Templ.getShadow());
+ view->_Parent = this;
+ view->setMultiLine (multiLine);
+ if (multiLine) view->setMultiLineSpace (_Space);
+ view->setText (line);
+ view->setColor (textColor);
+ // Herit global-coloring
+ view->setModulateGlobalColor(getModulateGlobalColor());
+ addChild (view);
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::addTextChildID (uint32 nID, bool multiLine)
+ {
+ const string elid = _Id + ":el" + toString(_IdCounter); ++_IdCounter;
+ CViewTextID *view= new CViewTextID (elid, nID, _Templ.getFontSize(), _Templ.getColor(), _Templ.getShadow());
+ view->_Parent = this;
+ view->setMultiLine (multiLine);
+ if (multiLine) view->setMultiLineSpace (_Space);
+ // Herit global-coloring
+ view->setModulateGlobalColor(getModulateGlobalColor());
+ addChild (view);
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::addTextChildID(const std::string &dbPath,bool multiLine /*=true*/)
+ {
+ const string elid = _Id + ":el" + toString(_IdCounter); ++_IdCounter;
+ CViewTextID *view= new CViewTextID (elid, dbPath, _Templ.getFontSize(), _Templ.getColor(), _Templ.getShadow());
+ view->_Parent = this;
+ view->setMultiLine (multiLine);
+ if (multiLine) view->setMultiLineSpace (_Space);
+ // Herit global-coloring
+ view->setModulateGlobalColor(getModulateGlobalColor());
+ addChild (view);
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::delChild (CViewBase* childToDel)
+ {
+ // Look for child
+ uint posChildToDel = 0;
+ for (posChildToDel = 0; posChildToDel < _Elements.size(); ++posChildToDel)
+ {
+ CElementInfo rEI = _Elements[posChildToDel];
+ if (rEI.Element == childToDel)
+ break;
+ }
+
+ if (posChildToDel == _Elements.size())
+ {
+ nlwarning("Can't del child %s, it does not exist in the list", childToDel->getId().c_str());
+ return;
+ }
+ delChild(posChildToDel);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::delChild(uint posChildToDel)
+ {
+ if (posChildToDel >= (uint) _Elements.size())
+ {
+ nlwarning(" bad index");
+ return;
+ }
+
+ CViewBase* childToDel = _Elements[posChildToDel].Element;
+ bool ElementMustBeDeleted = _Elements[posChildToDel].EltDeleteOnRemove;
+ _Elements.erase (_Elements.begin()+posChildToDel);
+ // Remove from drawing
+ if (dynamic_cast(childToDel)) delGroup(static_cast(childToDel), !ElementMustBeDeleted);
+ else if (dynamic_cast(childToDel)) delCtrl(static_cast(childToDel), !ElementMustBeDeleted);
+ else delView(childToDel, !ElementMustBeDeleted);
+
+ // Bind the new first element
+ if (posChildToDel < _Elements.size())
+ {
+ CViewBase *pVB = _Elements[posChildToDel].Element;
+ if (posChildToDel == 0)
+ {
+ pVB->_ParentPos = NULL;
+ // setHSGroup (pVB, _AddElt, _Align);
+ if ((_AddElt == Top) || (_AddElt == Bottom))
+ pVB->setY (0);
+ else
+ pVB->setX (0);
+ }
+ else
+ pVB->_ParentPos = _Elements[posChildToDel-1].Element;
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ /*void CGroupParagraph::removeHead ()
+ {
+ if (_Elements.empty())
+ {
+ nlwarning(" Can't remove head, list is empty");
+ return;
+ }
+ delChild (_Elements.begin()->Element);*/
+ /*CViewBase *pVB = _Elements.begin()->Element;
+ if ((_AddElt == Top) || (_AddElt == Bottom))
+ {
+ sint32 shift = _H - (pVB->getH() + _Space);
+ _H = shift;
+ }
+ else
+ {
+ sint32 shift = _W - (pVB->getW() + _Space);
+ _W = shift;
+ }
+
+ bool FirstElementMustBeDeleted = _Elements.begin()->EltDeleteOnRemove;
+ if (FirstElementMustBeDeleted)
+ delete pVB;
+ _Elements.erase (_Elements.begin());
+ // Remove from drawing
+ for (vector::iterator itg = _ChildrenGroups.begin(); itg != _ChildrenGroups.end(); itg++)
+ if(*itg == pVB)
+ {
+ _ChildrenGroups.erase (itg);
+ break;
+ }
+ for (vector::iterator itc = _Controls.begin(); itc != _Controls.end(); itc++)
+ if(*itc == pVB)
+ {
+ _Controls.erase (itc);
+ break;
+ }
+ for (vector::iterator itv = _Views.begin(); itv != _Views.end(); itv++)
+ if(*itv == pVB)
+ {
+ _Views.erase (itv);
+ break;
+ }
+ delEltOrder (pVB);
+
+ // Bind the new first element
+ pVB = _Elements.begin()->Element;
+ pVB->_ParentPos = NULL;
+ setHSGroup (pVB, _AddElt, _Align);
+ if ((_AddElt == Top) || (_AddElt == Bottom))
+ pVB->setY (0);
+ else
+ pVB->setX (0);*/
+ //}
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::setTextTemplate(const CViewText& templ)
+ {
+ _Templ = templ;
+ }
+
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::updateCoords()
+ {
+ if (_Parent)
+ {
+ if (!_ContentValidated)
+ {
+ // Update W
+ CInterfaceElement::updateCoords();
+
+ // Current X and Y
+ sint32 x=_Indent;
+ sint32 y=-(sint32)_TopSpace;
+
+ // Current W
+ sint width = std::min(getMaxWReal(), getWReal());
+
+ // For each elements, place them
+ uint firstElementOnLine = 0;
+ const uint elmCount = (uint)_Elements.size();
+ uint i;
+ for (i = 0; i < elmCount+1; ++i)
+ {
+ // Force flush for the last element
+ bool changeLine = (i == elmCount);
+ uint lastLineElement = i+1;
+
+ // Not the end of the element
+ if (i < elmCount)
+ {
+ // Active element ?
+ if (_Elements[i].Element->getActive())
+ {
+ _Elements[i].Element->updateCoords();
+ // Is a view text ?
+ CViewText *viewText = dynamic_cast(_Elements[i].Element);
+ if (viewText)
+ {
+ viewText->setFirstLineX(x + ((i==0)?_FirstViewIndentView:0));
+ viewText->setX(0);
+ viewText->updateTextContext();
+ }
+ else
+ {
+ _Elements[i].Element->setX(x + ((i==0)?_FirstViewIndentView:0));
+ }
+ _Elements[i].Element->setPosRef(Hotspot_TL);
+ _Elements[i].Element->setParentPosRef(Hotspot_TL);
+
+ // Update coords for this element
+ _Elements[i].Element->updateCoords();
+
+ // Does we balance the last line height ?
+ if (viewText)
+ {
+ changeLine = viewText->getNumLine() > 1;
+ if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n')
+ {
+ changeLine = true;
+ }
+ }
+ else
+ {
+ // If this element is too big for the line, place it next time
+ if ((i!=firstElementOnLine) && ((_Elements[i].Element->getX() + _Elements[i].Element->getW()) > width))
+ {
+ lastLineElement--;
+ changeLine = true;
+ i--;
+ }
+ }
+
+
+ // New x coordinate
+ x = _Elements[i].Element->getX() + _Elements[i].Element->getWReal();
+ }
+ }
+ else
+ lastLineElement = i;
+
+ // Balance line height
+ if (changeLine)
+ {
+ // Eval line height
+ uint j;
+ uint lineHeight = 0;
+ uint multiLineHeight = 0;
+ uint legHeight = 0;
+ uint lastLineWidth = _Indent;
+
+ for (j=firstElementOnLine; j(_Elements[j].Element);
+
+ // Element height
+ if (viewTextOnLine)
+ {
+ // Height is just under the first line letter
+ newHeight = viewTextOnLine->getFontHeight() - viewTextOnLine->getFontLegHeight();
+
+ // Leg height for this view
+ legHeight = std::max(legHeight, viewTextOnLine->getFontLegHeight());
+
+ // Last element is a text multi line
+ if (j==(lastLineElement-1))
+ {
+ const uint numLine = viewTextOnLine->getNumLine();
+ if (numLine>1)
+ {
+ multiLineHeight = (numLine-2) * viewTextOnLine->getFontHeight() + (numLine-1) * viewTextOnLine->getMultiLineSpace();
+ lastLineWidth = _Indent + viewTextOnLine->getLastLineW ();
+ }
+ }
+ }
+ else
+ {
+ newHeight = _Elements[j].Element->getH();
+ CGroupHTMLInputOffset *inputOffset = dynamic_cast(_Elements[j].Element);
+ if (inputOffset && inputOffset->Offset < 0)
+ {
+ newHeight += inputOffset->Offset;
+ legHeight = max(-(inputOffset->Offset), sint32(legHeight));
+ }
+ }
+
+ if (lineHeight < newHeight)
+ lineHeight = newHeight;
+ }
+
+ // Repos element on the line
+ for (j=firstElementOnLine; j(_Elements[j].Element);
+
+ sint32 offsetY=0;
+ CGroupHTMLInputOffset *inputOffset = dynamic_cast(_Elements[j].Element);
+ if (inputOffset)
+ offsetY = inputOffset->Offset;
+ // Element height
+ if (viewTextOnLine)
+ newHeight = viewTextOnLine->getFontHeight() - viewTextOnLine->getFontLegHeight() - offsetY;
+ else
+ newHeight = _Elements[j].Element->getH();
+
+ sint32 posY = y-lineHeight+newHeight+offsetY;
+ _Elements[j].Element->setY(posY);
+ }
+
+ if (i < elmCount)
+ {
+ nlassert(lastLineElement>0);
+ nlassert(lastLineElement-1getNumLine());
+
+ // Number of line..
+ uint j;
+ for (j=0; j<3; j++)
+ {
+ if (jsetId(getId()+":"+"links"+toString(i)+"-"+toString(j));
+ ctrl->setParent (this);
+ ctrl->setParentSize (this);
+ ctrl->setParentPos (this);
+ ctrl->setParentPosRef (Hotspot_TL);
+ ctrl->setPosRef (Hotspot_TL);
+ ctrl->setActive(true);
+ if (_BrowseGroup)
+ {
+ ctrl->setActionOnLeftClick("browse");
+ ctrl->setParamsOnLeftClick("name="+_BrowseGroup->getId()+"|url="+link.Link->Link);
+ }
+ ctrl->setScale(true);
+ addCtrl(ctrl);
+ }
+
+ // Pos the links
+ int x, y, width, height;
+ int fontSize = link.Link->getFontHeight();
+ int fontLineSpace = link.Link->getMultiLineSpace();
+
+ // X
+ x = (j == 0) ? link.Link->getFirstLineX() : link.Link->getX();
+
+ // Y
+ if (j < 2)
+ y = link.Link->getY() - (fontSize+fontLineSpace) * j;
+ else
+ y = link.Link->getY() - ((fontSize+fontLineSpace) * (link.Link->getNumLine()-1));
+
+ // Width
+
+ // Last line ?
+ if (j == (links-1))
+ width = link.Link->getLastLineW ();
+ else
+ {
+ width = link.Link->getW();
+
+ // First line ?
+ if (j == 0)
+ width -= (link.Link->getFirstLineX() - link.Link->getX());
+ }
+
+ if ((j == 1) && (links==3))
+ height = (fontSize+fontLineSpace)*(link.Link->getNumLine()-2);
+ else
+ height = fontSize;
+
+ ctrl->setX(x);
+ ctrl->setY(y);
+ ctrl->setW(width);
+ ctrl->setH(height);
+ }
+ else
+ {
+ if (link.CtrlLink[j])
+ {
+ delCtrl (link.CtrlLink[j]);
+ link.CtrlLink[j] = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ CInterfaceGroup::updateCoords();
+
+ // Validated
+ _ContentValidated = true;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::checkCoords ()
+ {
+ if (_Parent != NULL)
+ {
+ sint parentWidth = std::min(_Parent->getMaxWReal(), _Parent->getWReal());
+ if (_LastW != (sint) parentWidth)
+ {
+ CCtrlBase *pCB = CWidgetManager::getInstance()->getCapturePointerLeft();
+ if (pCB != NULL)
+ {
+ CCtrlResizer *pCR = dynamic_cast(pCB);
+ if (pCR != NULL)
+ {
+ // We are resizing !!!!
+ }
+ else
+ {
+ _LastW = parentWidth;
+ invalidateContent();
+ }
+ }
+ else
+ {
+ _LastW = parentWidth;
+ invalidateContent();
+ }
+ }
+ }
+ CInterfaceGroup::checkCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::draw ()
+ {
+ // TEMP TEMP
+ //CViewRenderer &rVR = *CViewRenderer::getInstance();
+ //rVR.drawRotFlipBitmap _RenderLayer, (_XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(0,255,0,255) );
+ if (_Over)
+ {
+ CViewRenderer &rVR = *CViewRenderer::getInstance();
+
+ if (CWidgetManager::getInstance()->getModalWindow() == NULL)
+ {
+ sint32 x = CWidgetManager::getInstance()->getPointer()->getX();
+ sint32 y = CWidgetManager::getInstance()->getPointer()->getY();
+
+ CInterfaceGroup *pIG = CWidgetManager::getInstance()->getWindowUnder(x,y);
+ CInterfaceGroup *pParent = this;
+ bool bFound = false;
+ while (pParent != NULL)
+ {
+ if (pParent == pIG)
+ {
+ bFound = true;
+ break;
+ }
+ pParent = pParent->getParent();
+ }
+
+ sint32 clipx,clipy,clipw,cliph;
+ getClip(clipx,clipy,clipw,cliph);
+ if ((x < clipx) ||
+ (x > (clipx + clipw)) ||
+ (y < clipy) ||
+ (y > (clipy + cliph)) || !bFound)
+ {
+ _OverElt = -1;
+ }
+ else
+ {
+ for (uint32 i = 0; i < _Elements.size(); ++i)
+ if (_Elements[i].Element->getActive())
+ {
+ CViewBase *pVB = _Elements[i].Element;
+ if ((x >= pVB->getXReal()) &&
+ (x < (pVB->getXReal() + pVB->getWReal()))&&
+ (y >= pVB->getYReal()) &&
+ (y < (pVB->getYReal() + pVB->getHReal())))
+ {
+ _OverElt = i;
+ }
+ }
+ }
+ }
+
+ if (_OverElt != -1)
+ {
+ CViewBase *pVB = _Elements[_OverElt].Element;
+ CRGBA col = _OverColor;
+ if(getModulateGlobalColor())
+ {
+ col.modulateFromColor (_OverColor, CWidgetManager::getInstance()->getGlobalColorForContent());
+ }
+ else
+ {
+ col= _OverColor;
+ col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
+ }
+ rVR.drawRotFlipBitmap (_RenderLayer, pVB->getXReal(), pVB->getYReal(),
+ pVB->getWReal(), pVB->getHReal(), 0, false, rVR.getBlankTextureId(),
+ col );
+
+ }
+ }
+
+ CInterfaceGroup::draw ();
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupParagraph::handleEvent (const NLGUI::CEventDescriptor& event)
+ {
+ if (!_Active)
+ return false;
+
+ bool bReturn = CInterfaceGroup::handleEvent(event);
+
+ if (event.getType() == NLGUI::CEventDescriptor::mouse)
+ {
+ const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
+
+ _OverElt = -1;
+ if (!isIn(eventDesc.getX(), eventDesc.getY()))
+ return false;
+
+ for (uint32 i = 0; i < _Elements.size(); ++i)
+ if (_Elements[i].Element->getActive())
+ {
+ CViewBase *pVB = _Elements[i].Element;
+ if ((eventDesc.getX() >= pVB->getXReal()) &&
+ (eventDesc.getX() < (pVB->getXReal() + pVB->getWReal()))&&
+ (eventDesc.getY() >= pVB->getYReal()) &&
+ (eventDesc.getY() < (pVB->getYReal() + pVB->getHReal())))
+ {
+ _OverElt = i;
+ }
+ }
+ }
+
+ return bReturn;
+ }
+
+
+
+ // predicate to remove a view from the list of element
+ struct CRemoveViewPred
+ {
+ bool operator()(const CGroupParagraph::CElementInfo &info) const { return dynamic_cast(info.Element) != NULL; }
+ };
+
+ // predicate to remove a ctrl from the list of element
+ struct CRemoveCtrlPred
+ {
+ bool operator()(const CGroupParagraph::CElementInfo &info) const { return dynamic_cast(info.Element) != NULL; }
+ };
+
+ // predicate to remove a group from the list of element
+ struct CRemoveGroupPred
+ {
+ bool operator()(const CGroupParagraph::CElementInfo &info) const { return dynamic_cast(info.Element) != NULL; }
+ };
+
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::clearViews()
+ {
+ _IdCounter = 0;
+ // remove views from the list of elements
+ _Elements.erase(std::remove_if(_Elements.begin(), _Elements.end(), CRemoveViewPred()), _Elements.end());
+ CInterfaceGroup::clearViews();
+ updateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::clearControls()
+ {
+ _IdCounter = 0;
+ // remove views from the list of elements
+ _Elements.erase(std::remove_if(_Elements.begin(), _Elements.end(), CRemoveCtrlPred()), _Elements.end());
+ CInterfaceGroup::clearControls();
+ updateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::clearGroups()
+ {
+ _IdCounter = 0;
+ // remove views from the list of elements
+ _Elements.erase(std::remove_if(_Elements.begin(), _Elements.end(), CRemoveGroupPred()), _Elements.end());
+ CInterfaceGroup::clearGroups();
+ updateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::forceSizeW (sint32 newSizeW)
+ {
+ _W = newSizeW;
+ for (uint32 i = 0; i < _Elements.size(); ++i)
+ {
+ _Elements[i].Element->setW (_W);
+ _Elements[i].Element->CInterfaceElement::updateCoords();
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::forceSizeH (sint32 newSizeH)
+ {
+ _H = newSizeH;
+ for (uint32 i = 0; i < _Elements.size(); ++i)
+ {
+ _Elements[i].Element->setH (_H);
+ _Elements[i].Element->CInterfaceElement::updateCoords();
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::setMinW(sint32 minW)
+ {
+ _MinW= minW;
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::setMinH(sint32 minH)
+ {
+ _MinH= minH;
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupParagraph::addChildAtIndex(CViewBase *child, uint index, bool deleteOnRemove /*=true*/)
+ {
+ if (!child)
+ {
+ nlwarning(" : tried to add a NULL view");
+ return false;
+ }
+ if (index > _Elements.size())
+ {
+ return false;
+ }
+ child->_Parent = this;
+ child->_ParentPos = NULL;
+ child->_Active = true;
+ child->_X = 0;
+ child->_Y = 0;
+ child->_RenderLayer = this->_RenderLayer;
+ // Can't have sizeref on the coordinate corresponding to alignement
+ switch(_AddElt)
+ {
+ case Top:
+ case Bottom:
+ child->_SizeRef &= 1; // sizeref on w is permitted
+ break;
+ case Left:
+ case Right:
+ child->_SizeRef &= 2; // sizeref on h is permitted
+ break;
+ default:
+ nlwarning(" bad align");
+ child->_SizeRef = 0;
+ break;
+ }
+
+ child->_SizeDivW = 10;
+ child->_SizeDivH = 10;
+
+ // Position the element according to the list alignement
+ // setHSGroup (child, _AddElt, _Align);
+
+ // update coords of the element (it may use child_resize_h or w)
+ //child->updateCoords();
+ child->invalidateCoords();
+
+ // Update size
+ if ((_AddElt == Top) || (_AddElt == Bottom))
+ {
+ // update the list size
+ sint32 newH = _H + child->getH();
+ if (_Elements.size() > 0)
+ newH += _Space;
+ _H = newH;
+
+ if ((_SizeRef&1) == 0) // No parent size reference in W
+ {
+ sint32 newW = max (_W, child->getW());
+ _W = newW;
+ }
+ }
+ else
+ {
+ // Update the list coords
+ sint32 newW = _W + child->getW();
+ if (_Elements.size() > 0)
+ newW += _Space;
+ _W = newW;
+
+ if ((_SizeRef&2) == 0) // No parent size reference in H
+ {
+ sint32 newH = max (_H, child->getH());
+ _H = newH;
+ }
+ }
+
+ CElementInfo ei;
+ ei.Element = child;
+ ei.EltDeleteOnRemove = deleteOnRemove;
+ ei.Order = 0;
+
+ if (index != 0)
+ {
+ // update alignement
+ // setHSParent(child, _AddElt, _Align, _Space);
+ // child->_ParentPos = _Elements[index - 1].Element;
+ }
+ _Elements.insert(_Elements.begin() + index, ei);
+ // link next element to this one
+ if (index < _Elements.size() - 1)
+ {
+ // _Elements[index + 1].Element->_ParentPos = child;
+ // setHSParent(_Elements[index + 1].Element, _AddElt, _Align, _Space);
+ }
+
+ // Add this element for drawing
+ {
+ CInterfaceGroup *pIG = dynamic_cast(child);
+ if (pIG != NULL)
+ {
+ addGroup (pIG, (sint) index);
+ return true;
+ }
+ CCtrlBase *pCB = dynamic_cast(child);
+ if (pCB != NULL)
+ {
+ addCtrl (pCB, (sint) index);
+ return true;
+ }
+ CViewBase *pVB = dynamic_cast(child);
+ if (pVB != NULL)
+ {
+ addView (pVB, (sint) index);
+ return true;
+ }
+ nlstop;
+ return false;
+ }
+ return false;
+ }
+
+ // ----------------------------------------------------------------------------
+ sint32 CGroupParagraph::getElementIndex(CViewBase* child) const
+ {
+ for(uint k = 0; k < _Elements.size(); ++k)
+ {
+ if (_Elements[k].Element == child) return k;
+ }
+ return -1;
+ }
+
+ // ----------------------------------------------------------------------------
+ /*void CGroupParagraph::swapChildren(uint index1, uint index2)
+ {
+ if (index1 >= _Elements.size()
+ || index2 >= _Elements.size())
+ {
+ nlwarning(" bad indexes");
+ return;
+ }
+ // prevent elements from being deleted
+ bool oldMustDelete1 = _Elements[index1].EltDeleteOnRemove;
+ bool oldMustDelete2 = _Elements[index2].EltDeleteOnRemove;
+
+ uint order1 = _Elements[index1].Order;
+ uint order2 = _Elements[index2].Order;
+
+ _Elements[index1].EltDeleteOnRemove = false;
+ _Elements[index2].EltDeleteOnRemove = false;
+
+ CViewBase *v1 = _Elements[index1].Element;
+ CViewBase *v2 = _Elements[index2].Element;
+
+
+ if (index1 < index2)
+ {
+ delChild(index2);
+ delChild(index1);
+ addChildAtIndex(v2, index1, oldMustDelete2);
+ setOrder(index1, order2);
+ addChildAtIndex(v1, index2, oldMustDelete1);
+ setOrder(index2, order1);
+ }
+ else
+ {
+ delChild(index1);
+ delChild(index2);
+ addChildAtIndex(v1, index2, oldMustDelete1);
+ setOrder(index2, order1);
+ addChildAtIndex(v2, index1, oldMustDelete2);
+ setOrder(index1, order2);
+ }
+ }*/
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::deleteAllChildren()
+ {
+ uint numChildren = getNbElement();
+ for(uint k = 0; k < numChildren; ++k)
+ {
+ delChild(numChildren - 1 - k); // delete in reverse order to avoid unnecessary vector copies
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ uint CGroupParagraph::getNumActiveChildren() const
+ {
+ uint numChildren = 0;
+ for(uint k = 0; k < _Elements.size(); ++k)
+ {
+ if (_Elements[k].Element->getActive()) ++numChildren;
+ }
+ return numChildren;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::setDelOnRemove(uint index, bool delOnRemove)
+ {
+ if (index >= _Elements.size())
+ {
+ nlwarning("bad index");
+ return;
+ }
+ _Elements[index].EltDeleteOnRemove = delOnRemove;
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupParagraph::getDelOnRemove(uint index) const
+ {
+ if (index >= _Elements.size())
+ {
+ nlwarning("bad index");
+ return false;
+ }
+ return _Elements[index].EltDeleteOnRemove;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::addChildLink (CViewLink* child, bool deleteOnRemove)
+ {
+ // Add the child
+ addChild (child, deleteOnRemove);
+
+ // Add the link
+ _Links.push_back (CLink(child));
+ }
+
+ // ----------------------------------------------------------------------------
+ CGroupParagraph::CLink::CLink (CViewLink *link)
+ {
+ Link = link;
+ CtrlLink[0] = NULL;
+ CtrlLink[1] = NULL;
+ CtrlLink[2] = NULL;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupParagraph::onInvalidateContent()
+ {
+ _ContentValidated = false;
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ sint32 CGroupParagraph::getMaxUsedW() const
+ {
+ // The paragraph max is the sum of the components max
+ sint maxWidth = 0;
+ for (uint k = 0; k < _Elements.size(); ++k)
+ {
+ // Get the child width
+ maxWidth += _Elements[k].Element->getMaxUsedW();
+ }
+ return maxWidth;
+ }
+
+ // ----------------------------------------------------------------------------
+ sint32 CGroupParagraph::getMinUsedW() const
+ {
+ // The paragraph min is the max of the components min
+ sint32 minWidth = 0;
+ for (uint k = 0; k < _Elements.size(); ++k)
+ {
+ // Get the child width
+ sint32 width = _Elements[k].Element->getMinUsedW();
+ if (width > minWidth)
+ minWidth = width;
+ }
+ return minWidth;
+ }
+
+}
+
diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp
new file mode 100644
index 000000000..fa996ac13
--- /dev/null
+++ b/code/nel/src/gui/libwww.cpp
@@ -0,0 +1,712 @@
+// Ryzom - MMORPG Framework
+// 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 .
+
+#define NOMINMAX
+
+// LibWWW
+extern "C"
+{
+#include "WWWLib.h" /* Global Library Include file */
+#include "WWWApp.h"
+#include "WWWInit.h"
+}
+
+#include "nel/gui/group_html.h"
+#include "nel/gui/libwww_nel_stream.h"
+
+using namespace NLMISC;
+
+// The HText structure for libwww
+struct _HText
+{
+ NLGUI::CGroupHTML *Parent;
+};
+
+namespace NLGUI
+{
+
+ /// the cookie value for session identification (nel cookie)
+ std::string CurrentCookie;
+
+ /// store all cookies we receive and resent them depending of the domain
+ std::map > HTTPCookies;
+ std::string HTTPCurrentDomain; // The current domain that will be used to get which cookies to send
+
+ // ***************************************************************************
+
+ // Some DTD table
+
+ // Here, modify the DTD table to change the HTML parser (add new tags for examples)
+
+ #undef HTML_ATTR
+ #define HTML_ATTR(a,b) { (char*) #b }
+
+ HTAttr a_attr[] =
+ {
+ HTML_ATTR(A,ACCESSKEY),
+ HTML_ATTR(A,CHARSET),
+ HTML_ATTR(A,CLASS),
+ HTML_ATTR(A,COORDS),
+ HTML_ATTR(A,DIR),
+ HTML_ATTR(A,HREF),
+ HTML_ATTR(A,HREFLANG),
+ HTML_ATTR(A,ID),
+ HTML_ATTR(A,NAME),
+ HTML_ATTR(A,REL),
+ HTML_ATTR(A,REV),
+ HTML_ATTR(A,SHAPE),
+ HTML_ATTR(A,STYLE),
+ HTML_ATTR(A,TABINDEX),
+ HTML_ATTR(A,TARGET),
+ HTML_ATTR(A,TYPE),
+ HTML_ATTR(A,TITLE),
+ HTML_ATTR(A,Z_ACTION_CATEGORY),
+ HTML_ATTR(A,Z_ACTION_PARAMS),
+ HTML_ATTR(A,Z_ACTION_SHORTCUT),
+ { 0 }
+ };
+
+ HTAttr table_attr[] =
+ {
+ HTML_ATTR(TABLE,ALIGN),
+ HTML_ATTR(TABLE,BGCOLOR),
+ HTML_ATTR(TABLE,BORDER),
+ HTML_ATTR(TABLE,CELLPADDING),
+ HTML_ATTR(TABLE,CELLSPACING),
+ HTML_ATTR(TABLE,CLASS),
+ HTML_ATTR(TABLE,DIR),
+ HTML_ATTR(TABLE,FRAME),
+ HTML_ATTR(TABLE,ID),
+ HTML_ATTR(TABLE,L_MARGIN),
+ HTML_ATTR(TABLE,LANG),
+ HTML_ATTR(TABLE,NOWRAP),
+ HTML_ATTR(TABLE,RULES),
+ HTML_ATTR(TABLE,SUMMARY),
+ HTML_ATTR(TABLE,STYLE),
+ HTML_ATTR(TABLE,TITLE),
+ HTML_ATTR(TABLE,VALIGN),
+ HTML_ATTR(TABLE,WIDTH),
+ { 0 }
+ };
+
+ HTAttr tr_attr[] =
+ {
+ HTML_ATTR(TR,ALIGN),
+ HTML_ATTR(TR,BGCOLOR),
+ HTML_ATTR(TR,L_MARGIN),
+ HTML_ATTR(TR,NOWRAP),
+ HTML_ATTR(TR,VALIGN),
+ { 0 }
+ };
+
+ HTAttr td_attr[] =
+ {
+ HTML_ATTR(TD,ABBR),
+ HTML_ATTR(TD,ALIGN),
+ HTML_ATTR(TD,AXIS),
+ HTML_ATTR(TD,BGCOLOR),
+ HTML_ATTR(TD,CHAR),
+ HTML_ATTR(TD,CHAROFF),
+ HTML_ATTR(TD,CLASS),
+ HTML_ATTR(TD,COLSPAN),
+ HTML_ATTR(TD,DIR),
+ HTML_ATTR(TD,ID),
+ HTML_ATTR(TD,HEADERS),
+ HTML_ATTR(TD,HEIGHT),
+ HTML_ATTR(TD,L_MARGIN),
+ HTML_ATTR(TD,LANG),
+ HTML_ATTR(TD,NOWRAP),
+ HTML_ATTR(TD,ROWSPAN),
+ HTML_ATTR(TD,SCOPE),
+ HTML_ATTR(TD,STYLE),
+ HTML_ATTR(TD,TITLE),
+ HTML_ATTR(TD,VALIGN),
+ HTML_ATTR(TD,WIDTH),
+ { 0 }
+ };
+
+ HTAttr img_attr[] =
+ {
+ HTML_ATTR(IMG,ALIGN),
+ HTML_ATTR(IMG,ALT),
+ HTML_ATTR(IMG,BORDER),
+ HTML_ATTR(IMG,CLASS),
+ HTML_ATTR(IMG,DIR),
+ HTML_ATTR(IMG,GLOBAL_COLOR),
+ HTML_ATTR(IMG,HEIGHT),
+ HTML_ATTR(IMG,HSPACE),
+ HTML_ATTR(IMG,ID),
+ HTML_ATTR(IMG,ISMAP),
+ HTML_ATTR(IMG,LANG),
+ HTML_ATTR(IMG,LONGDESC),
+ HTML_ATTR(IMG,SRC),
+ HTML_ATTR(IMG,STYLE),
+ HTML_ATTR(IMG,TITLE),
+ HTML_ATTR(IMG,USEMAP),
+ HTML_ATTR(IMG,VSPACE),
+ HTML_ATTR(IMG,WIDTH),
+ { 0 }
+ };
+
+ HTAttr input_attr[] =
+ {
+ HTML_ATTR(INPUT,ACCEPT),
+ HTML_ATTR(INPUT,ACCESSKEY),
+ HTML_ATTR(INPUT,ALIGN),
+ HTML_ATTR(INPUT,ALT),
+ HTML_ATTR(INPUT,CHECKED),
+ HTML_ATTR(INPUT,CLASS),
+ HTML_ATTR(INPUT,DIR),
+ HTML_ATTR(INPUT,DISABLED),
+ HTML_ATTR(INPUT,GLOBAL_COLOR),
+ HTML_ATTR(INPUT,ID),
+ HTML_ATTR(INPUT,LANG),
+ HTML_ATTR(INPUT,MAXLENGTH),
+ HTML_ATTR(INPUT,NAME),
+ HTML_ATTR(INPUT,READONLY),
+ HTML_ATTR(INPUT,SIZE),
+ HTML_ATTR(INPUT,SRC),
+ HTML_ATTR(INPUT,STYLE),
+ HTML_ATTR(INPUT,TABINDEX),
+ HTML_ATTR(INPUT,TITLE),
+ HTML_ATTR(INPUT,TYPE),
+ HTML_ATTR(INPUT,USEMAP),
+ HTML_ATTR(INPUT,VALUE),
+ HTML_ATTR(INPUT,Z_BTN_TMPL),
+ HTML_ATTR(INPUT,Z_INPUT_TMPL),
+ HTML_ATTR(INPUT,Z_INPUT_WIDTH),
+ { 0 }
+ };
+
+ HTAttr textarea_attr[] =
+ {
+ HTML_ATTR(TEXTAREA,CLASS),
+ HTML_ATTR(TEXTAREA,COLS),
+ HTML_ATTR(TEXTAREA,DIR),
+ HTML_ATTR(TEXTAREA,DISABLED),
+ HTML_ATTR(TEXTAREA,ID),
+ HTML_ATTR(TEXTAREA,LANG),
+ HTML_ATTR(TEXTAREA,NAME),
+ HTML_ATTR(TEXTAREA,READONLY),
+ HTML_ATTR(TEXTAREA,ROWS),
+ HTML_ATTR(TEXTAREA,STYLE),
+ HTML_ATTR(TEXTAREA,TABINDEX),
+ HTML_ATTR(TEXTAREA,TITLE),
+ HTML_ATTR(TEXTAREA,Z_INPUT_TMPL),
+ { 0 }
+ };
+
+
+ HTAttr p_attr[] =
+ {
+ HTML_ATTR(P,QUICK_HELP_CONDITION),
+ HTML_ATTR(P,QUICK_HELP_EVENTS),
+ HTML_ATTR(P,QUICK_HELP_LINK),
+ HTML_ATTR(P,NAME),
+ { 0 }
+ };
+
+
+ HTAttr div_attr[] =
+ {
+ HTML_ATTR(DIV,CLASS),
+ HTML_ATTR(DIV,ID),
+ HTML_ATTR(DIV,NAME),
+ HTML_ATTR(DIV,STYLE),
+ { 0 }
+ };
+
+ // ***************************************************************************
+
+ void _VerifyLibWWW(const char *function, bool ok, const char *file, int line)
+ {
+ if (!ok)
+ nlwarning("%s(%d) : LIBWWW %s returned a bad status", file, line, function);
+ }
+ #define VerifyLibWWW(a,b) _VerifyLibWWW(a,(b)!=FALSE,__FILE__,__LINE__)
+
+ // ***************************************************************************
+
+ int NelPrinter (const char * fmt, va_list pArgs)
+ {
+ char info[1024];
+ int ret;
+
+ ret = vsnprintf(info, sizeof(info), fmt, pArgs);
+ nlinfo("%s", info);
+ return ret;
+ }
+
+ // ***************************************************************************
+
+ int NelTracer (const char * fmt, va_list pArgs)
+ {
+ char err[1024];
+ int ret;
+
+ ret = vsnprintf(err, sizeof(err), fmt, pArgs);
+ nlwarning ("%s", err);
+ return ret;
+ }
+
+ // ***************************************************************************
+
+ HText * TextNew (HTRequest * request,
+ HTParentAnchor * /* anchor */,
+ HTStream * /* output_stream */)
+ {
+ HText *text = new HText;
+ text->Parent = (CGroupHTML *) HTRequest_context(request);
+ return text;
+ }
+
+ // ***************************************************************************
+
+ BOOL TextDelete (HText * me)
+ {
+ delete me;
+ return YES;
+ }
+
+ // ***************************************************************************
+
+ void TextBuild (HText * me, HTextStatus status)
+ {
+ // Do the work in the class
+ if (status == HTEXT_BEGIN)
+ me->Parent->beginBuild ();
+ else if (status == HTEXT_END)
+ me->Parent->endBuild ();
+ }
+
+ // ***************************************************************************
+
+ void TextAdd (HText * me, const char * buf, int len)
+ {
+ // Do the work in the class
+ me->Parent->addText (buf, len);
+ }
+
+ // ***************************************************************************
+
+ void TextLink (HText * me,
+ int element_number,
+ int attribute_number,
+ HTChildAnchor * anchor,
+ const BOOL * present,
+ const char ** value)
+ {
+ // Do the work in the class
+ me->Parent->addLink (element_number, attribute_number, anchor, present, value);
+ }
+
+ // ***************************************************************************
+
+ // Read a width HTML parameter. "100" or "100%". Returns true if percent (0 ~ 1) else false
+ bool getPercentage (sint32 &width, float &percent, const char *str)
+ {
+ // Percent ?
+ const char *percentChar;
+ if ((percentChar = strchr (str, '%')) != NULL)
+ {
+ std::string toto = str;
+ toto = toto.substr (0, percentChar - str);
+ fromString(toto, percent);
+ percent /= 100.f;
+ return true;
+ }
+ else
+ {
+ fromString(str, width);
+ return false;
+ }
+ }
+
+ // ***************************************************************************
+
+ CRGBA getColor (const char *color)
+ {
+ if (strlen (color) != 7 && strlen (color) != 9 )
+ return CRGBA::White;
+ char tmp[3] = {0,0,0};
+ CRGBA dst;
+ int value;
+ tmp[0] = color[1];
+ tmp[1] = color[2];
+ sscanf (tmp, "%x", &value);
+ dst.R = uint8(value);
+ tmp[0] = color[3];
+ tmp[1] = color[4];
+ sscanf (tmp, "%x", &value);
+ dst.G = uint8(value);
+ tmp[0] = color[5];
+ tmp[1] = color[6];
+ sscanf (tmp, "%x", &value);
+ dst.B = uint8(value);
+ if (strlen (color) == 9)
+ {
+ tmp[0] = color[7];
+ tmp[1] = color[8];
+ sscanf (tmp, "%x", &value);
+ dst.A = uint8(value);
+ }
+ else
+ {
+ // extension to html ; try to parse an additional alpha
+ dst.A = 255;
+ }
+ return dst;
+ }
+
+ // ***************************************************************************
+
+ void TextBeginElement (HText *me, int element_number, const BOOL *present, const char **value)
+ {
+ // Do the work in the class
+ me->Parent->beginElement (element_number, present, value);
+ }
+
+ // ***************************************************************************
+
+ void TextEndElement (HText *me, int element_number)
+ {
+ // Do the work in the class
+ me->Parent->endElement (element_number);
+ }
+
+ // ***************************************************************************
+ void TextBeginUnparsedElement(HText *me, const char *buffer, int length)
+ {
+ me->Parent->beginUnparsedElement(buffer, length);
+ }
+
+ // ***************************************************************************
+ void TextEndUnparsedElement(HText *me, const char *buffer, int length)
+ {
+ me->Parent->endUnparsedElement(buffer, length);
+ }
+
+ // ***************************************************************************
+ void TextUnparsedEntity (HText * /* HText */, const char *buffer, int length)
+ {
+ std::string str(buffer, buffer+length);
+ nlinfo("Unparsed entity '%s'", str.c_str());
+ }
+
+ // ***************************************************************************
+ int requestTerminater (HTRequest * request, HTResponse * /* response */,
+ void * param, int /* status */)
+ {
+ /*
+ Yoyo and Boris: we had to make the request terminate by UID and not by pointer (param is an uid).
+ Because this method was called at mainLoop time, but for GroupHTML created/deleted at login time !!!
+ => Memory Crash.
+ */
+
+ // TestYoyo
+ //nlinfo("** requestTerminater(): uid%d", (uint32)param);
+
+ // the parameter is actually an uint32
+ if (param != 0)
+ {
+ CGroupHTML::TGroupHtmlByUIDMap::iterator it= CGroupHTML::_GroupHtmlByUID.find((uint32)(size_t)param);
+ if(it!=CGroupHTML::_GroupHtmlByUID.end())
+ {
+ // get the pointer. NB: the refptr should not be NULL
+ // since object removed from map when deleted
+ CGroupHTML *gh = it->second;
+ nlassert(gh);
+
+ // callback the browser
+ gh->requestTerminated(request);
+ }
+ }
+ return HT_OK;
+ }
+
+
+ // callback called when receiving a cookie
+ BOOL receiveCookie (HTRequest * /* request */, HTCookie * cookie, void * /* param */)
+ {
+ if (strcmp(HTCookie_name(cookie), "ryzomId") == 0)
+ {
+ // we receive the ryzom id cookie, store it
+ CurrentCookie = HTCookie_value(cookie);
+ }
+ else
+ {
+ // store the id/value cookie
+ HTTPCookies[HTTPCurrentDomain][HTCookie_name(cookie)] = HTCookie_value(cookie);
+ // nlwarning("get cookie for domain %s %s=%s", HTTPCurrentDomain.c_str(), HTCookie_name(cookie), HTCookie_value(cookie));
+ }
+
+ return YES;
+ }
+
+ // callback called to add cookie to a request before sending it to the server
+ HTAssocList *sendCookie (HTRequest * /* request */, void * /* param */)
+ {
+ HTAssocList * alist = 0;
+ if (!CurrentCookie.empty())
+ {
+ if(alist == 0) alist = HTAssocList_new(); /* Is deleted by the cookie module */
+ HTAssocList_addObject(alist, "ryzomId", CurrentCookie.c_str());
+ }
+
+ if(!HTTPCookies[HTTPCurrentDomain].empty())
+ {
+ if(alist == 0) alist = HTAssocList_new();
+ for(std::map::iterator it = HTTPCookies[HTTPCurrentDomain].begin(); it != HTTPCookies[HTTPCurrentDomain].end(); it++)
+ {
+ HTAssocList_addObject(alist, it->first.c_str(), it->second.c_str());
+ // nlwarning("set cookie for domain '%s' %s=%s", HTTPCurrentDomain.c_str(), it->first.c_str(), it->second.c_str());
+ }
+ }
+ return alist;
+ }
+
+
+ // ***************************************************************************
+
+ HTAnchor * TextFindAnchor (HText * /* me */, int /* index */)
+ {
+ return NULL;
+ }
+
+ int HTMIME_location_custom (HTRequest * request, HTResponse * response, char * token, char * value)
+ {
+ char * location = HTStrip(value);
+
+ std::string finalLocation;
+
+ //nlinfo("redirect to '%s' '%s'", value, location);
+
+ // If not absolute URI (Error) then find the base
+ if (!HTURL_isAbsolute(location))
+ {
+ char * base = HTAnchor_address((HTAnchor *) HTRequest_anchor(request));
+ location = HTParse(location, base, PARSE_ALL);
+ //redirection = HTAnchor_findAddress(location);
+ finalLocation = location;
+ HT_FREE(base);
+ HT_FREE(location);
+ }
+ else
+ {
+ finalLocation = location;
+ }
+ //nlinfo("final location '%s'", finalLocation.c_str());
+
+ CGroupHTML *gh = (CGroupHTML *) HTRequest_context(request);
+
+ gh->setURL(finalLocation);
+
+ return HT_OK;
+ }
+
+
+ // ***************************************************************************
+
+ const std::string &setCurrentDomain(const std::string &url)
+ {
+ if(url.find("http://") == 0)
+ {
+ HTTPCurrentDomain = url.substr(7, url.find('/', 7)-7);
+ // nlinfo("****cd: %s", HTTPCurrentDomain.c_str());
+ }
+ else
+ {
+ HTTPCurrentDomain.clear();
+ // nlinfo("****cd: clear the domain");
+ }
+ return HTTPCurrentDomain;
+ }
+
+
+ void initLibWWW()
+ {
+ static bool initialized = false;
+ if (!initialized)
+ {
+ //HTProfile_newNoCacheClient("Ryzom", "1.1");
+
+ /* Need our own trace and print functions */
+ HTPrint_setCallback(NelPrinter);
+ HTTrace_setCallback(NelTracer);
+
+ /* Initiate libwww */
+
+ HTLib_setAppName( CGroupHTML::options.appName.c_str() );
+ HTLib_setAppVersion( CGroupHTML::options.appVersion.c_str() );
+
+ /* Set up TCP as transport */
+ VerifyLibWWW("HTTransport_add", HTTransport_add("buffered_tcp", HT_TP_SINGLE, HTReader_new, HTBufferWriter_new));
+ VerifyLibWWW("HTTransport_add", HTTransport_add("local", HT_TP_SINGLE, HTNeLReader_new, HTWriter_new));
+ // VerifyLibWWW("HTTransport_add", HTTransport_add("local", HT_TP_SINGLE, HTANSIReader_new, HTWriter_new));
+ // VerifyLibWWW("HTTransport_add", HTTransport_add("local", HT_TP_SINGLE, HTReader_new, HTWriter_new));
+
+ /* Set up HTTP as protocol */
+ VerifyLibWWW("HTProtocol_add", HTProtocol_add("http", "buffered_tcp", 80, NO, HTLoadHTTP, NULL));
+ VerifyLibWWW("HTProtocol_add", HTProtocol_add("file", "local", 0, YES, HTLoadNeLFile, NULL));
+ //VerifyLibWWW("HTProtocol_add", HTProtocol_add("file", "local", 0, YES, HTLoadFile, NULL));
+ // HTProtocol_add("cache", "local", 0, NO, HTLoadCache, NULL);
+
+ HTBind_init();
+ // HTCacheInit(NULL, 20);
+
+ /* Setup up transfer coders */
+ HTFormat_addTransferCoding((char*)"chunked", HTChunkedEncoder, HTChunkedDecoder, 1.0);
+
+ /* Setup MIME stream converters */
+ HTFormat_addConversion("message/rfc822", "*/*", HTMIMEConvert, 1.0, 0.0, 0.0);
+ HTFormat_addConversion("message/x-rfc822-foot", "*/*", HTMIMEFooter, 1.0, 0.0, 0.0);
+ HTFormat_addConversion("message/x-rfc822-head", "*/*", HTMIMEHeader, 1.0, 0.0, 0.0);
+ HTFormat_addConversion("message/x-rfc822-cont", "*/*", HTMIMEContinue, 1.0, 0.0, 0.0);
+ HTFormat_addConversion("message/x-rfc822-partial","*/*", HTMIMEPartial, 1.0, 0.0, 0.0);
+ HTFormat_addConversion("multipart/*", "*/*", HTBoundary, 1.0, 0.0, 0.0);
+
+ /* Setup HTTP protocol stream */
+ HTFormat_addConversion("text/x-http", "*/*", HTTPStatus_new, 1.0, 0.0, 0.0);
+
+ /* Setup the HTML parser */
+ HTFormat_addConversion("text/html", "www/present", HTMLPresent, 1.0, 0.0, 0.0);
+
+ /* Setup black hole stream */
+ HTFormat_addConversion("*/*", "www/debug", HTBlackHoleConverter, 1.0, 0.0, 0.0);
+ HTFormat_addConversion("*/*", "www/present", HTBlackHoleConverter, 0.3, 0.0, 0.0);
+
+ /* Set max number of sockets we want open simultaneously */
+ HTNet_setMaxSocket(32);
+
+ /* Register our HTML parser callbacks */
+ VerifyLibWWW("HText_registerCDCallback", HText_registerCDCallback (TextNew, TextDelete));
+ VerifyLibWWW("HText_registerBuildCallback", HText_registerBuildCallback (TextBuild));
+ VerifyLibWWW("HText_registerTextCallback", HText_registerTextCallback(TextAdd));
+ VerifyLibWWW("HText_registerLinkCallback", HText_registerLinkCallback (TextLink));
+ VerifyLibWWW("HText_registerElementCallback", HText_registerElementCallback (TextBeginElement, TextEndElement));
+ VerifyLibWWW("HText_registerUnparsedElementCallback", HText_registerUnparsedElementCallback(TextBeginUnparsedElement, TextEndUnparsedElement));
+ VerifyLibWWW("HText_registerUnparsedEntityCallback ", HText_registerUnparsedEntityCallback (TextUnparsedEntity ));
+
+
+ /* Register the default set of MIME header parsers */
+ struct {
+ const char * string;
+ HTParserCallback * pHandler;
+ } fixedHandlers[] = {
+ {"accept", &HTMIME_accept},
+ {"accept-charset", &HTMIME_acceptCharset},
+ {"accept-encoding", &HTMIME_acceptEncoding},
+ {"accept-language", &HTMIME_acceptLanguage},
+ {"accept-ranges", &HTMIME_acceptRanges},
+ {"authorization", NULL},
+ {"cache-control", &HTMIME_cacheControl},
+ {"connection", &HTMIME_connection},
+ {"content-encoding", &HTMIME_contentEncoding},
+ {"content-length", &HTMIME_contentLength},
+ {"content-range", &HTMIME_contentRange},
+ {"content-transfer-encoding", &HTMIME_contentTransferEncoding},
+ {"content-type", &HTMIME_contentType},
+ {"digest-MessageDigest", &HTMIME_messageDigest},
+ {"keep-alive", &HTMIME_keepAlive},
+ {"link", &HTMIME_link},
+ {"location", &HTMIME_location_custom},
+ {"max-forwards", &HTMIME_maxForwards},
+ {"mime-version", NULL},
+ {"pragma", &HTMIME_pragma},
+ {"protocol", &HTMIME_protocol},
+ {"protocol-info", &HTMIME_protocolInfo},
+ {"protocol-request", &HTMIME_protocolRequest},
+ {"proxy-authenticate", &HTMIME_authenticate},
+ {"proxy-authorization", &HTMIME_proxyAuthorization},
+ {"public", &HTMIME_public},
+ {"range", &HTMIME_range},
+ {"referer", &HTMIME_referer},
+ {"retry-after", &HTMIME_retryAfter},
+ {"server", &HTMIME_server},
+ {"trailer", &HTMIME_trailer},
+ {"transfer-encoding", &HTMIME_transferEncoding},
+ {"upgrade", &HTMIME_upgrade},
+ {"user-agent", &HTMIME_userAgent},
+ {"vary", &HTMIME_vary},
+ {"via", &HTMIME_via},
+ {"warning", &HTMIME_warning},
+ {"www-authenticate", &HTMIME_authenticate},
+ {"authentication-info", &HTMIME_authenticationInfo},
+ {"proxy-authentication-info", &HTMIME_proxyAuthenticationInfo}
+ };
+
+ for (uint i = 0; i < sizeof(fixedHandlers)/sizeof(fixedHandlers[0]); i++)
+ HTHeader_addParser(fixedHandlers[i].string, NO, fixedHandlers[i].pHandler);
+
+ /* Set up default event loop */
+ HTEventInit();
+
+ /* Add our own request terminate handler */
+ HTNet_addAfter(requestTerminater, NULL, 0, HT_ALL, HT_FILTER_LAST);
+
+ /* Setup cookies */
+ HTCookie_init();
+ HTCookie_setCookieMode(HTCookieMode(HT_COOKIE_ACCEPT | HT_COOKIE_SEND));
+ HTCookie_setCallbacks(receiveCookie, NULL, sendCookie, NULL);
+
+ /* Start the first request */
+
+ /* Go into the event loop... */
+ // HTEventList_newLoop();
+
+ // App_delete(app);
+
+ HTBind_add("htm", "text/html", NULL, "8bit", NULL, 1.0); /* HTML */
+ HTBind_add("html", "text/html", NULL, "8bit", NULL, 1.0); /* HTML */
+
+ HTBind_caseSensitive(NO);
+
+ // Change the HTML DTD
+ SGML_dtd *HTML_DTD = HTML_dtd ();
+ HTML_DTD->tags[HTML_TABLE].attributes = table_attr;
+ HTML_DTD->tags[HTML_TABLE].number_of_attributes = sizeof(table_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_TR].attributes = tr_attr;
+ HTML_DTD->tags[HTML_TR].number_of_attributes = sizeof(tr_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_TD].attributes = td_attr;
+ HTML_DTD->tags[HTML_TD].number_of_attributes = sizeof(td_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_IMG].attributes = img_attr;
+ HTML_DTD->tags[HTML_IMG].number_of_attributes = sizeof(img_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_INPUT].attributes = input_attr;
+ HTML_DTD->tags[HTML_INPUT].number_of_attributes = sizeof(input_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_TEXTAREA].attributes = textarea_attr;
+ HTML_DTD->tags[HTML_TEXTAREA].number_of_attributes = sizeof(textarea_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_P].attributes = p_attr;
+ HTML_DTD->tags[HTML_P].number_of_attributes = sizeof(p_attr) / sizeof(HTAttr) - 1;
+ HTML_DTD->tags[HTML_A].attributes = a_attr;
+ HTML_DTD->tags[HTML_A].number_of_attributes = sizeof(a_attr) / sizeof(HTAttr) - 1;
+ //HTML_DTD->tags[HTML_I].attributes = a_attr;
+ HTML_DTD->tags[HTML_I].number_of_attributes = 0;
+ HTML_DTD->tags[HTML_DIV].attributes = div_attr;
+ HTML_DTD->tags[HTML_DIV].number_of_attributes = sizeof(div_attr) / sizeof(HTAttr) - 1;
+
+ // Set a request timeout
+ // HTHost_setEventTimeout (30000);
+ // HTHost_setActiveTimeout (30000);
+ // HTHost_setPersistTimeout (30000);
+
+ // Initialized
+ initialized = true;
+ }
+ }
+
+ // ***************************************************************************
+}
+
diff --git a/code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp b/code/nel/src/gui/libwww_nel_stream.cpp
similarity index 95%
rename from code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp
rename to code/nel/src/gui/libwww_nel_stream.cpp
index 9a05ee607..ca79ccde2 100644
--- a/code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp
+++ b/code/nel/src/gui/libwww_nel_stream.cpp
@@ -31,7 +31,7 @@ extern "C"
#include "HTMulti.h"
#include "HTNetMan.h"
#include "HTChannl.h"
-#include "libwww_nel_stream.h" /* Implemented here */
+#include "nel/gui/libwww_nel_stream.h" /* Implemented here */
}
using namespace std;
diff --git a/code/ryzom/client/src/interface_v3/view_link.cpp b/code/nel/src/gui/view_link.cpp
similarity index 53%
rename from code/ryzom/client/src/interface_v3/view_link.cpp
rename to code/nel/src/gui/view_link.cpp
index efe760567..db0df6618 100644
--- a/code/ryzom/client/src/interface_v3/view_link.cpp
+++ b/code/nel/src/gui/view_link.cpp
@@ -16,45 +16,48 @@
#include "nel/misc/bit_mem_stream.h"
#include "nel/misc/i18n.h"
-#include "view_link.h"
+#include "nel/gui/view_link.h"
using namespace std;
using namespace NLMISC;
using namespace NL3D;
-// ***************************************************************************
-
-CViewLink::CViewLink (const TCtorParam ¶m)
-: CViewText(param)
+namespace NLGUI
{
- HTML = NULL;
-}
-// ***************************************************************************
+ // ***************************************************************************
-void CViewLink::setHTMLView(CGroupHTML *html)
-{
- HTML = html;
-}
-
-// ***************************************************************************
-bool CViewLink::getMouseOverShape(string &texName, uint8 &rot, CRGBA &col)
-{
- if (HTML != NULL)
+ CViewLink::CViewLink (const TCtorParam ¶m)
+ : CViewText(param)
{
- if (!LinkTitle.empty())
- {
- texName = LinkTitle;
- rot= 0;
- col = CRGBA::White;
- return true;
- }
+ HTML = NULL;
}
-
- return false;
+
+ // ***************************************************************************
+
+ void CViewLink::setHTMLView(CGroupHTML *html)
+ {
+ HTML = html;
+ }
+
+ // ***************************************************************************
+ bool CViewLink::getMouseOverShape(string &texName, uint8 &rot, CRGBA &col)
+ {
+ if (HTML != NULL)
+ {
+ if (!LinkTitle.empty())
+ {
+ texName = LinkTitle;
+ rot= 0;
+ col = CRGBA::White;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ // ***************************************************************************
}
-
-// ***************************************************************************
-
-
diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
index f07dbb018..fc7b6d6d9 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
@@ -31,7 +31,7 @@
#include "../net_manager.h"
#include "nel/gui/group_menu.h"
#include "../global.h"
-#include "group_html.h"
+#include "nel/gui/group_html.h"
//
#include "game_share/inventories.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_ui.cpp b/code/ryzom/client/src/interface_v3/action_handler_ui.cpp
index 1fcc35684..837ba4d3f 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_ui.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_ui.cpp
@@ -28,7 +28,7 @@
#include "chat_window.h"
#include "people_interraction.h"
#include "nel/gui/group_editbox.h"
-#include "group_html.h"
+#include "nel/gui/group_html.h"
#include "inventory_manager.h"
// Client Game
diff --git a/code/ryzom/client/src/interface_v3/group_html.cpp b/code/ryzom/client/src/interface_v3/group_html.cpp
deleted file mode 100644
index b1bfdfe80..000000000
--- a/code/ryzom/client/src/interface_v3/group_html.cpp
+++ /dev/null
@@ -1,3914 +0,0 @@
-// Ryzom - MMORPG Framework
-// 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 .
-
-//#include
-
-// LibWWW
-extern "C"
-{
-#include "WWWLib.h" /* Global Library Include file */
-#include "WWWApp.h"
-#include "WWWInit.h"
-}
-
-#include "../libwww.h"
-#include "group_html.h"
-#include "nel/gui/group_list.h"
-#include "nel/gui/group_container.h"
-#include "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 "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"
-
-using namespace std;
-using namespace NLMISC;
-
-
-// Default timeout to connect a server
-#define DEFAULT_RYZOM_CONNECTION_TIMEOUT (10.0)
-
-// Uncomment to see the log about image download
-//#define LOG_DL 1
-
-CGroupHTML *CGroupHTML::_ConnectingLock = NULL;
-CGroupHTML::SWebOptions CGroupHTML::options;
-
-
-// Check if domain is on TrustedDomain
-bool CGroupHTML::isTrustedDomain(const string &domain)
-{
- vector::iterator it;
- it = find ( options.trustedDomains.begin(), options.trustedDomains.end(), domain);
- return it != options.trustedDomains.end();
-}
-
-void CGroupHTML::setImage(CViewBase * view, const string &file)
-{
- CCtrlButton *btn = dynamic_cast(view);
- if(btn)
- {
- btn->setTexture (file);
- btn->setTexturePushed(file);
- btn->invalidateCoords();
- btn->invalidateContent();
- btn->resetInvalidCoords();
- btn->updateCoords();
- paragraphChange();
- }
- else
- {
- CViewBitmap *btm = dynamic_cast(view);
- if(btm)
- {
- btm->setTexture (file);
- btm->invalidateCoords();
- btm->invalidateContent();
- btm->resetInvalidCoords();
- btm->updateCoords();
- paragraphChange();
- }
- else
- {
- CGroupCell *btgc = dynamic_cast(view);
- if(btgc)
- {
- btgc->setTexture (file);
- btgc->invalidateCoords();
- btgc->invalidateContent();
- btgc->resetInvalidCoords();
- btgc->updateCoords();
- paragraphChange();
- }
- }
- }
-}
-
-// 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)
-{
- // 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' img %p", url.c_str(), img);
-#endif
- Curls[i].imgs.push_back(img);
- return;
- }
- }
-
- CURL *curl = curl_easy_init();
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
-
- string dest = localImageName(url);
- string tmpdest = localImageName(url)+".tmp";
-#ifdef LOG_DL
- nlwarning("add to download '%s' dest '%s' img %p", url.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))
- {
-
- FILE *fp = fopen (tmpdest.c_str(), "wb");
- if (fp == NULL)
- {
- nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno));
- return;
- }
- curl_easy_setopt(curl, CURLOPT_FILE, fp);
-
- curl_multi_add_handle(MultiCurl, curl);
- Curls.push_back(CDataDownload(curl, url, fp, ImgType, img, "", ""));
- #ifdef LOG_DL
- nlwarning("adding handle %x, %d curls", curl, Curls.size());
- #endif
- RunningCurls++;
- }
- else
- {
- setImage(img, dest);
- }
-}
-
-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")
- {
- CURL *curl = curl_easy_init();
- if (!MultiCurl || !curl)
- return false;
-
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
-
- FILE *fp = fopen (tmpdest.c_str(), "wb");
- if (fp == NULL)
- {
- nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno));
- return false;
- }
- curl_easy_setopt(curl, CURLOPT_FILE, fp);
-
- curl_multi_add_handle(MultiCurl, curl);
- Curls.push_back(CDataDownload(curl, url, 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(RunningCurls == 0)
- 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)))
- {
- if (msg->msg == CURLMSG_DONE)
- {
- for (vector::iterator it=Curls.begin(); iteasy_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("transfer %x completed with status res %d r %d - %d curls", msg->easy_handle, res, r, Curls.size());
-#endif
- curl_easy_cleanup(it->curl);
-
- string file;
-
- if (it->type == ImgType)
- file = localImageName(it->url);
- else
- file = localBnpName(it->url);
-
- if(res != CURLE_OK || r < 200 || r >= 300 || ((it->md5sum != "") && (it->md5sum != getMD5(file+".tmp").toString())))
- {
- NLMISC::CFile::deleteFile((file+".tmp").c_str());
- }
- else
- {
- string finalUrl;
- if (it->type == ImgType)
- {
- CFile::moveFile(file.c_str(), (file+".tmp").c_str());
- if (lookupLocalFile (finalUrl, file.c_str(), false))
- {
- for(uint i = 0; i < it->imgs.size(); i++)
- {
- // don't display image that are not power of 2
- //uint32 w, h;
- //CBitmap::loadSize (file, w, h);
- //if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures()))
- // file.clear();
- setImage(it->imgs[i], file);
- }
- }
- }
- else
- {
- CFile::moveFile(file.c_str(), (file+".tmp").c_str());
- if (lookupLocalFile (finalUrl, file.c_str(), false))
- {
- CLuaManager::getInstance().executeLuaScript( it->luaScript, true );
- }
- }
- }
- Curls.erase(it);
- break;
- }
- }
- }
- }
- }
- RunningCurls = NewRunningCurls;
-}
-
-
-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 ¶m)
- : 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 void popIfNotEmpty(A &vect) { if(!vect.empty()) vect.pop_back(); }
-
-// Data stored in CGroupHTML for libwww.
-
-class CLibWWWData
-{
-public:
- CLibWWWData ()
- {
- Request = NULL;
- Anchor = NULL;
- }
- HTRequest *Request;
- HTAnchor *Anchor;
-};
-
-// ***************************************************************************
-
-void CGroupHTML::beginBuild ()
-{
- if (_Browsing)
- {
- nlassert (_Connecting);
- nlassert (_ConnectingLock == this);
- _Connecting = false;
- _ConnectingLock = NULL;
-
- removeContent ();
- }
-}
-
-
-TStyle CGroupHTML::parseStyle (const string &str_styles)
-{
- TStyle styles;
- vector elements;
- NLMISC::splitString(str_styles, ";", elements);
-
- for(uint i = 0; i < elements.size(); ++i)
- {
- vector 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])] = 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= '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 BOOL *present, const char **value)
-{
- if (_Browsing)
- {
- // Paragraph ?
- switch(element_number)
- {
- case HTML_A:
- _TextColor.push_back(LinkColor);
- _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:
- {
- 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 TTmplParam;
- vector 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::parser->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 = strlwr(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])
- {
- HTParentAnchor *parent = HTAnchor_parent (_LibWWW->Anchor);
- HTChildAnchor *child = HTAnchor_findChildAndLink (parent, "", value[HTML_FORM_ACTION], NULL);
- if (child)
- {
- HTAnchor *mainChild = HTAnchor_followMainLink((HTAnchor *) child);
- if (mainChild)
- {
- C3WSmartPtr uri = HTAnchor_address(mainChild);
- form.Action = (const char*)uri;
- }
- }
- else
- {
- HTAnchor * dest = HTAnchor_findAddress (value[HTML_FORM_ACTION]);
- if (dest)
- {
- C3WSmartPtr uri = HTAnchor_address(dest);
- form.Action = (const char*)uri;
- }
- else
- {
- form.Action = value[HTML_FORM_ACTION];
- }
- }
- }
- _Forms.push_back(form);
- }
- break;
- case HTML_H1:
- newParagraph(PBeginSpace);
- _FontSize.push_back(H1FontSize);
- _TextColor.push_back(H1Color);
- _GlobalColor.push_back(H1ColorGlobalColor);
- break;
- case HTML_H2:
- newParagraph(PBeginSpace);
- _FontSize.push_back(H2FontSize);
- _TextColor.push_back(H2Color);
- _GlobalColor.push_back(H2ColorGlobalColor);
- break;
- case HTML_H3:
- newParagraph(PBeginSpace);
- _FontSize.push_back(H3FontSize);
- _TextColor.push_back(H3Color);
- _GlobalColor.push_back(H3ColorGlobalColor);
- break;
- case HTML_H4:
- newParagraph(PBeginSpace);
- _FontSize.push_back(H4FontSize);
- _TextColor.push_back(H4Color);
- _GlobalColor.push_back(H4ColorGlobalColor);
- break;
- case HTML_H5:
- newParagraph(PBeginSpace);
- _FontSize.push_back(H5FontSize);
- _TextColor.push_back(H5Color);
- _GlobalColor.push_back(H5ColorGlobalColor);
- break;
- case 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])
- {
- // 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);
- }
- else
- {
- // Get the option to reload (class==reload)
- bool reloadImg = false;
-
- string style;
- if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
- style = value[MY_HTML_IMG_STYLE];
-
- if (!style.empty())
- {
- TStyle styles = parseStyle(style);
- TStyle::iterator it;
-
- it = styles.find("reload");
- if (it != styles.end() && (*it).second == "1")
- reloadImg = true;
- }
-
- addImage (value[MY_HTML_IMG_SRC], globalColor, reloadImg);
- }
- }
- }
- 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 = value[MY_HTML_INPUT_TYPE];
- type = strlwr (type);
- if (type == "image")
- {
- // 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;
-
- // Add the ctrl button
- addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
- globalColor, "html_submit_form", param.c_str(), tooltip);
- }
- 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;
-
- // Add the ctrl button
- if (!_Paragraph)
- {
- newParagraph (0);
- paragraphChange ();
- }
-
- typedef pair TTmplParam;
- vector 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::parser->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
- if (buttonGroup)
- {
-
- // Add the ctrl button
- CCtrlTextButton *ctrlButton = dynamic_cast(buttonGroup->getCtrl("button"));
- if (!ctrlButton) ctrlButton = dynamic_cast(buttonGroup->getCtrl("b"));
- if (ctrlButton)
- {
- ctrlButton->setModulateGlobalColorAll (globalColor);
-
- // Translate the tooltip
- if (tooltip)
- ctrlButton->setDefaultContextHelp (CI18N::get (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;
- 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]);
-
- string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup);
- // Add the editbox
- CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue);
- 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")
- {
- // The submit button
- string name;
- string normal = DefaultCheckBoxBitmapNormal;
- string pushed = DefaultCheckBoxBitmapPushed;
- string over = DefaultCheckBoxBitmapOver;
- bool checked = false;
- 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];
- checked = (present[MY_HTML_INPUT_CHECKED] && value[MY_HTML_INPUT_CHECKED]);
-
- // Add the ctrl button
- CCtrlButton *checkbox = addButton (CCtrlButton::ToggleButton, name, normal, pushed, over,
- globalColor, "", "", tooltip);
- if (checkbox)
- {
- checkbox->setPushed (checked);
-
- // Add the text area to the form
- CGroupHTML::CForm::CEntry entry;
- entry.Name = name;
- 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
-
- // read general property
- string templateName;
- string minWidth;
-
- // Widget template name
- 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];
-
- string name;
- if (present[HTML_SELECT_NAME] && value[HTML_SELECT_NAME])
- name = value[HTML_SELECT_NAME];
-
- string formTemplate = templateName.empty() ? DefaultFormSelectGroup : templateName;
- CDBGroupComboBox *cb = addComboBox(formTemplate, 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);
- }
- break;
- case HTML_P:
- newParagraph(PBeginSpace);
- break;
- case HTML_PRE:
- _PRE.push_back(true);
- break;
- case 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_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 = strlwr(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);
- }
- }
- }
- _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;
-
- 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 = "";
- if (present[HTML_TEXTAREA_NAME] && value[HTML_TEXTAREA_NAME])
- _TextAreaName = value[HTML_TEXTAREA_NAME];
- if (present[HTML_TEXTAREA_ROWS] && value[HTML_TEXTAREA_ROWS])
- fromString(value[HTML_TEXTAREA_ROWS], _TextAreaRow);
- if (present[HTML_TEXTAREA_COLS] && value[HTML_TEXTAREA_COLS])
- fromString(value[HTML_TEXTAREA_COLS], _TextAreaCols);
-
- _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_STYLE:
- _IgnoreText = true;
- break;
- }
- }
-}
-
-// ***************************************************************************
-
-void CGroupHTML::endElement (uint element_number)
-{
- if (_Browsing)
- {
- // Paragraph ?
- switch(element_number)
- {
- case HTML_FONT:
- popIfNotEmpty (_TextColor);
- popIfNotEmpty (_FontSize);
- break;
- case HTML_A:
- popIfNotEmpty (_TextColor);
- 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:
- {
- // Add the editbox
-// nlinfo("textarea temp '%s'", _TextAreaTemplate.c_str());
-// nlinfo("textarea name '%s'", _TextAreaName.c_str());
-// nlinfo("textarea %d %d", _TextAreaRow, _TextAreaCols);
-// nlinfo("textarea content '%s'", _TextAreaContent.toUtf8().c_str());
- CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent);
- 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);
- }
- _TextArea = false;
- }
- 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;
- case HTML_UL:
- if (getUL())
- {
- _Indent -= ULIndent;
- _Indent = std::max(_Indent, (uint)0);
- endParagraph();
- popIfNotEmpty (_UL);
- }
- break;
- case HTML_STYLE:
- _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("\nlocal __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 = "\nlocal __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 ¶m)
-: CGroupScrollText(param),
- _TimeoutValue(DEFAULT_RYZOM_CONNECTION_TIMEOUT)
-{
- // add it to map of group html created
- _GroupHtmlUID= ++_GroupHtmlUIDPool; // valid assigned Id begin to 1!
- _GroupHtmlByUID[_GroupHtmlUID]= this;
-
- // init
- _ParsingLua = false;
- _IgnoreText = false;
- _BrowseNextTime = false;
- _PostNextTime = false;
- _Browsing = false;
- _Connecting = false;
- _LibWWW = new CLibWWWData;
- _CurrentViewLink = NULL;
- _CurrentViewImage = NULL;
- _Indent = 0;
- _LI = false;
- _SelectOption = false;
- _GroupListAdaptor = NULL;
-
- // 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";
- DefaultBackgroundBitmapView = "bg";
- clearContext();
-
- MultiCurl = curl_multi_init();
- RunningCurls = 0;
-
- initImageDownload();
- initBnpDownload();
-}
-
-// ***************************************************************************
-
-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();
- delete _LibWWW;
-}
-
-// ***************************************************************************
-
-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*)"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());
-}
-
-// ***************************************************************************
-void CGroupHTML::doBrowse(const char *url)
-{
- // Stop previous browse
- if (_Browsing)
- {
- // Clear all the context
- clearContext();
-
- _Browsing = false;
- if (_Connecting)
- {
- nlassert (_ConnectingLock == this);
- _ConnectingLock = NULL;
- }
- else
- nlassert (_ConnectingLock != this);
- _Connecting = false;
-// stopBrowse ();
- updateRefreshButton();
-
-#ifdef LOG_DL
- nlwarning("*** ALREADY BROWSING, break first");
-#endif
- }
-
-#ifdef LOG_DL
- nlwarning("Browsing URL : '%s'", url);
-#endif
-
- // go
- _URL = url;
- _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(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");
-#endif
-
- // Clear all the context
- clearContext();
-
- _Browsing = false;
-
- if (_Connecting)
- {
- nlassert (_ConnectingLock == this);
- _ConnectingLock = NULL;
- }
- else
- nlassert (_ConnectingLock != this);
- _Connecting = false;
-
- // Request running ?
- if (_LibWWW->Request)
- {
-// VerifyLibWWW("HTRequest_kill", HTRequest_kill(_LibWWW->Request) == TRUE);
- HTRequest_kill(_LibWWW->Request);
- HTRequest_delete(_LibWWW->Request);
- _LibWWW->Request = NULL;
- }
-}
-
-// ***************************************************************************
-
-void CGroupHTML::updateCoords()
-{
- CGroupScrollText::updateCoords();
-}
-
-// ***************************************************************************
-
-bool CGroupHTML::translateChar(ucchar &output, ucchar input, ucchar lastCharParam) const
-{
- // Keep this char ?
- bool keep = true;
-
- switch (input)
- {
- // Return / tab only in 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::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;
-
- // 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()) &&
- (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 TTmplParam;
- vector 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::parser->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
- if (buttonGroup)
- {
-
- // Add the ctrl button
- CCtrlTextButton *ctrlButton = dynamic_cast(buttonGroup->getCtrl("button"));
- if (!ctrlButton) ctrlButton = dynamic_cast(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->setUnderlined (true);
- }
- }
- newLink->setText(tmpStr);
- newLink->setColor(getTextColor());
- newLink->setFontSize(getFontSize());
- newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor));
- newLink->setMultiLine(true);
- newLink->setModulateGlobalColor(getGlobalColor());
- // newLink->setLineAtBottom (true);
-
- if (getA() && !newLink->Link.empty())
- {
- getParagraph()->addChildLink(newLink);
- }
- else
- {
- getParagraph()->addChild(newLink);
- }
- paragraphChange ();
- }
- }
- }
-}
-
-// ***************************************************************************
-
-void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg)
-{
- // In a paragraph ?
- if (_Paragraph)
- {
- string finalUrl;
-
- //
- // 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))
- {
- // No more text in this text view
- _CurrentViewLink = NULL;
-
- // Not added ?
- CViewBitmap *newImage = new CViewBitmap (TCtorParam());
- /* todo link in image
- if (getA())
- {
- newImage->Link = getLink();
- newImage->setHTMLView (this);
- }*/
- newImage->setRenderLayer(getRenderLayer()+1);
- newImage->setTexture (finalUrl);
- newImage->setModulateGlobalColor(globalColor);
-
- /* todo link in image
- if (getA())
- getParagraph()->addChildLink(newImage);
- else*/
- getParagraph()->addChild(newImage);
- paragraphChange ();
- }
- 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))
- {
- // No more text in this text view
- _CurrentViewLink = NULL;
-
- // Not added ?
- CViewBitmap *newImage = new CViewBitmap (TCtorParam());
- /* todo link in image
- if (getA())
- {
- newImage->Link = getLink();
- newImage->setHTMLView (this);
- }*/
-
- // 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();
-
- newImage->setTexture (image);
-// newImage->setTexture (finalUrl);
- newImage->setModulateGlobalColor(globalColor);
-
- /* todo link in image
- if (getA())
- getParagraph()->addChildLink(newImage);
- else*/
- getParagraph()->addChild(newImage);
- paragraphChange ();
- }
- else
- {
-
- //
- // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache
- //
- image = "web_del.tga";
- if (lookupLocalFile (finalUrl, image.c_str(), false))
- {
- // No more text in this text view
- _CurrentViewLink = NULL;
-
- // Not added ?
- CViewBitmap *newImage = new CViewBitmap (TCtorParam());
- /* todo link in image
- if (getA())
- {
- newImage->Link = getLink();
- newImage->setHTMLView (this);
- }*/
- newImage->setTexture (image);
- // newImage->setTexture (finalUrl);
- newImage->setModulateGlobalColor(globalColor);
-
- addImageDownload(img, newImage);
-
- /* todo link in image
- if (getA())
- getParagraph()->addChildLink(newImage);
- else*/
- getParagraph()->addChild(newImage);
- paragraphChange ();
- }
- }
- }
- }
-}
-
-// ***************************************************************************
-
-CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content)
-{
- // In a paragraph ?
- if (!_Paragraph)
- {
- newParagraph (0);
- paragraphChange ();
- }
-
- // No more text in this text view
- _CurrentViewLink = NULL;
-
- {
- // Not added ?
- std::vector > templateParams;
- templateParams.push_back (std::pair ("w", toString (cols*12)));
- //templateParams.push_back (std::pair ("h", toString (rows*12)));
- templateParams.push_back (std::pair ("id", name));
- templateParams.push_back (std::pair ("prompt", ""));
- templateParams.push_back (std::pair ("multiline", multiLine?"true":"false"));
- templateParams.push_back (std::pair ("want_return", multiLine?"true":"false"));
- templateParams.push_back (std::pair ("enter_recover_focus", "false"));
- templateParams.push_back (std::pair ("max_num_chars", "1024"));
- CInterfaceGroup *textArea = CWidgetManager::parser->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(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 > templateParams;
- templateParams.push_back (std::pair ("id", name));
- CInterfaceGroup *group = CWidgetManager::parser->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(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)
-{
- // 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);
- }
- }
- }
-
- 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(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 ();
-
- return ctrlButton;
-}
-
-// ***************************************************************************
-
-void CGroupHTML::flushString()
-{
- _CurrentViewLink = NULL;
-}
-
-// ***************************************************************************
-
-void CGroupHTML::clearContext()
-{
- _Paragraph = NULL;
- _PRE.clear();
- _TextColor.clear();
- _GlobalColor.clear();
- _FontSize.clear();
- _Indent = 0;
- _LI = false;
- _UL.clear();
- _A.clear();
- _Link.clear();
- _LinkTitle.clear();
- _Tables.clear();
- _Cells.clear();
- _TR.clear();
- _Forms.clear();
- _Groups.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(child);
- _CurrentViewImage = dynamic_cast(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;
- }
-
- 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(group);
-
- CInterfaceGroup *parentGroup = CGroupHTML::getCurrentGroup();
- const std::vector &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(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(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 = strlwr(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 (strlwr(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:"+strlwr(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 *submitButtonName)
-{
- // Form id valid ?
- if (formId < _Forms.size())
- {
- _PostNextTime = true;
- _PostFormId = formId;
- _PostFormSubmitButton = submitButtonName;
- }
-}
-
-// ***************************************************************************
-
-void CGroupHTML::setBackgroundColor (const CRGBA &bgcolor)
-{
- // Should have a child named bg
- CViewBase *view = getView (DefaultBackgroundBitmapView);
- if (view)
- {
- CViewBitmap *bitmap = dynamic_cast (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 (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(ctrl);
- if (textButt)
- {
- textButt->setFrozen(true);
- }
- }
-};
-
-static int timer_called = 0;
-
-static int
-timer_callback(HTTimer * const timer ,
- void * const user_data ,
- HTEventType const event )
-{
-/*----------------------------------------------------------------------------
- A handy timer callback which cancels the running event loop.
------------------------------------------------------------------------------*/
- nlassert(event == HTEvent_TIMEOUT);
- timer_called = 1;
- HTEventList_stopLoop();
-
- /* XXX - The meaning of this return value is undocumented, but close
- ** inspection of libwww's source suggests that we want to return HT_OK. */
- return HT_OK;
-}
-
-static void handleLibwwwEvents()
-{
- HTTimer *timer;
- timer_called = 0;
- timer = HTTimer_new(NULL, &timer_callback, NULL,
- 1, YES, NO);
- if (!timer_called)
- HTEventList_newLoop();
- HTTimer_delete(timer);
-}
-
-// ***************************************************************************
-
-void CGroupHTML::handle ()
-{
- H_AUTO(RZ_Interface_Html_handle)
-
- const CWidgetManager::SInterfaceTimes × = CWidgetManager::getInstance()->getInterfaceTimes();
-
- if (_Connecting)
- {
- nlassert (_ConnectingLock == this);
-
- // Check timeout if needed
- if (_TimeoutValue != 0 && _ConnectingTimeout <= ( times.thisFrameMs / 1000.0f ) )
- {
- browseError(("Connection timeout : "+_URL).c_str());
- }
- }
- else
- {
- if (_ConnectingLock == NULL)
- {
- if (_BrowseNextTime)
- {
- // Stop browsing now
- stopBrowse ();
- updateRefreshButton();
-
- // Home ?
- if (_URL == "home")
- _URL = home();
-
- string finalUrl;
- bool isLocal = lookupLocalFile (finalUrl, _URL.c_str(), true);
-
- // Reset the title
- if(_TitlePrefix.empty())
- setTitle (CI18N::get("uiPleaseWait"));
- else
- setTitle (_TitlePrefix + " - " + CI18N::get("uiPleaseWait"));
-
- // Start connecting
- nlassert (_ConnectingLock == NULL);
- _ConnectingLock = this;
- _Connecting = true;
- _ConnectingTimeout = ( times.thisFrameMs / 1000.0f ) + _TimeoutValue;
-
-
- CButtonFreezer freezer;
- this->visit(&freezer);
-
- // Browsing
- _Browsing = true;
- updateRefreshButton();
-
- // Save new url
- _URL = finalUrl;
-
- // display HTTP query
- //nlinfo("WEB: GET '%s'", finalUrl.c_str());
-
- // Init LibWWW
- initLibWWW();
- _TrustedDomain = isTrustedDomain(setCurrentDomain(finalUrl));
-
- // Add custom get params
- addHTTPGetParams (finalUrl, _TrustedDomain);
-
-
- // Get the final URL
- C3WSmartPtr uri = HTParse(finalUrl.c_str(), NULL, PARSE_ALL);
-
- // Create an anchor
-#ifdef NL_OS_WINDOWS
- if ((_LibWWW->Anchor = HTAnchor_findAddress(uri)) == NULL)
-#else
- // temporarily disable local URL's until LibWWW can be replaced.
- if (isLocal || ((_LibWWW->Anchor = HTAnchor_findAddress(uri)) == NULL))
-#endif
- {
- browseError((string("The page address is malformed : ")+(const char*)uri).c_str());
- }
- else
- {
- /* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */
- HTNet_addAfter(requestTerminater, NULL, (void*)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST);
-
- /* Set the timeout for long we are going to wait for a response */
- HTHost_setEventTimeout(60000);
-
- /* Start the first request */
-
- // request = Request_new(app);
- _LibWWW->Request = HTRequest_new();
- HTRequest_setContext(_LibWWW->Request, this);
-
- // add supported language header
- HTList *langs = HTList_new();
- // set the language code used by the client
- HTLanguage_add(langs, options.languageCode.c_str(), 1.0);
- HTRequest_setLanguage (_LibWWW->Request, langs, 1);
-
- // get_document(_LibWWW->Request, _LibWWW->Anchor);
- C3WSmartPtr address = HTAnchor_address(_LibWWW->Anchor);
- HTRequest_setAnchor(_LibWWW->Request, _LibWWW->Anchor);
- if (HTLoad(_LibWWW->Request, NO))
- {
- }
- else
- {
- browseError((string("The page cannot be displayed : ")+(const char*)uri).c_str());
- }
- }
-
- _BrowseNextTime = false;
- }
-
- if (_PostNextTime)
- {
- /* Create a list to hold the form arguments */
- HTAssocList * formfields = HTAssocList_new();
-
- // Add text area text
- uint i;
-
- // Ref the form
- CForm &form = _Forms[_PostFormId];
-
- // Save new url
- _URL = form.Action;
-
- for (i=0; igetGroup ("eb");
- if (group)
- {
- // Should be a CGroupEditBox
- CGroupEditBox *editBox = dynamic_cast(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 = ucstring ("on");
- 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)
- {
- // Build a utf8 string
- string uft8 = form.Entries[i].Name + "=" + CI18N::encodeUTF8(entryData);
-
- /* Parse the content and add it to the association list */
- HTParseFormInput(formfields, uft8.c_str());
- }
- }
-
- // Add the button coordinates
- HTParseFormInput(formfields, (_PostFormSubmitButton + "_x=0").c_str());
- HTParseFormInput(formfields, (_PostFormSubmitButton + "_y=0").c_str());
-
- // Add custom params
- addHTTPPostParams(formfields, _TrustedDomain);
-
- // Reset the title
- if(_TitlePrefix.empty())
- setTitle (CI18N::get("uiPleaseWait"));
- else
- setTitle (_TitlePrefix + " - " + CI18N::get("uiPleaseWait"));
-
- // Stop previous browse
- stopBrowse ();
-
- // Set timeout
- nlassert (_ConnectingLock == NULL);
- _ConnectingLock = this;
- _Connecting = true;
- _ConnectingTimeout = ( times.thisFrameMs / 1000.0f ) + _TimeoutValue;
-
- CButtonFreezer freezer;
- this->visit(&freezer);
-
- // Browsing
- _Browsing = true;
- updateRefreshButton();
-
- // display HTTP query with post parameters
- //nlinfo("WEB: POST %s", _URL.c_str());
-
- // Init LibWWW
- initLibWWW();
- _TrustedDomain = isTrustedDomain(setCurrentDomain(_URL));
-
- // Get the final URL
- C3WSmartPtr uri = HTParse(_URL.c_str(), NULL, PARSE_ALL);
-
- // Create an anchor
- if ((_LibWWW->Anchor = HTAnchor_findAddress(uri)) == NULL)
- {
- browseError((string("The page address is malformed : ")+(const char*)uri).c_str());
- }
- else
- {
- /* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */
- HTNet_addAfter(requestTerminater, NULL, (void*)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST);
-
- /* Start the first request */
-
- // request = Request_new(app);
- _LibWWW->Request = HTRequest_new();
- HTRequest_setContext(_LibWWW->Request, this);
-
- /*
- ** Dream up a source anchor (an editor can for example use this).
- ** After creation we associate the data that we want to post and
- ** set some metadata about what the data is. More formats can be found
- ** ../src/HTFormat.html
- */
- /*HTParentAnchor *src = HTTmpAnchor(NULL);
- HTAnchor_setDocument(src, (void*)(data.c_str()));
- HTAnchor_setFormat(src, WWW_PLAINTEXT);*/
-
- /*
- ** If not posting to an HTTP/1.1 server then content length MUST be
- ** there. If HTTP/1.1 then it doesn't matter as we just use chunked
- ** encoding under the covers
- */
- // HTAnchor_setLength(src, data.size());
-
- HTParentAnchor *result = HTPostFormAnchor (formfields, _LibWWW->Anchor, _LibWWW->Request);
- if (result)
- {
- }
- else
- {
- browseError((string("The page cannot be displayed : ")+(const char*)uri).c_str());
- }
-
- /* POST the source to the dest */
- /*
- BOOL status = NO;
- status = HTPostAnchor(src, _LibWWW->Anchor, _LibWWW->Request);
- if (status)
- {
- }
- else
- {
- browseError((string("The page cannot be displayed : ")+(const char*)uri).c_str());
- }*/
- }
-
- _PostNextTime = false;
- }
- }
- }
-#ifndef NL_OS_WINDOWS
- if(isBrowsing())
- handleLibwwwEvents();
-#endif
-}
-
-// ***************************************************************************
-
-void CGroupHTML::draw ()
-{
- checkDownloads();
- CGroupScrollText::draw ();
-}
-
-// ***************************************************************************
-
-void CGroupHTML::endBuild ()
-{
- invalidateCoords();
-}
-
-// ***************************************************************************
-
-void CGroupHTML::addHTTPGetParams (string &/* url */, bool /*trustedDomain*/)
-{
-}
-
-// ***************************************************************************
-
-void CGroupHTML::addHTTPPostParams (HTAssocList * /* formfields */, bool /*trustedDomain*/)
-{
-}
-
-// ***************************************************************************
-
-void CGroupHTML::requestTerminated(HTRequest * /* request */)
-{
- // 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);
- }
-}
-
-// ***************************************************************************
-
-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();
- _Paragraph = NULL;
-
- // 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;iChildren.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 ¶ms, 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::parser->getProcedureNumActions(procName);
- for(uint i=0;igetProcedureAction(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(CWidgetManager::getInstance()->getElementFromId(_BrowseUndoButton));
- CCtrlBaseButton *butRedo= dynamic_cast(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(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 ¶m)
- : CInterfaceGroup(param),
- Offset(0)
-{
-}
-
-// ***************************************************************************
-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(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.toNumber(1);
- std::vector present;
- std::vector 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().isNumber())
- {
- 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().toNumber();
-
- present.insert(present.begin() + (uint)it.nextKey().toNumber(), 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().toNumber(), buffer);
- }
-
- beginElement(element_number, &present[0], &value[0]);
- if (element_number == HTML_A)
- addLink(element_number, 0, NULL, &present[0], &value[0]);
-
- 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.toNumber(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= 4)
- {
- pos = i+1;
-
- // unicode character
- if (str[pos] == '#')
- {
- ++pos;
-
- // using decimal by default
- uint base = 10;
-
- // using hexadecimal if
- if (str[pos] == 'x')
- {
- base = 16;
- ++pos;
- }
-
- // setup "last" to point at the first character following "?[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: "?[0-9a-f]+;"
- if (last == pos || str[last] != ';')
- {
- result += str[i];
- continue;
- }
-
- ucchar c = 0;
-
- // convert digits to unicode character
- while (pos'; continue; }
- }
-
- // all the special cases are catered for... treat this as a normal character
- result += str[i];
- }
-
- return result;
-}
-
-
diff --git a/code/ryzom/client/src/interface_v3/group_html.h b/code/ryzom/client/src/interface_v3/group_html.h
deleted file mode 100644
index fa39debf7..000000000
--- a/code/ryzom/client/src/interface_v3/group_html.h
+++ /dev/null
@@ -1,658 +0,0 @@
-// Ryzom - MMORPG Framework
-// 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 .
-
-#ifndef CL_GROUP_HTML_H
-#define CL_GROUP_HTML_H
-
-#define CURL_STATICLIB 1
-#include
-
-#include "nel/misc/types_nl.h"
-#include "nel/gui/interface_group.h"
-#include "nel/gui/group_scrolltext.h"
-#include "nel/gui/group_tree.h"
-#include "nel/gui/ctrl_button.h"
-#include "nel/gui/group_table.h"
-
-typedef std::map TStyle;
-
-extern "C"
-{
-#include "WWWInit.h"
-}
-
-namespace NLGUI
-{
- class CCtrlButton;
- class CCtrlScroll;
- class CGroupList;
- class CDBGroupComboBox;
-}
-
-class CGroupParagraph;
-
-
-// HTML group
-/**
- * Widget to have a resizable scrolltext and its scrollbar
- * \author Cyril 'Hulud' Corvazier
- * \author Nevrax France
- * \date 2002
- */
-class CGroupHTML : public CGroupScrollText
-{
-public:
- friend void TextAdd (struct _HText *me, const char * buf, int len);
- friend void TextBeginElement (_HText *me, int element_number, const BOOL *present, const char ** value);
- friend void TextEndElement (_HText *me, int element_number);
- friend void TextLink (struct _HText *me, int element_number, int attribute_number, struct _HTChildAnchor *anchor, const BOOL *present, const char **value);
- friend void TextBuild (HText * me, HTextStatus status);
- friend void TextBeginUnparsedElement(HText *me, const char *buffer, int length);
- friend void TextEndUnparsedElement(HText *me, const char *buffer, int length);
- friend int requestTerminater (HTRequest * request, HTResponse * response, void * param, int status);
-
- struct SWebOptions
- {
- public:
- std::string appName;
- std::string appVersion;
- std::string languageCode;
- std::vector< std::string > trustedDomains;
-
- SWebOptions()
- {
- }
- };
-
- static SWebOptions options;
-
- // Constructor
- CGroupHTML(const TCtorParam ¶m);
- ~CGroupHTML();
-
- // CInterfaceGroup Interface
- virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
- virtual void draw ();
-
- // Events
- virtual bool handleEvent (const NLGUI::CEventDescriptor& eventDesc);
-
- // Browse
- virtual void browse (const char *url);
-
- // Refresh
- void refresh();
-
- // submit form
- void submitForm (uint formId, const char *submitButtonName);
-
- // Browse error
- void browseError (const char *msg);
-
- // stop browse
- void stopBrowse ();
-
- bool isBrowsing();
-
- void clean() { stopBrowse(); updateRefreshButton(); removeContent(); }
-
- // Update coords
- void updateCoords();
-
- // New paragraph
- void newParagraph(uint beginSpace);
-
- // End of the paragraph
- void endParagraph();
-
- // Timeout
- void setTimeout(float tm) {_TimeoutValue= std::max(0.f, tm);}
- float getTimeout() const {return (float)_TimeoutValue;}
-
- // Some constants
- NLMISC::CRGBA BgColor;
- NLMISC::CRGBA ErrorColor;
- NLMISC::CRGBA LinkColor;
- NLMISC::CRGBA TextColor;
- NLMISC::CRGBA H1Color;
- NLMISC::CRGBA H2Color;
- NLMISC::CRGBA H3Color;
- NLMISC::CRGBA H4Color;
- NLMISC::CRGBA H5Color;
- NLMISC::CRGBA H6Color;
- bool ErrorColorGlobalColor;
- bool LinkColorGlobalColor;
- bool TextColorGlobalColor;
- bool H1ColorGlobalColor;
- bool H2ColorGlobalColor;
- bool H3ColorGlobalColor;
- bool H4ColorGlobalColor;
- bool H5ColorGlobalColor;
- bool H6ColorGlobalColor;
- uint TextFontSize;
- uint H1FontSize;
- uint H2FontSize;
- uint H3FontSize;
- uint H4FontSize;
- uint H5FontSize;
- uint H6FontSize;
- uint TDBeginSpace;
- uint PBeginSpace;
- uint LIBeginSpace;
- uint ULBeginSpace;
- uint LIIndent;
- uint ULIndent;
- float LineSpaceFontFactor;
- std::string DefaultButtonGroup;
- std::string DefaultFormTextGroup;
- std::string DefaultFormTextAreaGroup;
- std::string DefaultFormSelectGroup;
- std::string DefaultCheckBoxBitmapNormal;
- std::string DefaultCheckBoxBitmapPushed;
- std::string DefaultCheckBoxBitmapOver;
- std::string DefaultBackgroundBitmapView;
- std::string CurrentLinkTitle;
-
- // Browser home
- std::string Home;
-
- // Undo browse: Browse the precedent url browsed. no op if none
- void browseUndo ();
- // Redo browse: Browse the precedent url undoed. no op if none
- void browseRedo ();
- // clear undo/redo
- void clearUndoRedo();
-
-
- std::string getURL() const { return _URL; }
- void setURL(const std::string &url);
-
-
- int luaBrowse(CLuaState &ls);
- int luaRefresh(CLuaState &ls);
- int luaRemoveContent(CLuaState &ls);
- int luaInsertText(CLuaState &ls);
- int luaAddString(CLuaState &ls);
- int luaAddImage(CLuaState &ls);
- int luaBeginElement(CLuaState &ls);
- int luaEndElement(CLuaState &ls);
- int luaShowDiv(CLuaState &ls);
-
- REFLECT_EXPORT_START(CGroupHTML, CGroupScrollText)
- REFLECT_LUA_METHOD("browse", luaBrowse)
- REFLECT_LUA_METHOD("refresh", luaRefresh)
- REFLECT_LUA_METHOD("removeContent", luaRemoveContent)
- REFLECT_LUA_METHOD("insertText", luaInsertText)
- REFLECT_LUA_METHOD("addString", luaAddString)
- REFLECT_LUA_METHOD("addImage", luaAddImage)
- REFLECT_LUA_METHOD("beginElement", luaBeginElement)
- REFLECT_LUA_METHOD("endElement", luaEndElement)
- REFLECT_LUA_METHOD("showDiv", luaShowDiv)
- REFLECT_STRING("url", getURL, setURL)
- REFLECT_FLOAT("timeout", getTimeout, setTimeout)
- REFLECT_EXPORT_END
-
-protected :
-
- // \name callback from libwww
-
- // Begin of the parsing of a HTML document
- virtual void beginBuild ();
-
- // End of the parsing of a HTML document
- virtual void endBuild ();
-
- // A new text block has been parsed
- virtual void addText (const char * buf, int len);
-
- // A link has been parsed
- virtual void addLink (uint element_number, uint attribute_number, HTChildAnchor *anchor, const BOOL *present, const char **value);
-
- // A new begin HTML element has been parsed ( for exemple)
- virtual void beginElement (uint element_number, const BOOL *present, const char **value);
-
- // A new end HTML element has been parsed ( for exemple)
- virtual void endElement (uint element_number);
-
- // A new begin unparsed element has been found
- virtual void beginUnparsedElement(const char *buffer, int length);
-
- // A new end unparsed element has been found
- virtual void endUnparsedElement(const char *buffer, int length);
-
- // Add GET params to the url
- virtual void addHTTPGetParams (std::string &url, bool trustedDomain);
-
- // Add POST params to the libwww list
- virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain);
-
- // the current request is terminated
- virtual void requestTerminated(HTRequest *request);
-
- // Get Home URL
- virtual std::string home();
-
- // Parse style html tag
- TStyle parseStyle(const std::string &str_styles);
-
- // Handle some work at each pass
- virtual void handle ();
-
- // \name internal methods
-
- // Add a group in the current parent group
- void addGroup (CInterfaceGroup *group, uint beginSpace);
-
- // Get the current parent group
- CInterfaceGroup *getCurrentGroup();
-
- // Update current paragraph dependent data
- void paragraphChange ();
-
- // Clear the contexts info
- void clearContext();
-
- // Translate a char
- bool translateChar(ucchar &output, ucchar input, ucchar lastChar) const;
-
- // Add a string in the current paragraph
- void addString(const ucstring &str);
-
- // Add an image in the current paragraph
- void addImage(const char *image, bool globalColor, bool reloadImg=false);
-
- // Add a text area in the current paragraph
- CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content);
-
- // Add a combo box in the current paragraph
- CDBGroupComboBox *addComboBox(const std::string &templateName, const char *name);
-
- // Add a button in the current paragraph. actionHandler, actionHandlerParams and tooltip can be NULL.
- CCtrlButton *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);
-
- // Set the background color
- void setBackgroundColor (const NLMISC::CRGBA &bgcolor);
-
- // Set the background
- void setBackground (const std::string &bgtex, bool scale, bool tile);
-
- // Force the current string to be in a single string
- void flushString();
-
- // Set the title
- void setTitle (const ucstring &title);
-
- // Lookup a url in local file system
- bool lookupLocalFile (std::string &result, const char *url, bool isUrl);
-
- // Delete page content and prepare next page
- void removeContent ();
-
- // Current URL
- std::string _URL;
-
- // Current DOMAIN
- bool _TrustedDomain;
-
- // Title prefix
- ucstring _TitlePrefix;
-
- // Title string
- ucstring _TitleString;
-
- // Need to browse next update coords..
- bool _BrowseNextTime;
- bool _PostNextTime;
- uint _PostFormId;
- std::string _PostFormSubmitButton;
-
- // Browsing..
- bool _Browsing;
- bool _Connecting;
- double _TimeoutValue; // the timeout in seconds
- double _ConnectingTimeout;
-
- // minimal embeded lua script support
- // Note : any embeded script is executed immediately after the closing
- // element has been found
- // True when the element has been encountered
- bool _ParsingLua;
- bool _IgnoreText;
- // the script to execute
- std::string _LuaScript;
-
- bool _Object;
- std::string _ObjectScript;
-
- // Someone is conecting. We got problem with libwww : 2 connection requests can deadlock the client.
- static CGroupHTML *_ConnectingLock;
-
- // LibWWW data
- class CLibWWWData *_LibWWW;
-
- // Current paragraph
- std::string _DivName;
- CGroupParagraph* _Paragraph;
- inline CGroupParagraph *getParagraph()
- {
- return _Paragraph;
- /*if (_Paragraph.empty())
- return NULL;
- return _Paragraph.back();*/
- }
-
- // PRE mode
- std::vector _PRE;
- inline bool getPRE() const
- {
- if (_PRE.empty())
- return false;
- return _PRE.back();
- }
-
- // UL mode
- std::vector _UL;
- inline bool getUL() const
- {
- if (_UL.empty())
- return false;
- return _UL.back();
- }
-
- // A mode
- std::vector _A;
- inline bool getA() const
- {
- if (_A.empty())
- return false;
- return _A.back();
- }
-
- // IL mode
- bool _LI;
-
- // Current text color
- std::vector _TextColor;
- inline const NLMISC::CRGBA &getTextColor() const
- {
- if (_TextColor.empty())
- return TextColor;
- return _TextColor.back();
- }
-
- // Current global color flag
- std::vector _GlobalColor;
- inline bool getGlobalColor() const
- {
- if (_GlobalColor.empty())
- return false;
- return _GlobalColor.back();
- }
-
- // Current font size
- std::vector _FontSize;
- inline uint getFontSize() const
- {
- if (_FontSize.empty())
- return TextFontSize;
- return _FontSize.back();
- }
-
- // Current link
- std::vector _Link;
- inline const char *getLink() const
- {
- if (_Link.empty())
- return "";
- return _Link.back().c_str();
- }
-
- std::vector _LinkTitle;
- inline const char *getLinkTitle() const
- {
- if (_LinkTitle.empty())
- return "";
- return _LinkTitle.back().c_str();
- }
- std::vector _LinkClass;
- inline const char *getLinkClass() const
- {
- if (_LinkClass.empty())
- return "";
- return _LinkClass.back().c_str();
- }
-
- // Divs (i.e. interface group)
- std::vector _Divs;
- inline CInterfaceGroup *getDiv() const
- {
- if (_Divs.empty())
- return NULL;
- return _Divs.back();
- }
-
- // Tables
- std::vector _Tables;
- inline CGroupTable *getTable() const
- {
- if (_Tables.empty())
- return NULL;
- return _Tables.back();
- }
-
- // Cells
- std::vector _Cells;
-
- // TR
- std::vector _TR;
- inline bool getTR() const
- {
- if (_TR.empty())
- return false;
- return _TR.back();
- }
-
- // Forms
- class CForm
- {
- public:
-
- class CEntry
- {
- public:
- CEntry ()
- {
- TextArea = NULL;
- Checkbox = NULL;
- ComboBox = NULL;
- InitialSelection = 0;
- }
-
- // Variable name
- std::string Name;
-
- // Variable value
- ucstring Value;
-
- // Text area group
- CInterfaceGroup *TextArea;
-
- // Checkbox
- CCtrlButton *Checkbox;
-
- // Combobox group
- CDBGroupComboBox *ComboBox;
-
- // select values (for the