1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 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) 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/>.
26 #include "events_listener.h"
27 #include "interface_v3/interface_manager.h"
34 using namespace NLMISC
;
36 extern CEventsListener EventsListener
;
43 H_AUTO_DECL ( RZ_Client_Actions_Context_Mngr_Update
)
45 static bool getParam (CBaseAction::CParameter::TType type
, string
¶mName
, string
¶mValue
, const std::string
&argu
, uint paramId
);
47 /////////////////////////////////////////////////////
48 /////////////////////////////////////////////////////
49 // CAction //////////////////////////////////////////
50 /////////////////////////////////////////////////////
51 /////////////////////////////////////////////////////
52 //---------------------------------------------------
55 //---------------------------------------------------
65 void CAction::runAction ()
67 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
70 CAHManager::getInstance()->runActionHandler (Name
.Name
, NULL
, Name
.Argu
);
74 /////////////////////////////////////////////////////
75 /////////////////////////////////////////////////////
76 // CActionsManager //////////////////////////////////
77 /////////////////////////////////////////////////////
78 /////////////////////////////////////////////////////
79 //---------------------------------------------------
82 //---------------------------------------------------
83 CActionsManager::CActionsManager()
87 }// CActionsManager //
90 //---------------------------------------------------
92 // Add a new Action in the context.
93 //---------------------------------------------------
94 bool CActionsManager::addAction(const CAction::CName
&name
)
96 // Try to allocate memory for action
100 // Find the base action
101 const CBaseAction
*baseAction
= getBaseAction(name
);
104 // Copy the repeat flag
105 action
.Repeat
= baseAction
->Repeat
;
106 action
.KeyUp
= baseAction
->KeyUp
;
107 action
.KeyDown
= baseAction
->KeyDown
;
110 // Try to insert the new action.
111 pair
<TActionsMap::iterator
, bool> p
= _Actions
.insert(TActionsMap::value_type(name
, action
));
115 nlwarning ("Action (%s %s) already exist in the action manager.", name
.Name
.c_str (), name
.Argu
.c_str ());
121 // ***************************************************************************
123 CAction
* CActionsManager::getAction(const CAction::CName
&name
)
125 TActionsMap::iterator it
= _Actions
.find(name
);
126 if (it
== _Actions
.end()) return NULL
;
127 return &(it
->second
);
130 // ***************************************************************************
132 void CActionsManager::clear ()
135 _ActionForceDisplay
.clear ();
136 _ActionCombo
.clear ();
137 _ComboAction
.clear ();
139 _WatchedActions
.clear ();
140 _ActionCategory
.clear ();
141 _Categories
.clear ();
144 // ***************************************************************************
146 void CActionsManager::removeCombo (const CCombo
&combo
)
148 // Get the old action of the combo
149 TComboActionMap::iterator itePreviousCombo
= _ComboAction
.find (combo
);
150 if (itePreviousCombo
!= _ComboAction
.end ())
152 const CAction::CName oldName
= itePreviousCombo
->second
;
154 // Remove all affected keys
155 TKeyActionMap::iterator ite
= _KeyAction
.find (combo
.Key
);
156 while ((ite
!= _KeyAction
.end ()) && (ite
->first
== combo
.Key
))
158 TKeyActionMap::iterator copyToDelete
= ite
;
159 #ifdef NL_ISO_CPP0X_AVAILABLE
160 if (copyToDelete
->second
== oldName
)
161 ite
= _KeyAction
.erase (copyToDelete
);
166 if (copyToDelete
->second
== oldName
)
167 _KeyAction
.erase (copyToDelete
);
172 _ActionCombo
.erase (oldName
);
175 _ComboAction
.erase (itePreviousCombo
);
179 // ***************************************************************************
180 void CActionsManager::removeAllCombos()
183 _ActionCombo
.clear ();
184 _ComboAction
.clear ();
186 _WatchedActions
.clear ();
187 _ActionForceDisplay
.clear();
190 // ***************************************************************************
192 bool CActionsManager::addCombo(const CAction::CName
&name
, const CCombo
&combo
, bool createAction
)
194 // If createAction == "true" -> Create the Action before to add te combo.
198 // Erase previous values
199 TActionComboMap::iterator itePreviousCombo
= _ActionCombo
.find (name
);
200 if (itePreviousCombo
!= _ActionCombo
.end ())
202 // Remove the old action affected to the combo
203 removeCombo (itePreviousCombo
->second
);
206 // Remove the new combo
209 _ComboAction
.insert (TComboActionMap::value_type (combo
, name
));
210 _ActionCombo
.insert (TActionComboMap::value_type (name
, combo
));
211 _KeyAction
.insert (TKeyActionMap::value_type (combo
.Key
, name
));
216 // ***************************************************************************
217 bool CActionsManager::valide(const CAction::CName
&name
) const
219 // Recover the pointer on "actionName" if it exists.
220 TActionsMap::const_iterator it
= _Actions
.find(name
);
221 if(it
!= _Actions
.end())
223 return it
->second
.Valide
;
225 // No action of this name found.
231 // ***************************************************************************
232 void CActionsManager::validate(const CAction::CName
&name
)
234 // Recover the pointer on "actionName" if it exists.
235 TActionsMap::iterator it
= _Actions
.find(name
);
236 if(it
!= _Actions
.end())
238 it
->second
.Valide
= true;
243 // ***************************************************************************
244 void CActionsManager::unvalidate(const CAction::CName
&name
)
246 // Recover the pointer on "actionName" if it exists.
247 TActionsMap::iterator it
= _Actions
.find(name
);
248 if(it
!= _Actions
.end())
250 it
->second
.Valide
= false;
255 // ***************************************************************************
256 bool CActionsManager::isActionPresentInContext(const CAction::CName
&name
) const
258 CInterfaceManager
*im
= CInterfaceManager::getInstance();
259 if (!im
->isInGame()) return true; // no filtering done when outgame, because actions.xml not loaded yet (no base actions where added)
261 const CBaseAction
*baseAction
= getBaseAction(name
);
262 if (!baseAction
) return false;
263 // see if action valid in current context
264 if (!ActionsContext
.matchContext(baseAction
->Contexts
)) return false;
265 // all parameters must be valid in current context
266 for (uint i
=0; i
<baseAction
->Parameters
.size (); i
++)
268 const CBaseAction::CParameter
¶meter
= baseAction
->Parameters
[i
];
269 if (parameter
.Type
== CBaseAction::CParameter::Constant
)
272 string paramValue
= parameter
.DefaultValue
;
274 // Get the param from the argu
275 getParam (parameter
.Type
, paramName
, paramValue
, name
.Argu
, i
);
278 for (uint k
= 0; k
< parameter
.Values
.size(); ++k
)
280 if (parameter
.Values
[k
].Value
== paramValue
)
282 if (!ActionsContext
.matchContext(parameter
.Values
[k
].Contexts
)) return false;
287 if (!found
) return false;
295 // ***************************************************************************
297 bool CActionsManager::keyPushed (const CEventKeyDown
&keyDown
)
299 bool actionExist
= false;
303 combo
.Key
= keyDown
.Key
;
304 combo
.KeyButtons
= keyDown
.Button
;
306 // Scan action binded to this key
307 TKeyActionMap::iterator iteKeyAction
= _KeyAction
.find (keyDown
.Key
);
308 while ((iteKeyAction
!= _KeyAction
.end ()) && (iteKeyAction
->first
== keyDown
.Key
))
310 if (isActionPresentInContext(iteKeyAction
->second
))
312 // Add it to the set of actions to watch
313 _WatchedActions
.insert (*iteKeyAction
);
318 // Update special valide actions
319 updateKeyButton (keyDown
.Button
);
322 TComboActionMap::iterator ite
= _ComboAction
.find (combo
);
323 if (ite
!= _ComboAction
.end ())
326 TActionsMap::iterator iteAction
= _Actions
.find (ite
->second
);
327 nlassert (iteAction
!= _Actions
.end ());
329 if (isActionPresentInContext(iteAction
->first
))
332 if (iteAction
->second
.KeyDown
&& (iteAction
->second
.Repeat
|| keyDown
.FirstTime
))
334 iteAction
->second
.runAction ();
350 // ***************************************************************************
352 void CActionsManager::keyReleased (const CEventKeyUp
&keyUp
)
356 // Update special keys state
357 updateKeyButton (keyUp
.Button
);
359 // For each watched actions
360 TKeyActionMap::iterator iteWatchedAction
= _WatchedActions
.begin ();
361 while (iteWatchedAction
!= _WatchedActions
.end ())
363 TKeyActionMap::iterator iteToDelete
= iteWatchedAction
;
365 // Get the combo for this action
366 TActionComboMap::iterator iteCombo
= _ActionCombo
.find (iteToDelete
->second
);
367 nlassert (iteCombo
!= _ActionCombo
.end());
369 // This combo released ?
370 if (iteCombo
->second
.Key
== keyUp
.Key
)
373 TActionsMap::iterator iteAction
= _Actions
.find (iteToDelete
->second
);
374 nlassert (iteAction
!= _Actions
.end());
376 // Remove this action from watching
377 #ifdef NL_ISO_CPP0X_AVAILABLE
378 // C++11 return the next item
379 iteWatchedAction
= _WatchedActions
.erase (iteToDelete
);
381 // remember the next iterator only if not using C++11
384 _WatchedActions
.erase (iteToDelete
);
387 // Invalidate the action
388 bool LastValid
= iteAction
->second
.Valide
;
389 iteAction
->second
.Valide
= false;
391 if ((LastValid
== true) && (iteAction
->second
.Valide
== false))
394 if (iteAction
->second
.KeyUp
)
396 iteAction
->second
.runAction ();
408 // ***************************************************************************
409 void CActionsManager::releaseAllKeyNoRunning()
411 // For each watched actions
412 TKeyActionMap::iterator iteWatchedAction
= _WatchedActions
.begin ();
413 while (iteWatchedAction
!= _WatchedActions
.end ())
415 TKeyActionMap::iterator iteToDelete
= iteWatchedAction
++;
417 // Invalidate the action
418 TActionsMap::iterator iteAction
= _Actions
.find (iteToDelete
->second
);
419 nlassert (iteAction
!= _Actions
.end());
420 iteAction
->second
.Valide
= false;
422 // Remove this action from watching
423 _WatchedActions
.erase (iteToDelete
);
428 // ***************************************************************************
430 sint
getMatchingNote (sint keyButton
, sint newButton
)
432 // At least all the needed key
433 if ((keyButton
& newButton
) != keyButton
)
436 // If exactly the same, we want it
437 if (keyButton
== newButton
)
440 // Else count the number of bits used
441 const uint flags
[3] = { ctrlKeyButton
, shiftKeyButton
, altKeyButton
};
443 for (uint i
=0; i
<3; i
++)
445 if (keyButton
& flags
[i
])
451 // ***************************************************************************
453 void CActionsManager::updateKeyButton (NLMISC::TKeyButton newButtons
)
455 // For each watched actions
456 TKeyActionMap::iterator iteWatchedAction
= _WatchedActions
.begin ();
457 while (iteWatchedAction
!= _WatchedActions
.end ())
459 // First action for this key
460 TKeyActionMap::iterator iteWatchedActionBegin
= iteWatchedAction
;
463 NLMISC::TKey key
= iteWatchedAction
->first
;
465 // Best matching action
466 CAction
*bestMatching
= NULL
;
467 sint bestMatchingNote
= -1;
469 // For each action with the same key, search the best combo
470 while ((iteWatchedAction
!= _WatchedActions
.end ()) && (key
== iteWatchedAction
->first
))
472 // Get the action combo
473 TActionComboMap::iterator iteCombo
= _ActionCombo
.find (iteWatchedAction
->second
);
474 if (iteCombo
== _ActionCombo
.end())
475 nlwarning("try to find Name:%s , Argu:%s",iteWatchedAction
->second
.Name
.c_str(), iteWatchedAction
->second
.Argu
.c_str());
476 nlassert (iteCombo
!= _ActionCombo
.end());
478 // Get the matching note
479 sint matchingNote
= getMatchingNote (iteCombo
->second
.KeyButtons
, newButtons
);
480 if (matchingNote
> bestMatchingNote
)
483 TActionsMap::iterator iteAction
= _Actions
.find (iteWatchedAction
->second
);
484 nlassert (iteAction
!= _Actions
.end());
486 // Memorise the best action
487 bestMatching
= &(iteAction
->second
);
488 bestMatchingNote
= matchingNote
;
494 // Invalide or valide actions
495 while (iteWatchedActionBegin
!= iteWatchedAction
)
498 TActionsMap::iterator iteAction
= _Actions
.find (iteWatchedActionBegin
->second
);
499 nlassert (iteAction
!= _Actions
.end());
501 // Valide or invalide it
502 bool LastValid
= iteAction
->second
.Valide
;
503 iteAction
->second
.Valide
= (&(iteAction
->second
) == bestMatching
);
504 if ((LastValid
== true) && (iteAction
->second
.Valide
== false))
506 // Run the action on keyup
507 if (iteAction
->second
.KeyUp
)
509 iteAction
->second
.runAction ();
514 iteWatchedActionBegin
++;
519 // ***************************************************************************
521 void CCombo::init (NLMISC::TKey key
, NLMISC::TKeyButton keyButtons
)
524 KeyButtons
= keyButtons
;
527 // ***************************************************************************
528 string
CCombo::toString() const
531 if ((KeyButtons
& shiftKeyButton
) && (Key
!= 0x10))
532 ret
+= CI18N::get("uiKeySHIFT") + "+";
533 if ((KeyButtons
& ctrlKeyButton
) && (Key
!= 0x11))
534 ret
+= CI18N::get("uiKeyCONTROL") + "+";
535 if ((KeyButtons
& altKeyButton
) && (Key
!= 0x12))
536 ret
+= CI18N::get("uiKeyMENU") + "+";
537 if (CI18N::hasTranslation("ui"+CEventKey::getStringFromKey(Key
)))
538 ret
+= CI18N::get("ui"+CEventKey::getStringFromKey(Key
));
540 ret
+= CEventKey::getStringFromKey(Key
);
544 // ***************************************************************************
546 const std::vector
<CCategory
> &CActionsManager::getCategories () const
551 // ***************************************************************************
553 void CActionsManager::reserveCategories (uint space
)
555 _Categories
.reserve (space
);
558 // ***************************************************************************
560 void CActionsManager::addCategory (const CCategory
&category
)
562 _Categories
.push_back (category
);
564 // Add an entry in the map to get the base action by the action name
566 for (i
=0; i
<category
.BaseActions
.size (); i
++)
568 CCategoryLocator locator
;
569 locator
.CategoryId
= (uint
)_Categories
.size ()-1;
570 locator
.BaseActionId
= i
;
571 _ActionCategory
.insert (TActionBaseActionMap::value_type (category
.BaseActions
[i
].Name
, locator
));
575 // ***************************************************************************
577 void CActionsManager::removeCategory (const string
&catName
)
579 // Search the category
581 for (catNb
=0; catNb
< _Categories
.size(); ++catNb
)
582 if (_Categories
[catNb
].Name
== catName
)
585 if (catNb
== _Categories
.size()) return;
587 // Remove all entries in the map to get the base action by the action name
588 for (i
=0; i
<_Categories
[catNb
].BaseActions
.size (); i
++)
590 CCategoryLocator locator
;
591 locator
.CategoryId
= catNb
;
592 locator
.BaseActionId
= i
;
593 _ActionCategory
.erase (_Categories
[catNb
].BaseActions
[i
].Name
);
595 _Categories
.erase (_Categories
.begin()+catNb
);
598 // ***************************************************************************
600 void CActionsManager::enable (bool enable
)
605 // ***************************************************************************
607 // ***************************************************************************
609 CBaseAction::CBaseAction ()
614 WaitForServer
= false;
618 // ***************************************************************************
619 bool CBaseAction::isUsableInCurrentContext() const
621 if (ActionsContext
.matchContext(Contexts
))
623 bool cteParamFound
= false;
624 bool matchingParamFound
= false;
625 // now, see if for all the constant parameter for this action,
626 // at least one is valid in current context
627 for (uint l
= 0; l
< Parameters
.size(); ++l
)
629 const CParameter
¶m
= Parameters
[l
];
630 if (param
.Type
== CParameter::Constant
)
632 cteParamFound
= true;
633 for (uint m
= 0; m
< param
.Values
.size(); ++m
)
635 if (ActionsContext
.matchContext(param
.Values
[m
].Contexts
))
637 matchingParamFound
= true;
642 if (matchingParamFound
) break;
644 if (!cteParamFound
|| matchingParamFound
) return true;
649 // ***************************************************************************
651 CBaseAction::CParameter::CParameter ()
657 // ***************************************************************************
659 static bool getParam (CBaseAction::CParameter::TType type
, string
¶mName
, string
¶mValue
, const std::string
&argu
, uint paramId
)
661 const string separator
= "|";
662 const string equal_separator
= "=";
666 string::size_type pos
= 0;
667 while (index
!= paramId
)
670 pos
= argu
.find_first_of(separator
, pos
);
671 if (pos
== string::npos
)
679 if (pos
< argu
.size ())
682 string::size_type end
= argu
.find_first_of(separator
, pos
);
683 if (end
== string::npos
)
687 string::size_type equal
= argu
.find_first_of(equal_separator
, pos
);
688 if ((equal
!= string::npos
) && (equal
>= end
))
689 equal
= string::npos
;
691 // Equal is present ?
692 if (equal
!= string::npos
)
694 // Extract parameter name
695 paramName
= argu
.substr(pos
, equal
-pos
);
700 paramValue
= argu
.substr(pos
, end
-pos
);
708 string
CBaseAction::getActionLocalizedText(const CAction::CName
&name
) const
711 string temp
= CI18N::get(LocalizedName
);
715 for (i
=0; i
<Parameters
.size (); i
++)
717 bool parameterOk
= false;
718 const CParameter
¶meter
= Parameters
[i
];
722 // Get the param from the argu
723 if (getParam (parameter
.Type
, paramName
, paramValue
, name
.Argu
, i
))
725 switch (parameter
.Type
)
727 case CParameter::Hidden
:
728 if ((parameter
.DefaultValue
== paramValue
) && (parameter
.Name
== paramName
))
731 case CParameter::Constant
:
734 for (j
=0; j
<parameter
.Values
.size (); j
++)
737 const CParameter::CValue
&value
= parameter
.Values
[j
];
738 if (value
.Value
== paramValue
)
742 if ((value
.LocalizedValue
.size() >= 2) &&
743 (value
.LocalizedValue
[0]=='u') && (value
.LocalizedValue
[1]=='i'))
744 temp
+= CI18N::get(value
.LocalizedValue
);
746 temp
+= value
.LocalizedValue
;
753 case CParameter::User
:
754 case CParameter::UserName
:
761 // Parameter not found ? Next base action..
768 if (i
==Parameters
.size ())
774 // ***************************************************************************
776 // ***************************************************************************
778 const CActionsManager::TComboActionMap
&CActionsManager::getComboActionMap () const
783 // ***************************************************************************
785 const CActionsManager::TActionComboMap
&CActionsManager::getActionComboMap () const
790 // ***************************************************************************
792 const CActionsManager::CCategoryLocator
*CActionsManager::getActionLocator (const CAction::CName
&name
) const
794 // Look for the base action
795 TActionBaseActionMap::const_iterator ite
= _ActionCategory
.find (name
.Name
);
796 while ((ite
!= _ActionCategory
.end ()) && (ite
->first
== name
.Name
))
798 // Ref on the base action
799 const CCategory
&cat
= _Categories
[ite
->second
.CategoryId
];
800 uint baseActionId
= ite
->second
.BaseActionId
;
801 uint baseActionSize
= cat
.BaseActions
.size();
803 if( ite
->second
.BaseActionId
>= cat
.BaseActions
.size() )
806 const CBaseAction
&baseAction
= cat
.BaseActions
[ite
->second
.BaseActionId
];
810 uint s
= baseAction
.Parameters
.size();
814 bool parameterOk
= false;
815 const CBaseAction::CParameter
¶meter
= baseAction
.Parameters
[i
];
819 // Get the param from the argu
820 if (getParam (parameter
.Type
, paramName
, paramValue
, name
.Argu
, i
))
822 switch (parameter
.Type
)
824 case CBaseAction::CParameter::Hidden
:
825 if ((parameter
.DefaultValue
== paramValue
) && (parameter
.Name
== paramName
))
828 case CBaseAction::CParameter::Constant
:
830 // If the value of the action param match with one of the values of the base action param so its ok
832 for (j
=0; j
<parameter
.Values
.size (); j
++)
834 const CBaseAction::CParameter::CValue
&value
= parameter
.Values
[j
];
835 if (value
.Value
== paramValue
)
843 case CBaseAction::CParameter::User
:
844 case CBaseAction::CParameter::UserName
:
850 // Parameter not found ? Next base action..
856 if (i
==baseAction
.Parameters
.size ())
865 // ***************************************************************************
866 const CBaseAction
*CActionsManager::getBaseAction (const CAction::CName
&name
) const
868 const CCategoryLocator
*pCL
= getActionLocator(name
);
869 if (pCL
== NULL
) return NULL
;
870 return &_Categories
[pCL
->CategoryId
].BaseActions
[pCL
->BaseActionId
];
873 // ***************************************************************************
874 void CActionsManager::removeBaseAction(const CAction::CName
&name
)
876 const CCategoryLocator
*pCL
= getActionLocator(name
);
879 nlwarning("Action %s %s not found.", name
.Name
.c_str(), name
.Argu
.c_str());
882 std::vector
<CBaseAction
> &baseActions
= _Categories
[pCL
->CategoryId
].BaseActions
;
883 baseActions
.erase(baseActions
.begin() + pCL
->BaseActionId
);
886 // ***************************************************************************
887 const CCategory
*CActionsManager::getCategory (const CAction::CName
&name
) const
889 const CCategoryLocator
*pCL
= getActionLocator(name
);
890 if (pCL
== NULL
) return NULL
;
891 return &_Categories
[pCL
->CategoryId
];
895 // ***************************************************************************
896 void CActionsManager::forceDisplayForAction(const CAction::CName
&name
, bool state
)
899 _ActionForceDisplay
.insert(name
);
901 _ActionForceDisplay
.erase(name
);
904 // ***************************************************************************
905 bool CActionsManager::isActionDisplayForced(const CAction::CName
&name
) const
907 return _ActionForceDisplay
.find(name
)!=_ActionForceDisplay
.end();
910 // ***************************************************************************
911 string
CActionsManager::getActionLocalizedText (const CAction::CName
&name
) const
913 const CBaseAction
*baseAction
= getBaseAction(name
);
916 return baseAction
->getActionLocalizedText(name
);
920 // ***************************************************************************
922 // ***************************************************************************
925 CActionsContext::CActionsContext()
930 bool CActionsContext::addActionsManager (CActionsManager
*actionManager
, const std::string
&category
)
932 return _ActionsManagers
.insert (TActionsManagerMap::value_type(category
, actionManager
)).second
;
935 // ***************************************************************************
936 CActionsManager
*CActionsContext::getActionsManager (const std::string
&category
) const
938 TActionsManagerMap::const_iterator ite
= _ActionsManagers
.find (category
);
939 if (ite
!= _ActionsManagers
.end())
943 ite
= _ActionsManagers
.find ("");
944 if (ite
!= _ActionsManagers
.end())
950 // ***************************************************************************
951 bool CActionsContext::matchContext(const std::string
&contexts
) const
953 std::vector
<std::string
> contextList
;
954 splitString(contexts
, ",", contextList
);
955 for (uint k
= 0; k
< contextList
.size(); ++k
)
957 std::string currContext
= contextList
[k
];
958 while(strFindReplace(currContext
, " ", ""));
959 while(strFindReplace(currContext
, "\t", ""));
960 if (nlstricmp(currContext
, _Context
) == 0) return true;
965 // ***************************************************************************
966 void CActionsContext::removeAllCombos()
968 for (TActionsManagerMap::iterator it
= _ActionsManagers
.begin(); it
!= _ActionsManagers
.end(); ++it
)
970 it
->second
->removeAllCombos();
974 // ***************************************************************************