1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #ifndef SUIT_SHORTCUTMGR_H
24 #define SUIT_SHORTCUTMGR_H
30 #include <QStringList>
43 #pragma warning( disable: 4251 )
46 // Define SHORTCUT_MGR_DBG to enable SUIT_ShortcutMgr debug logging.
47 // #define SHORTCUT_MGR_DBG
48 /*! \returns true, if SUIT_ShortcutMgr debug logging is enabled. */
49 SUIT_EXPORT extern inline bool ShCutDbg() {
50 #ifdef SHORTCUT_MGR_DBG
56 /*! \brief Prints theString to std::wcout, if SUIT_ShortcutMgr debug logging is enabled. */
57 SUIT_EXPORT extern bool ShCutDbg(const QString& theString);
58 /*! \brief Prints theString to std::wcout, if SUIT_ShortcutMgr debug logging is enabled. */
59 SUIT_EXPORT extern bool ShCutDbg(const char* theString);
63 \class SUIT_ShortcutContainer
64 \brief Provides means to keep and edit shortcuts in compliance with the application logics.
65 \ref See SUIT_ShortcutMgr for details.
67 class SUIT_EXPORT SUIT_ShortcutContainer
70 SUIT_ShortcutContainer();
72 /*! \returns IDs of modules, which interfere with the module:
73 if the module is root (theModuleID is empty) - returns all module IDs, otherwise returns ["", theModuleID]. */
74 std::set<QString> getIDsOfInterferingModules(const QString& theModuleID) const;
76 std::set<QString> getIDsOfAllModules() const;
78 /*! \brief Checks for conflicts. If theOverride, modifies incoming and disables all conflicting shortcuts.
79 Redefining a key sequence for the action, if theKeySequence does not conflict with other shortcuts, is not considered as a conflict.
80 \param theModuleID The method has no effect if theModuleID is invalid. \ref See SUIT_ShortcutMgr::isModuleIDValid(const QString&) for details.
81 \param theInModuleActionID The method has no effect if theInModuleActionID is invalid. \ref See SUIT_ShortcutMgr::isInModuleActionIDValid(const QString&).
82 If theInModuleActionID is meta-action ID, the shortcut is set to root module, and theModuleID is ignored.
83 \param theKeySequence Empty theKeySequence does not cause conflicts, in this case
84 a shortcut for the action is disabled: theInModuleActionID is added/retained in the container but mapped to empty key sequence.
85 \param theOverride If true, conflicting shortcuts are disabled.
86 \returns {moduleID, inModuleActionID}[] - Set of conflicting actions if theOverride = false,
87 otherwise set of actions (without incoming one), whose shortcuts have been disabled. */
88 std::set<std::pair<QString, QString>> setShortcut(
90 const QString& theInModuleActionID,
91 const QKeySequence& theKeySequence,
95 /*! \brief Checks for conflicts. Existence of a shortcut with another key sequence for the action,
96 if theKeySequence does not conflict with other shortcuts, is not considered as a conflict.
97 \param theInModuleActionID If theInModuleActionID is meta-action ID, the shortcut is looked for in root module, and theModuleID is ignored.
98 \param theKeySequence Empty theKeySequence does not have conflicts.
99 \returns {moduleID, inModuleActionID}[] - Set of conflicting actions. */
100 std::set<std::pair<QString, QString>> getConflicts(
102 const QString& theInModuleActionID,
103 const QKeySequence& theKeySequence
106 /*! \returns empty key sequence if shortcut for the action is not set.
107 \param theInModuleActionID If theInModuleActionID is meta-action ID, seeks in root module, and theModuleID is ignored.*/
108 const QKeySequence& getKeySequence(QString theModuleID, const QString& theInModuleActionID) const;
110 /*! \returns true, if shortcut for the action is set (even if the mapped key sequence is empty).
111 \param theInModuleActionID If theInModuleActionID is meta-action ID, seeks in root module, and theModuleID is ignored.*/
112 bool hasShortcut(QString theModuleID, const QString& theInModuleActionID) const;
114 /*! \returns {inModuleActionID, keySequence}[] - If the module was not added, the map is empty. */
115 const std::map<QString, QKeySequence>& getModuleShortcutsInversed(const QString& theModuleID) const;
117 /*! \brief Seeks for shortcuts in the module with in-module action IDs, which start with theInModuleActionIDPrefix.
118 \returns {inModuleActionID, keySequence}[] - If the module was not added, the map is empty. */
119 const std::map<QString, QKeySequence> getModuleShortcutsInversed(const QString& theModuleID, const QString& theInModuleActionIDPrefix) const;
121 /*! \brief Merges shortcuts of theOther into this.
122 \param theOverride if true, overrides conflicting shortcuts.
123 If false, and this has no shortcut for an incoming action, and the incoming shortcut conflicts
124 with an existing shortcut, disabled shortcut for the incoming action is set.
125 \param theTreatAbsentIncomingAsDisabled If theOverride == false, theTreatAbsentIncomingAsDisabled is ignored.
126 If theOverride and theTreatAbsentIncomingAsDisabled, and theOther has no shortcut for an action, which exists in this,
127 the existing shortcut in this is set disabled.
128 \returns { moduleID, { inModuleActionID, keySequence }[] }[] - Modiified shortcuts inversed. */
129 std::map<QString, std::map<QString, QKeySequence>> merge(
130 const SUIT_ShortcutContainer& theOther,
132 bool theTreatAbsentIncomingAsDisabled = false
135 /*! \brief Generates human-readable text representation of content. */
136 QString toString() const;
139 /** { moduleID, { keySequence, inModuleActionID }[] }[]. keySequence can not be empty.
140 * Can not contain entries like { <non-root module ID>, { keySequence, <meta-action ID> } }. */
141 std::map<QString, std::map<QKeySequence, QString>> myShortcuts;
143 /** { moduleID, { inModuleActionID, keySequence }[] }[]. keySequence can be empty.
144 * Can not contain entries like { <non-root module ID>, { <meta-action ID>, keySequence } }. */
145 std::map<QString, std::map<QString, QKeySequence>> myShortcutsInversed;
149 /*! \brief GUI-related assets. */
150 struct SUIT_EXPORT SUIT_ActionAssets
152 struct LangDependentAssets
154 static const QString PROP_ID_NAME;
155 static const QString PROP_ID_TOOLTIP;
157 bool fromJSON(const QJsonObject& theJsonObject);
158 void toJSON(QJsonObject& oJsonObject) const;
164 static const QString STRUCT_ID;
165 static const QString PROP_ID_LANG_DEPENDENT_ASSETS;
166 static const QString PROP_ID_ICON_PATH;
168 bool fromJSON(const QJsonObject& theJsonObject);
169 void toJSON(QJsonObject& oJsonObject) const;
170 QString toString() const;
172 QStringList getLangs() const;
173 void clearAllLangsExcept(const QString& theLang);
175 /*! \param theOverride If true, values of theOther override conflicting values of this. */
176 void merge(const SUIT_ActionAssets& theOther, bool theOverride);
178 std::map<QString, LangDependentAssets> myLangDependentAssets;
181 /*! Is not serialized. */
187 \class SUIT_ShortcutMgr
188 \brief Handles action shortcut customization.
190 Register actions under action IDs. Set shortcuts, which are [action ID]<->[key sequence] mappings.
191 Every time an action is registered or a shorcut is set, if there are an action and a shortcut,
192 which are mapped to the same action ID, the action is bound to the key sequence of the shortcut.
193 Action IDs are also used to (de)serialize shortcut settings.
194 Several QActions may be registered under the same ID.
196 Most of actions are intercepted on creation in SUIT_ShortcutMgr:eventFilter(QObject* theObject, QEvent* theEvent).
197 If an intercepted action is instance of QtxAction, it is registered automatically.
198 Since non-QtxActions have no member ID(), SUIT_ShortcutMgr is unable to register them automatically
199 in SUIT_ShortcutMgr::eventFilter(). Thus, every non-QtxAction should be
200 passed to SUIT_ShortcutMgr::registerAction(const QString& theActionID, QAction* theAction).
202 Action ID is application-unique must be composed as <moduleID>/<inModuleActionID>.
203 If an action belongs to a desktop or is available even if no module is active (e.g. 'Save As'),
204 use empty string as <moduleID>. Let's call such actions as root actions.
206 There is a need to keep multiple actions, which do the same from user' perspective,
207 bound to the same key sequence. E.g. 'Front view'. Let's call such set of actions as meta-action.
208 Actions of a meta-action may belong to different modules, and/or there may be several actions
209 of the same meta-action in the same module. <inModuleActionID> of all members of a meta-action
210 must be the same and start with "#".
211 Meta-action is root action when it comes to checking for conflicts.
212 Shortcuts of meta-actions are (de)serialized to the same section of preference files as root shortcuts.
214 <inModuleActionID> can contain several "/". Go to \ref isInModuleActionIDValid(const QString&) for details.
215 You can refer to multiple actions, whose <inModuleActionID> starts with the prefix.
217 Only one module can be active at instance. So a key sequence must be unique within a joined temporary table of
218 root and active module shortcuts. An action is allowed to be bound with only key sequence.
221 Avoid assigning shortcuts to instances of QAction and all its descendants directly.
222 (1) Key sequence being bound directly to any registered/intercepted action with valid ID,
223 if the key sequence does not conflict with shortcuts kept by SUIT_ShortcutMgr,
224 is added to the manager and appears in user preference file. If it does conflict,
225 it is reassigned with a key sequence from preference files or
226 disabled and added to user preference files (if the files have no shortcut for the action).
227 (2) Key sequences being bound directly to non-QtxAction instances are disabled.
229 class SUIT_EXPORT SUIT_ShortcutMgr: public QObject
235 SUIT_ShortcutMgr(const SUIT_ShortcutMgr&) = delete;
236 SUIT_ShortcutMgr& operator=(const SUIT_ShortcutMgr&) = delete;
239 virtual ~SUIT_ShortcutMgr();
242 static const QString ROOT_MODULE_ID;
244 /*! \brief Create new singleton-instance of shortcut manager, if it has not been created. */
247 static SUIT_ShortcutMgr* get();
249 /*! \brief Checks whether the theKeySequence is platform-compatible. */
250 static bool isKeySequenceValid(const QKeySequence& theKeySequence);
252 /*! \returns {false, _ } if theKeySequenceString is invalid. */
253 static std::pair<bool, QKeySequence> toKeySequenceIfValid(const QString& theKeySequenceString);
255 /*! \brief Valid module ID does not contain "/" and equals to result of QString(theModuleID).simplified().
256 Empty module ID is valid - it is root module ID. */
257 static bool isModuleIDValid(const QString& theModuleID);
259 /*! \brief Valid in-module action ID may consist of several tokens, separated by "/":
260 <token_0>/<token_1>...<token_N>/<token_N-1>.
261 Each <token> must be non-empty and be equal to QString(<token>).simplified().
262 Empty or "#" in-module action ID is not valid. */
263 static bool isInModuleActionIDValid(const QString& theInModuleActionID);
265 /*! \returns true, is theInModuleActionID starts with "#". */
266 static bool isInModuleMetaActionID(const QString& theInModuleActionID);
268 /*! \brief Extracts module ID and in-module action ID from application-unique action ID.
269 The theActionID must be composed as <moduleID>/<inModuleActionID>.
270 \returns { _ , "" }, if theActionID is invalid. */
271 static std::pair<QString, QString> splitIntoModuleIDAndInModuleID(const QString& theActionID);
273 /*! See \ref splitIntoModuleIDAndInModuleID(const QString&). */
274 static bool isActionIDValid(const QString& theActionID);
276 /*! \brief Creates application-unique action ID. Reverse to splitIntoModuleIDAndInModuleID.
277 \returns Emppty string, if either theModuleID or theInModuleActionID is invalid*/
278 static QString makeActionID(const QString& theModuleID, const QString& theInModuleActionID);
280 /*! \brief Sets all shortcuts from preferences to theContainer. Incoming shortcuts override existing ones.
281 If the container has shortcut for an action, which is absent in preferences, and the existing shortcut
282 does not conflict with incoming ones, it is untouched.
283 See \ref setShortcutsFromPreferences() for details.
284 \param theDefaultOnly If true, user preferences are ignored and only default preferences are used. */
285 static void fillContainerFromPreferences(SUIT_ShortcutContainer& theContainer, bool theDefaultOnly);
287 /*! \brief Checks the resource manager directly.
288 \returns {assetsExist, assets}. */
289 static std::pair<bool, SUIT_ActionAssets> getActionAssetsFromResources(const QString& theActionID);
291 /*! \returns Language being set in resource manager. */
292 static QString getLang();
295 /*! \brief Add theAction to map of managed actions. */
296 void registerAction(const QString& theActionID, QAction* theAction);
298 /*! \brief Add theAction to map of managed actions. QtxAction::ID() is used as action ID. */
299 void registerAction(QtxAction* theAction);
301 /*! \brief Get registered actions. If theInModuleActionID is meta-action ID, seeks in all modules. */
302 std::set<QAction*> getActions(const QString& theModuleID, const QString& theInModuleActionID) const;
304 /*! \brief Get module ID and in-module-ID of theAction.
305 \returns { _ , "" } if theAction is not registered. */
306 std::pair<QString, QString> getModuleIDAndInModuleID(const QAction* theAction) const;
308 /*! Returns true if theAction is registered. */
309 bool hasAction(const QAction* theAction) const;
311 /*! \brief Get action ID of theActon.
312 \returns empty string if theAction is not registered. */
313 QString getActionID(const QAction* theAction) const;
315 /*! \brief Enables/disable actions of the module.
316 Only those actions are affected, whose parent widget is active desktop. */
317 void setActionsOfModuleEnabled(const QString& theModuleID, const bool theEnable = true) const;
319 /*! \brief Enables/disables all registered actions whose in-module action ID begins with theInModuleActionIDPrefix.
320 Only those actions are affected, whose parent widget is active desktop. */
321 void setActionsWithPrefixInIDEnabled(const QString& theInModuleActionIDPrefix, bool theEnable = true) const;
323 [[deprecated("Use setActionsWithPrefixInIDEnabled(const QString&, bool) instead.")]]
324 void setSectionEnabled(const QString& theInModuleActionIDPrefix, bool theEnable = true) const;
326 /*! \brief For all registered actions binds key sequences from myShortcutContainer. */
327 void rebindActionsToKeySequences() const;
329 [[deprecated("Use rebindActionsToKeySequences() instead.")]]
330 void updateShortcuts() const;
332 /*! \brief Checks for conflicts. If theOverride, modifies incoming and disables all conflicting shortcuts.
333 Then binds key sequences with corresponding registered actions. Saves changes to preferences.
335 Redefining a key sequence for the action, if the key sequence does not conflict with other shortcuts, is not considered as a conflict.
336 \param theInModuleActionID The method has no effect if theInModuleActionID is empty.
337 \param theKeySequence Empty theKeySequence does not cause conflicts, in this case
338 a shortcut for the action is disabled: theInModuleActionID is added/retained in the container but mapped to empty key sequence.
339 \param theOverride If true, conflicting shortcuts are disabled.
340 \returns {moduleID, inModuleActionID}[] - Set of conflicting actions if theOverride = false,
341 otherwise set of actions (without incoming one), whose shortcuts have been disabled. */
342 std::set<std::pair<QString, QString>> setShortcut(const QString& theActionID, const QKeySequence& theKeySequence, bool theOverride = false);
343 std::set<std::pair<QString, QString>> setShortcut(const QString& theModuleID, const QString& theInModuleActionID, const QKeySequence& theKeySequence, bool theOverride = false);
345 const SUIT_ShortcutContainer& getShortcutContainer() const;
347 /*! \brief Does not perform validity checks on theModuleID and theInModuleActionID. */
348 void mergeShortcutContainer(const SUIT_ShortcutContainer& theContainer, bool theOverride = true, bool theTreatAbsentIncomingAsDisabled = false);
350 /*! \brief Get a key sequence mapped to the action. */
351 QKeySequence getKeySequence(const QString& theModuleID, const QString& theInModuleActionID) const;
353 /*! \returns {inModuleActionID, keySequence}[] */
354 const std::map<QString, QKeySequence>& getModuleShortcutsInversed(const QString& theModuleID) const;
356 /*! \returns All module IDs, which were added to myShortcutContainer. */
357 std::set<QString> getShortcutModuleIDs() const;
359 /*! \returns IDs of modules, which interfere with the module:
360 if the module is root (theModuleID is empty) - returns all module IDs, otherwise returns ["", theModuleID]. */
361 std::set<QString> getIDsOfInterferingModules(const QString& theModuleID) const;
363 std::shared_ptr<const SUIT_ActionAssets> getModuleAssets(const QString& theModuleID) const;
365 /*! \brief Retrieves module name, if the asset was loaded using \ref setAssetsFromResources(). If theLang is empty, it is effectively current language. */
366 QString getModuleName(const QString& theModuleID, const QString& theLang = "") const;
368 std::shared_ptr<const SUIT_ActionAssets> getActionAssets(const QString& theModuleID, const QString& theInModuleActionID) const;
370 std::shared_ptr<const SUIT_ActionAssets> getActionAssets(const QString& theActionID) const;
372 std::map<QString, std::map<QString, std::shared_ptr<SUIT_ActionAssets>>> getActionAssets() const { return myActionAssets; }
374 std::map<QString, std::shared_ptr<SUIT_ActionAssets>> getModuleAssets() const { return myModuleAssets; }
376 /*! \brief Retrieves action name, if the asset was loaded using \ref setAssetsFromResources(). If theLang is empty, it is effectively current language. */
377 QString getActionName(const QString& theModuleID, const QString& theInModuleActionID, const QString& theLang = "") const;
381 \brief Called when the corresponding action is destroyed.
382 Removes destroyed action from maps of registered actions. Preserves shortcut.
383 \param theObject action being destroyed.
385 void onActionDestroyed(QObject* theObject);
388 /*! \brief Overrides QObject::eventFilter().
389 If theEvent is QEvent::ActionAdded and the action is instance of QtxAction, registers it. */
390 virtual bool eventFilter(QObject* theObject, QEvent* theEvent);
392 /*! \brief Does not perform validity checks on theModuleID and theInModuleActionID. */
393 std::set<std::pair<QString, QString>> setShortcutNoIDChecks(const QString& theModuleID, const QString& theInModuleActionID, const QKeySequence& theKeySequence, bool theOverride);
395 /*! \brief Set shortcuts from preference files. The method is intended to be called before any calls to setShortcut() or mergeShortcutContainer().
396 Definition of this method assumes, that shortcut settings are serialized as prerefence entries {name=<inModuleActionID>, val=<keySequence>}
397 in dedicated section for each module, with names of sections being composed as "shortcuts:<moduleID>".
399 E.g. in case of XML file it may look like this:
401 <section name="<module ID>">
403 <parameter name="<in-module action ID>" value="key sequence">
407 <section name="shortcuts:">
408 <parameter name="TOT_DESK_FILE_NEW" value="Ctrl+N"/>
409 <parameter name="TOT_DESK_FILE_OPEN" value="Ctrl+O"/>
410 <parameter name="#General/Show object(s)" value="Ctrl+Alt+S"/>
411 <parameter name="#General/Hide object(s)" value="Ctrl+Alt+H"/>
412 <parameter name="#Viewers/Back view" value="Ctrl+Alt+B"/>
413 <parameter name="#Viewers/Front view" value="Ctrl+Alt+F"/>
415 <section name="shortcuts:GEOM">
416 <parameter name="Isolines/Increase number" value="Meta+I"/>
417 <parameter name="Isolines/Decrease number" value="Meta+D"/>
418 <parameter name="Transparency/Increase" value="Meta+Y"/>
419 <parameter name="Transparency/Decrease" value="Meta+T"/>
422 Empty inModuleActionIDs are ignored.
424 nb! For any theQtxAction you wish user be able to assign it to a shortcut,
425 add theQtxAction.ID() to default resource files (you can map it to no key sequence).*/
426 void setShortcutsFromPreferences();
428 /*! \brief Writes shortcuts to preference files.
429 \param theShortcuts { moduleID, { inModuleActionID, keySequence }[] }[]. Empty inModuleActionIDs are ignored. */
430 static void saveShortcutsToPreferences(const std::map<QString, std::map<QString, QKeySequence>>& theShortcutsInversed);
432 /*! Fills myActionAssets from asset files in theLanguage.
433 \param theLanguage If default, fills assets in current language.
434 If an asset in requested language is not found, seeks for the asset EN in and then in FR.
436 Asset files must be structured like this:
440 "langDependentAssets": {
453 void setAssetsFromResources(QString theLanguage = QString());
456 static SUIT_ShortcutMgr* myShortcutMgr;
458 /** { moduleID, { inModuleActionID, action[] }[] }[]. May contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }. */
459 std::map<QString, std::map<QString, std::set<QAction*>>> myActions;
461 /** { action, { moduleID, inModuleActionID } }[]. May contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }. */
462 std::map<QAction*, std::pair<QString, QString>> myActionIDs; // To maintain uniqueness of actions and effectively retrieve IDs of registered actions.
464 /** Can not contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }. */
465 SUIT_ShortcutContainer myShortcutContainer;
468 Sets of moduleIDs and inModuleActionIDs are equal for myActions and myActionIDs.
469 Sets of moduleIDs and inModuleActionIDs may NOT be equal for myActions and myShortcutContainer.
472 /* { moduleID, {inModuleActionID, assets}[] }[] */
473 std::map<QString, std::map<QString, std::shared_ptr<SUIT_ActionAssets>>> myActionAssets;
475 /* {moduleID, assets}[] */
476 mutable std::map<QString, std::shared_ptr<SUIT_ActionAssets>> myModuleAssets;
481 \class SUIT_SentenceMatcher
482 \brief Approximate string matcher, treats strings as sentences composed of words.
484 class SUIT_EXPORT SUIT_SentenceMatcher
488 Exact word order = false;
490 Case sensitive = false;
491 Query = ""; // matches nothing.
493 SUIT_SentenceMatcher();
495 void setUseExactWordOrder(bool theOn);
496 void setUseFuzzyWords(bool theOn);
497 void setCaseSensitive(bool theOn);
498 inline bool isCaseSensitive() const { return myIsCaseSensitive; };
500 /*! \param theQuery should not be regex. */
501 void setQuery(QString theQuery);
503 inline const QString& getQuery() const { return myQuery; };
505 /*! \returns number of matched words. */
506 size_t match(const QString& theInputString) const;
508 QString toString() const;
511 static bool makePermutatedSentences(const QStringList& theWords, QList<QStringList>& theSentences);
512 static void makeFuzzyWords(const QStringList& theWords, QStringList& theFuzzyWords);
514 static size_t matchWithSentenceIgnoreEndings(const QString& theInputString, const QStringList& theSentence, bool theCaseSensitive);
515 static size_t matchWithSentencesIgnoreEndings(const QString& theInputString, const QList<QStringList>& theSentences, bool theCaseSensitive);
517 static size_t matchAtLeastOneWord(const QString& theInputString, const QStringList& theWords, bool theCaseSensitive);
520 const QString& theInputString,
521 const QStringList& theSentence,
522 bool theCaseSensitive
526 const QString& theInputString,
527 const QList<QStringList>& theSentences,
528 bool theCaseSensitive
531 bool myUseExactWordOrder; // If false, try to match with sentences, composed of query's words in different orders.
532 bool myUseFuzzyWords; // Try to match with sentences, composed of query's truncated words.
533 bool myIsCaseSensitive;
536 QStringList myWords; // It is also original search sentence.
537 QList<QStringList> myPermutatedSentences;
539 QStringList myFuzzyWords; // Regexes.
540 QList<QStringList> myFuzzyPermutatedSentences;
544 typedef std::map<QString, std::map<QString, std::shared_ptr<SUIT_ActionAssets>>> SUIT_ActionAssetsMap2;
548 \class SUIT_ActionSearcher
549 \brief Searches in data, provided in action asset files and shortcut preferences.
551 class SUIT_EXPORT SUIT_ActionSearcher
561 struct AssetsAndSearchData
563 AssetsAndSearchData() = default;
564 AssetsAndSearchData(std::shared_ptr<SUIT_ActionAssets> theAssets, size_t theNumOfMatchingWords);
566 std::shared_ptr<SUIT_ActionAssets> myAssets;
567 size_t myNumOfMatchingWords;
569 void toJSON(QJsonObject& oJsonObject) const;
570 QString toString() const;
574 Included modules' IDs = { ROOT_MODULE_ID };
575 Include disabled actions = false;
576 Fields to match = { Name, Tooltip };
577 Case sensitive = false;
578 Fuzzy matching = true;
579 Query = ""; // matches everything.
581 SUIT_ActionSearcher();
582 SUIT_ActionSearcher(const SUIT_ActionSearcher&) = delete;
583 SUIT_ActionSearcher& operator=(const SUIT_ActionSearcher&) = delete;
584 virtual ~SUIT_ActionSearcher() = default;
586 /*! \returns true, if set of results is changed. */
587 bool setIncludedModuleIDs(std::set<QString> theIncludedModuleIDs);
589 /*! \returns true, if set of results is changed. */
590 bool includeDisabledActions(bool theOn);
591 inline bool areDisabledActionsIncluded() const {return myIncludeDisabledActions;};
593 /*! \returns true, if set of results is changed. */
594 bool setFieldsToMatch(const std::set<SUIT_ActionSearcher::MatchField>& theFields);
596 /*! \returns true, if set of results is changed. */
597 bool setCaseSensitive(bool theOn);
599 /*! \returns true, if set of results is changed. */
600 bool setQuery(const QString& theQuery);
601 inline const QString& getQuery() const {return myMatcher.getQuery();};
603 const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& getSearchResults() const;
607 /*! \brief Applies filter to all actions, provided in asset files for SUIT_ShortcutMgr.
608 \returns { true, _ } if set of results is changed; { _ , true } if number of matching words is changed for at least one result. */
609 std::pair<bool, bool> filter();
611 /*! \brief Applies filter to search results only.
612 \returns { true, _ } if set of results is shrunk; { _ , true } if number of matching words is changed for at least one result. */
613 std::pair<bool, bool> filterResults();
615 /*! \brief Applies filter only to actions, which are not in search results.
616 \returns True, if set of results is extended. */
617 bool extendResults();
619 size_t matchAction(const QString& theModuleID, const QString& theInModuleActionID, std::shared_ptr<SUIT_ActionAssets> theAssets);
621 QString toString() const;
624 std::set<QString> myIncludedModuleIDs;
625 bool myIncludeDisabledActions;
627 std::set<SUIT_ActionSearcher::MatchField> myFieldsToMatch;
628 SUIT_SentenceMatcher myMatcher;
630 /* { moduleID, {inModuleActionID, assetsAndSearchData}[] }[]. */
631 std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>> mySearchResults;
636 #pragma warning( default: 4251 )