1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2021 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2019-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "group_quick_help.h"
29 #include "nel/gui/group_list.h"
30 #include "nel/gui/group_paragraph.h"
31 #include "nel/gui/libwww.h"
32 #include "nel/gui/html_element.h"
33 #include "interface_manager.h"
34 #include "nel/gui/action_handler.h"
35 #include "nel/misc/xml_auto_ptr.h"
36 #include "../actions.h"
37 #include "../client_cfg.h"
40 using namespace NLMISC
;
42 // ***************************************************************************
43 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupQuickHelp
, std::string
, "quick_help");
45 CGroupQuickHelp::CGroupQuickHelp(const TCtorParam
¶m
)
50 _UpdateParagraphNextUpdateCoords
= true;
53 // ***************************************************************************
55 CGroupQuickHelp::~CGroupQuickHelp()
59 // ***************************************************************************
61 bool CGroupQuickHelp::submitEvent (const char *event
)
63 if(_IsQuickHelp
==false)
66 if (_CurrentStep
<_Steps
.size())
68 const CStep
&step
= _Steps
[_CurrentStep
];
69 if (step
.EventToComplete
.find (event
) != step
.EventToComplete
.end())
74 activateCurrentStep ();
83 // ***************************************************************************
85 void CGroupQuickHelp::updateParagraph ()
87 // Get the group list of CGroupScrollText
88 CGroupList
*groupList
= getList ();
89 if (groupList
&& groupList
->getNumChildren())
92 CViewBase
*viewBase
= groupList
->getChild(0);
95 CInterfaceGroup
*adaptor
= dynamic_cast<CInterfaceGroup
*>(viewBase
);
99 const vector
<CInterfaceGroup
*> &groups
= adaptor
->getGroups();
101 // For each paragraph
103 for (i
=0; i
<groups
.size(); i
++)
108 CGroupParagraph
*paragraph
= dynamic_cast<CGroupParagraph
*> (groups
[i
]);
113 setGroupTextSize (paragraph
, true);
115 setGroupTextSize (paragraph
, false);
125 // ***************************************************************************
127 bool CGroupQuickHelp::parse (xmlNodePtr cur
, CInterfaceGroup
*parentGroup
)
134 ptr
= xmlGetProp (cur
, (xmlChar
*)"non_selected_color");
136 _NonSelectedColor
= convertColor(ptr
);
137 ptr
= xmlGetProp (cur
, (xmlChar
*)"non_selected_link_color");
139 _NonSelectedLinkColor
= convertColor(ptr
);
140 ptr
= xmlGetProp (cur
, (xmlChar
*)"non_selected_global_color");
142 _NonSelectedGlobalColor
= convertBool(ptr
);
143 ptr
= xmlGetProp (cur
, (xmlChar
*)"non_selected_font_size");
145 fromString((const char*)ptr
, _NonSelectedSize
);
148 if (!CGroupHTML::parse (cur
, parentGroup
))
154 // ***************************************************************************
156 void CGroupQuickHelp::initParameters()
159 _NonSelectedSize
= 10;
160 _NonSelectedColor
= CRGBA(128,128,128);
161 _NonSelectedLinkColor
= CRGBA(0,0,128);
162 _NonSelectedGlobalColor
= true;
165 // ***************************************************************************
167 void CGroupQuickHelp::setGroupTextSize (CInterfaceGroup
*group
, bool selected
)
169 bool globalColor
= selected
? TextColorGlobalColor
: _NonSelectedGlobalColor
;
170 bool linkGlobalColor
= selected
? LinkColorGlobalColor
: _NonSelectedGlobalColor
;
171 uint fontSize
= selected
? _BrowserStyle
.Current
.FontSize
: _NonSelectedSize
;
172 NLMISC::CRGBA color
= selected
? _BrowserStyle
.Current
.TextColor
: _NonSelectedColor
;
173 NLMISC::CRGBA linkColor
= selected
? LinkColor
: _NonSelectedLinkColor
;
175 // Look for text in this group
176 const vector
<CViewBase
*> &views
= group
->getViews();
178 for (i
=0; i
<views
.size(); i
++)
181 CViewLink
*viewText
= dynamic_cast<CViewLink
*>(views
[i
]);
184 bool link
= !(viewText
->getText().empty()) && viewText
->getUnderlined ();
186 // Set text attributes
187 viewText
->setFontSize(fontSize
);
188 viewText
->setColor(link
? linkColor
: color
);
189 viewText
->setModulateGlobalColor(link
? linkGlobalColor
: globalColor
);
193 // Active / desactive link ctrl
194 const vector
<CCtrlBase
*> &ctrls
= group
->getControls();
195 for (i
=0; i
<ctrls
.size(); i
++)
197 CCtrlLink
*ctrlLink
= dynamic_cast<CCtrlLink
*>(ctrls
[i
]);
200 ctrlLink
->setActive(selected
);
204 // Look into subgroups
205 const vector
<CInterfaceGroup
*> &groups
= group
->getGroups();
206 for (i
=0; i
<groups
.size(); i
++)
210 setGroupTextSize (groups
[i
], selected
);
213 CGroupParagraph
*p
= dynamic_cast<CGroupParagraph
*>(group
);
216 group
->setActive(selected
);
219 // ***************************************************************************
221 extern CActionsContext ActionsContext
;
223 void CGroupQuickHelp::beginElement(CHtmlElement
&elm
)
225 CGroupHTML::beginElement (elm
);
232 if (_TrustedDomain
&& elm
.hasNonEmptyAttribute("z_action_shortcut"))
234 // Get the action category
235 string category
= elm
.getAttribute("z_action_category");
237 // Get the action params
238 string params
= elm
.getAttribute("z_action_params");
240 // Get the action descriptor
241 CActionsManager
*actionManager
= ActionsContext
.getActionsManager (category
);
244 const CActionsManager::TActionComboMap
&actionCombo
= actionManager
->getActionComboMap ();
245 CActionsManager::TActionComboMap::const_iterator ite
= actionCombo
.find (CAction::CName (elm
.getAttribute("z_action_shortcut").c_str(), params
.c_str()));
246 if (ite
!= actionCombo
.end())
248 addString (ite
->second
.toString());
255 // Get the action name
256 if (elm
.hasAttribute("quick_help_events"))
258 // This page is a quick help
261 _Steps
.push_back (CStep());
262 CStep
&step
= _Steps
.back();
264 // Get the event names
265 string events
= elm
.getAttribute("quick_help_events");
269 while (first
< events
.size())
272 string::size_type last
= events
.find_first_of(" ", first
);
273 if (last
== string::npos
)
274 last
= events
.size();
276 // Extract the string
277 step
.EventToComplete
.insert (events
.substr (first
, last
-first
));
278 first
= (uint
)last
+1;
283 step
.Condition
= elm
.getAttribute("quick_help_condition");
285 // Get the action handlers to run
286 step
.URL
= elm
.getAttribute("quick_help_link");
292 // ***************************************************************************
293 std::string
CGroupQuickHelp::getLanguageUrl(const std::string
&href
, std::string lang
) const
295 std::string uri
= href
;
297 if (uri
.size() < 5 || uri
.substr(0, 5) == "http://" || uri
.substr(0, 6) == "https://")
302 // modify uri such that '_??.html' ending contains current user language
303 if (uri
.substr(uri
.size()-5) == ".html")
305 if (uri
.rfind("_") == uri
.size() - 8)
307 uri
= uri
.substr(0, uri
.size() - 8);
311 uri
= uri
.substr(0, uri
.size() - 5);
313 uri
+= "_" + lang
+ ".html";
315 // files inside bnp (file:/gamedev.bnp@help_en.html) will always match with CPath::lookup()
317 size_t pos
= uri
.find("@");
318 if (pos
!= std::string::npos
)
320 fname
= uri
.substr(pos
+1);
326 if (CPath::lookup(fname
, false) == "" && lang
!= "en")
328 uri
= getLanguageUrl(href
, "en");
335 // ***************************************************************************
337 void CGroupQuickHelp::browse (const char *url
)
343 _IsQuickHelp
= false;
345 string completeURL
= getLanguageUrl(url
, ClientCfg
.getHtmlLanguageCode());
347 CGroupHTML::browse (completeURL
.c_str());
350 // ***************************************************************************
352 std::string
CGroupQuickHelp::home() const
354 string completeURL
= getLanguageUrl(Home
, ClientCfg
.getHtmlLanguageCode());
359 // ***************************************************************************
361 void CGroupQuickHelp::endBuild ()
363 CGroupHTML::endBuild ();
365 if(_IsQuickHelp
==false)
368 // First step must run an action handler ?
369 activateCurrentStep ();
370 _UpdateParagraphNextUpdateCoords
= true;
373 // ***************************************************************************
375 void CGroupQuickHelp::activateCurrentStep ()
377 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
380 if (_CurrentStep
< _Steps
.size())
383 CStep
&step
= _Steps
[_CurrentStep
];
385 // A link to follow ?
386 if (!step
.URL
.empty())
387 CAHManager::getInstance()->runActionHandler("browse", NULL
, "url="+step
.URL
);
389 // Test a skip condition
390 if (!step
.Condition
.empty() && evalExpression (step
.Condition
))
392 // Next action handler
401 // ***************************************************************************
403 bool CGroupQuickHelp::evalExpression (const std::string
&condition
)
405 // Add your conditions here :
407 if (condition
== "always")
413 // ***************************************************************************
414 /** Submit a quick help action
416 class CHandlerSubmitQuickHelp
: public IActionHandler
418 void execute (CCtrlBase
* /* pCaller */, const std::string
&sParams
)
420 CInterfaceElement
*element
= CWidgetManager::getInstance()->getElementFromId("ui:interface:quick_help:content:html");
424 CGroupQuickHelp
*groupQH
= dynamic_cast<CGroupQuickHelp
*>(element
);
427 // Submit the form the url
428 groupQH
->submitEvent (sParams
.c_str());
431 element
= CWidgetManager::getInstance()->getElementFromId("ui:interface:help_browser:content:html");
435 CGroupQuickHelp
*groupQH
= dynamic_cast<CGroupQuickHelp
*>(element
);
438 // Submit the form the url
439 groupQH
->submitEvent (sParams
.c_str());
445 REGISTER_ACTION_HANDLER( CHandlerSubmitQuickHelp
, "submit_quick_help");
447 // ***************************************************************************
450 class CHandlerRunQuickHelp
: public IActionHandler
452 void execute (CCtrlBase
* /* pCaller */, const std::string
&sParams
)
454 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
456 // Get the quick help radio buttons base id
457 string buttonId
= CWidgetManager::getInstance()->getParser()->getDefine("quick_help_buttons");
458 if (!buttonId
.empty())
461 CInterfaceElement
*element
= CWidgetManager::getInstance()->getElementFromId(buttonId
+":"+sParams
);
465 CCtrlBaseButton
*button
= dynamic_cast<CCtrlBaseButton
*>(element
);
469 button
->setPushed(true);
471 // Run the left click action handler
472 CAHManager::getInstance()->runActionHandler(button
->getActionOnLeftClick(), button
, button
->getParamsOnLeftClick());
478 REGISTER_ACTION_HANDLER( CHandlerRunQuickHelp
, "run_quick_help");
480 // ***************************************************************************
482 void CGroupQuickHelp::updateCoords()
484 CGroupHTML::updateCoords();
485 if(_IsQuickHelp
==false)
487 if (_UpdateParagraphNextUpdateCoords
)
489 _UpdateParagraphNextUpdateCoords
= false;
494 // ***************************************************************************