Version: 9.15.0
SUIT_ShortcutMgr Class Reference

Handles action shortcut customization. More...

#include <SUIT_ShortcutMgr.h>

Inheritance diagram for SUIT_ShortcutMgr:
Inheritance graph

Public Member Functions

void registerAction (const QString &theActionID, QAction *theAction)
 Add theAction to map of managed actions. More...
 
void registerAction (QtxAction *theAction)
 Add theAction to map of managed actions. QtxAction::ID() is used as action ID. More...
 
std::set< QAction * > getActions (const QString &theModuleID, const QString &theInModuleActionID) const
 Get registered actions. If theInModuleActionID is meta-action ID, seeks in all modules. More...
 
std::pair< QString, QString > getModuleIDAndInModuleID (const QAction *theAction) const
 Get module ID and in-module-ID of theAction. More...
 
bool hasAction (const QAction *theAction) const
 
QString getActionID (const QAction *theAction) const
 Get action ID of theActon. More...
 
void setActionsOfModuleEnabled (const QString &theModuleID, const bool theEnable=true) const
 Enables/disable actions of the module. Only those actions are affected, whose parent widget is active desktop. More...
 
void setSectionEnabled (const QString &theInModuleActionIDPrefix, bool theEnable=true) const
 
void setActionsWithPrefixInIDEnabled (const QString &theInModuleActionIDPrefix, bool theEnable=true) const
 Enables/disables all registered actions whose in-module action ID begins with theInModuleActionIDPrefix. Only those actions are affected, whose parent widget is active desktop. More...
 
void rebindActionsToKeySequences () const
 For all registered actions binds key sequences from myShortcutContainer. More...
 
void updateShortcuts () const
 
std::set< std::pair< QString, QString > > setShortcut (const QString &theActionID, const QKeySequence &theKeySequence, bool theOverride=false)
 Checks for conflicts. If theOverride, modifies incoming and disables all conflicting shortcuts. Then binds key sequences with corresponding registered actions. Saves changes to preferences. More...
 
std::set< std::pair< QString, QString > > setShortcut (const QString &theModuleID, const QString &theInModuleActionID, const QKeySequence &theKeySequence, bool theOverride=false)
 
const SUIT_ShortcutContainergetShortcutContainer () const
 
void mergeShortcutContainer (const SUIT_ShortcutContainer &theContainer, bool theOverride=true, bool theTreatAbsentIncomingAsDisabled=false, bool theSaveToPreferences=true)
 Does not perform validity checks on theModuleID and theInModuleActionID. More...
 
const QKeySequence & getKeySequence (const QString &theModuleID, const QString &theInModuleActionID) const
 Get a key sequence mapped to the action. More...
 
const std::map< QString, QKeySequence > & getModuleShortcutsInversed (const QString &theModuleID) const
 
std::set< QString > getShortcutModuleIDs () const
 
std::set< QString > getIDsOfInterferingModules (const QString &theModuleID) const
 
std::shared_ptr< const SUIT_ShortcutModuleAssetsgetModuleAssets (const QString &theModuleID) const
 
const std::map< QString, std::shared_ptr< SUIT_ShortcutModuleAssets > > & getModuleAssets () const
 
QString getModuleName (const QString &theModuleID, const QString &theLang="") const
 Retrieves module name, if the asset was loaded using setAssetsFromResources(). If theLang is empty, it is current language. More...
 
std::shared_ptr< const SUIT_ShortcutItemAssetsgetActionAssets (const QString &theModuleID, const QString &theInModuleActionID, bool theTryToCreateRuntimeAssetsIfAbsent=true) const
 
std::shared_ptr< const SUIT_ShortcutItemAssetsgetActionAssets (const QString &theActionID, bool theTryToCreateRuntimeAssetsIfAbsent=true) const
 
std::shared_ptr< const SUIT_ShortcutItemAssetscreateRuntimeActionAssets (const QString &theModuleID, const QString &theInModuleActionID) const
 Creates assets using action instance fields, if corresponding action is registered. More...
 
QString getActionName (const QString &theModuleID, const QString &theInModuleActionID, const QString &theLang="") const
 Retrieves action name, if the asset is myModuleAssets. Name of module is not included. If theLang is empty, it is current language. More...
 
QtxActioncreateAction (QObject *theParent, QObject *theReceiver, const char *theReceiverSlot, const QString &theActionID, const bool theIsToggle=false) const
 Creates an action and sets asset data to the action. More...
 

Static Public Member Functions

static void Init ()
 Create new singleton-instance of shortcut manager, if it has not been created. More...
 
static SUIT_ShortcutMgrget ()
 
static bool isKeySequenceValid (const QKeySequence &theKeySequence)
 Checks whether the theKeySequence is platform-compatible. More...
 
static std::pair< bool, QKeySequence > toKeySequenceIfValid (const QString &theKeySequenceString)
 
static bool isModuleIDValid (const QString &theModuleID)
 Valid module ID does not contain "/" and equals to result of QString(theModuleID).simplified(). Empty module ID is valid - it is root module ID. More...
 
static bool isInModuleIDTokenValid (const QString &theInModuleIDToken)
 
static bool isInModuleIDTokenMeta (const QString &theInModuleIDToken)
 
static bool isInModuleActionIDValid (const QString &theInModuleActionID)
 Valid in-module action ID may consist of several tokens, separated by "/": <token_0>/<token_1>...<token_N>/<token_N-1>. Each <token> must be non-empty and be equal to QString(<token>).simplified(). Token "#" is also not valid, since the character in the beginning of the last token means action is meta-action. More...
 
static bool isInModuleMetaActionID (const QString &theInModuleActionID)
 
static std::pair< QString, QString > splitIntoModuleIDAndInModuleID (const QString &theActionID)
 Extracts module ID and in-module action ID from application-unique action ID. The theActionID must be composed as <moduleID>/<inModuleActionID>. More...
 
static QStringList splitIntoTokens (const QString &theRelativeID)
 Does not check validity. More...
 
static QString joinIntoRelativeID (const QStringList &theTokens)
 Does not check validity. More...
 
static bool isActionIDValid (const QString &theActionID)
 
static QString makeActionID (const QString &theModuleID, const QString &theInModuleActionID)
 Creates application-unique action ID. Reverse to splitIntoModuleIDAndInModuleID. More...
 
static void fillContainerFromPreferences (SUIT_ShortcutContainer &theContainer, bool theDefaultOnly)
 Sets all shortcuts from preferences to theContainer. Incoming shortcuts override existing ones. If the container has shortcut for an action, which is absent in preferences, and the existing shortcut does not conflict with incoming ones, it is untouched. See setShortcutsFromPreferences() for details. More...
 
static void fillContainerFromPreferences (SUIT_ShortcutContainer &theContainer, bool theDefaultOnly, const QString &theSectionNamePrefix)
 
static std::pair< std::shared_ptr< SUIT_ShortcutModuleAssets >, std::shared_ptr< SUIT_ShortcutItemAssets > > getActionAssetsFromResources (const QString &theActionID, const std::set< QString > &theLangs={})
 Returns item assets as they are in asset files. Returned module assets is necessary to keep memory ownership of theAction ancestors. The module assets contain only ancestors of theActionID. More...
 
static QString currentLang ()
 

Static Public Attributes

static const QString ROOT_MODULE_ID = QString("")
 

Protected Member Functions

virtual ~SUIT_ShortcutMgr ()
 

Private Slots

void onActionDestroyed (QObject *theObject)
 Called when the corresponding action is destroyed. Removes destroyed action from maps of registered actions. Preserves shortcut. More...
 
void onAnonymousActionDestroyed (QObject *theObject)
 

Private Member Functions

 SUIT_ShortcutMgr ()
 
 SUIT_ShortcutMgr (const SUIT_ShortcutMgr &)=delete
 
SUIT_ShortcutMgroperator= (const SUIT_ShortcutMgr &)=delete
 
virtual bool eventFilter (QObject *theObject, QEvent *theEvent)
 Overrides QObject::eventFilter(). If theEvent is QEvent::ActionAdded and the action is instance of QtxAction, registers it. More...
 
std::set< std::pair< QString, QString > > setShortcutNoIDChecks (const QString &theModuleID, const QString &theInModuleActionID, const QKeySequence &theKeySequence, bool theOverride)
 Does not perform validity checks on theModuleID and theInModuleActionID. More...
 
void setShortcutsFromPreferences ()
 Set shortcuts from preference files. The method is intended to be called before any calls to setShortcut() or mergeShortcutContainer(). Definition of this method assumes, that shortcut settings are serialized as prerefence entries {name=<inModuleActionID>, val=<keySequence>} in dedicated section for each module, with names of sections being composed as "shortcuts_vA1.0:<moduleID>". More...
 
void setAssetsFromResources (QString theLanguage=QString())
 
void registerAnonymousShortcut (QAction *const theAction)
 
void enableAnonymousShortcutsClashingWith (const QString &theModuleID, const bool theEnable) const
 
void enableAnonymousShortcutsClashingWith (const QKeySequence &theKeySequence, bool theEnable) const
 
QString anonymousShortcutsToString () const
 

Static Private Member Functions

static void saveShortcutsToPreferences (const std::map< QString, std::map< QString, QKeySequence >> &theShortcutsInversed)
 Writes shortcuts to preference files. More...
 
static void saveShortcutsToPreferences (const std::map< QString, std::map< QString, std::pair< QKeySequence, QKeySequence >>> &theShortcutsInversed)
 Writes shortcuts to preference files. More...
 

Private Attributes

std::map< QString, std::map< QString, std::set< QAction * > > > myActions
 { moduleID, { inModuleActionID, action[] }[] }[]. More...
 
std::map< QAction *, std::pair< QString, QString > > myActionIDs
 { action, { moduleID, inModuleActionID } }[]. More...
 
SUIT_ShortcutContainer myShortcutContainer
 Can not contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }. More...
 
std::map< QString, std::shared_ptr< SUIT_ShortcutModuleAssets > > myModuleAssets
 {moduleID, moduleAssets}[]. More...
 
bool myAssetsLoaded
 True, if SUIT_ShortcutMgr::setAssetsFromResources(QString) was called. More...
 
std::set< QString > myActiveModuleIDs
 
std::map< QAction *, QKeySequence > myAnonymousShortcuts
 Actions without IDs, but with hard-coded non-empty key sequences. More...
 
std::map< QKeySequence, std::set< QAction * > > myAnonymousShortcutsInverse
 

Static Private Attributes

static SUIT_ShortcutMgrmyShortcutMgr = nullptr
 

Detailed Description

Handles action shortcut customization.

The manager is designed to detect shortcut conflicts even for actions, which are not constructed yet. To do this, data about action shortcuts should be available for the manager prior to construction of actions.

SHORTCUT PREFERENCES The data about shortcuts is stored in preference files (see SUIT_ShortcutMgr::setShortcutsFromPreferences()) as maps [action ID]->[key sequence]. It means, actions should have valid IDs (see SUIT_ShortcutMgr::isActionIDValid(const QString&)). Let's call such action identified, and actions with invalid IDs anonymous. Action IDs are language-independent.

After an action is constructed (even if it is anonymous), it must be registered by the manager. If the action is instance of QtxAction, the manager registers it automatically (see SUIT_ShortcutMgr:eventFilter(QObject* theObject, QEvent* theEvent)). Otherwise SUIT_ShortcutMgr::registerAction(const QString& theActionID, QAction* theAction) must be called.

Upon registration of an action, the manager checks, if a key sequence, assigned to the action, clashes with other shortcuts. If it does, and the action is anonymous - empty keysequnce is set to the action. If the action is identified - a keysequence from preferences is set to the action, even if incoming key sequence does not clash with other shortcuts. Absence of an action ID in preference files means default key sequence is empty.

If shortcuts are changed (via SUIT_ShortcutMgr::mergeShortcutContainer(const SUIT_ShortcutContainer&, bool, bool, bool)), the manager serizalizes the changes into user preference file and sets new key sequences to according registered actions.

ACTION ASSETS Users are not aware about action IDs, since GUI normally shows user-friendly data: action names, tooltips and icons. Let's call the data assets. Assets of an action should be available for GUI for shortcut presenting/editing (let's call the piece of GUI Shortcut Editor) even before the action is constructed. The assets should be provided is asset files (see SUIT_ShortcutMgr::setAssetsFromResources(QString)).

CONFLICT DETECTION IDENTIFIED ACTIONS/SHORTCUTS Let's call GUI module root module. Only one module, besides the root module, can be active at instance. So a key sequence must be unique within a joined temporary table of root and active module shortcuts. An action is allowed to be bound with only key sequence. Multiple actions may be registered under the same ID.

Action ID is application-unique, language-independent and must be composed as <moduleID>/<inModuleActionID>. If an action belongs to root module (e.g. 'Save As'), use empty string as <moduleID>. Let's call actions with empty module ID root actions.

<inModuleActionID> can be composed of several tokens, delimited by "/". See SUIT_ShortcutMgr::isInModuleActionIDValid(const QString&) for details. Shortcut Editor considers <inModuleActionID> as "path": <inModuleActionID> without the last token is inModuleID of parent folder or action-folder (see SUIT_ShortcutMgr::setAssetsFromResources(QString)).

META-ACTIONS There is a need to keep actions from different modules, which do the same from user' perspective, bound to the same key sequence. E.g. 'Front view' or 'Undo'. Let's call such set of actions meta-action. <inModuleActionID> of all members of a meta-action must be the same and the last token of the ID must start with "#". Meta-action is root action, when it comes to checking for conflicts. Shortcuts of meta-actions are (de)serialized to the same section of preference files as root shortcuts. Assets of meta-actions should be placed in asset files of root (GUI) module.

ANONYMOUS ACTIONS/SHORTCUTS Actions without action IDs or with invalid ones are called anonymous actions. All anonymous actions with non-empty shortcut key sequences are registered by SUIT_ShortcutMgr. If a shortcut for an anonymous action clashes with a shortcut for an action with defined ID (identified action/shortcut), the shortcut for the anonymous action is disabled, but [the anonymous action, the hard-coded key sequence] pair remains within the SUIT_ShortcutMgr. If user redefines key sequences for identified actions, and the clash is gone, SUIT_ShortcutMgr enables back the shortcut for the anonymous action.

It is not possible to reassign key sequences for anonymous actions using the Shortcut Editor GUI. It is not possible to always warn users, if a key sequence, they assigns to an identified action, disables an anonymous shortcut, because SUIT_ShortcutMgr has no data about anonymous actions until they appear in runtime. To prevent the user from relying on such warnings, they are completely disabled.

HOW TO USE 1) Come up with valid action ID for an action and: 1A) Pass the ID as an agrument to constructor of QtxAction; or 1B) Call SUIT_ShortcutMgr::registerAction(const QString& theActionID, QAction* theAction); or 1C) Construct the action using SUIT_ShortcutMgr::createAction(..). The latest option allows to avoid duplication of action assets in *.ts files. 2) Add action assets in asset files. 3) Add action default keysequence to default preference file.

DEVELOPMENT There are two macros: SHORTCUT_MGR_DBG and SHORTCUT_MGR_DEVTOOLS. SHORTCUT_MGR_DBG enables shortcut-related debug output. SHORTCUT_MGR_DEVTOOLS enables DevTools class. It assists in making anonymous actions identified and composing asset and default preference files.

More details can be found in the "SUIT_ShortcutMgr. ReadMe.md".

Constructor & Destructor Documentation

◆ SUIT_ShortcutMgr() [1/2]

SUIT_ShortcutMgr::SUIT_ShortcutMgr ( )
private

References ROOT_MODULE_ID.

◆ SUIT_ShortcutMgr() [2/2]

SUIT_ShortcutMgr::SUIT_ShortcutMgr ( const SUIT_ShortcutMgr )
privatedelete

◆ ~SUIT_ShortcutMgr()

SUIT_ShortcutMgr::~SUIT_ShortcutMgr ( )
protectedvirtual

Member Function Documentation

◆ anonymousShortcutsToString()

QString SUIT_ShortcutMgr::anonymousShortcutsToString ( ) const
private

◆ createAction()

QtxAction * SUIT_ShortcutMgr::createAction ( QObject theParent,
QObject theReceiver,
const char *  theReceiverSlot,
const QString &  theActionID,
const bool  theIsToggle = false 
) const

Creates an action and sets asset data to the action.

References getActionAssets(), splitIntoModuleIDAndInModuleID(), splitIntoTokens(), and Warning().

◆ createRuntimeActionAssets()

std::shared_ptr< const SUIT_ShortcutItemAssets > SUIT_ShortcutMgr::createRuntimeActionAssets ( const QString &  theModuleID,
const QString &  theInModuleActionID 
) const

Creates assets using action instance fields, if corresponding action is registered.

References SUIT_ShortcutModuleAssets::create(), currentLang(), getActions(), SUIT_ShortcutAssets::LangDependentAssets::myName, and SUIT_ShortcutAssets::LangDependentAssets::myToolTip.

◆ currentLang()

QString SUIT_ShortcutMgr::currentLang ( )
static
Returns
Language, which is set in resource manager.

References DEFAULT_LANG, LANG_SECTION, SUIT_Session::resourceMgr(), SUIT_Session::session(), QtxResourceMgr::stringValue(), and Warning().

◆ enableAnonymousShortcutsClashingWith() [1/2]

void SUIT_ShortcutMgr::enableAnonymousShortcutsClashingWith ( const QKeySequence &  theKeySequence,
bool  theEnable 
) const
private

◆ enableAnonymousShortcutsClashingWith() [2/2]

void SUIT_ShortcutMgr::enableAnonymousShortcutsClashingWith ( const QString &  theModuleID,
const bool  theEnable 
) const
private

◆ eventFilter()

bool SUIT_ShortcutMgr::eventFilter ( QObject theObject,
QEvent theEvent 
)
privatevirtual

Overrides QObject::eventFilter(). If theEvent is QEvent::ActionAdded and the action is instance of QtxAction, registers it.

References SUIT_ShortcutContainer::hasShortcut(), QtxAction::ID(), myShortcutContainer, registerAction(), registerAnonymousShortcut(), ShCutDbg(), and splitIntoModuleIDAndInModuleID().

◆ fillContainerFromPreferences() [1/2]

void SUIT_ShortcutMgr::fillContainerFromPreferences ( SUIT_ShortcutContainer theContainer,
bool  theDefaultOnly 
)
static

Sets all shortcuts from preferences to theContainer. Incoming shortcuts override existing ones. If the container has shortcut for an action, which is absent in preferences, and the existing shortcut does not conflict with incoming ones, it is untouched. See setShortcutsFromPreferences() for details.

Parameters
theDefaultOnlyIf true, user preferences are ignored and only default preferences are used.

References SECTION_NAME_PREFIX.

◆ fillContainerFromPreferences() [2/2]

void SUIT_ShortcutMgr::fillContainerFromPreferences ( SUIT_ShortcutContainer theContainer,
bool  theDefaultOnly,
const QString &  theSectionNamePrefix 
)
static
Parameters
theSectionNamePrefixPrefix of section name in preference files to look in.

List of modules with invalid IDs.

{ moduleID, {inModuleActionID, keySequence}[] }[]

Shortcuts, which have not been set, because they are in conflict with previously parsed shortcuts. { moduleID, {inModuleActionID, keySequence}[] }[]

References SUIT_Session::activeApplication(), SUIT_Application::desktop(), QtxResourceMgr::IgnoreUserValues, isInModuleActionIDValid(), isInModuleMetaActionID(), isModuleIDValid(), QtxResourceMgr::parameters(), SUIT_Session::resourceMgr(), ROOT_MODULE_ID, QtxResourceMgr::sectionsToken(), SUIT_Session::session(), SUIT_ShortcutContainer::setShortcut(), QtxResourceMgr::setWorkingMode(), ShCutDbg(), QtxResourceMgr::subSections(), toKeySequenceIfValid(), SUIT_ShortcutContainer::toString(), QtxResourceMgr::value(), Warning(), and QtxResourceMgr::workingMode().

◆ get()

SUIT_ShortcutMgr * SUIT_ShortcutMgr::get ( )
static

References Init(), and myShortcutMgr.

◆ getActionAssets() [1/2]

std::shared_ptr< const SUIT_ShortcutItemAssets > SUIT_ShortcutMgr::getActionAssets ( const QString &  theActionID,
bool  theTryToCreateRuntimeAssetsIfAbsent = true 
) const

◆ getActionAssets() [2/2]

std::shared_ptr< const SUIT_ShortcutItemAssets > SUIT_ShortcutMgr::getActionAssets ( const QString &  theModuleID,
const QString &  theInModuleActionID,
bool  theTryToCreateRuntimeAssetsIfAbsent = true 
) const

References makeActionID(), and ShCutDbg().

◆ getActionAssetsFromResources()

std::pair< std::shared_ptr< SUIT_ShortcutModuleAssets >, std::shared_ptr< SUIT_ShortcutItemAssets > > SUIT_ShortcutMgr::getActionAssetsFromResources ( const QString &  theActionID,
const std::set< QString > &  theLangs = {} 
)
static

Returns item assets as they are in asset files. Returned module assets is necessary to keep memory ownership of theAction ancestors. The module assets contain only ancestors of theActionID.

Parameters
theLangsIf empty, all languages is parsed.

References SUIT_ShortcutModuleAssets::create(), isInModuleMetaActionID(), QtxResourceMgr::parameters(), SUIT_Session::resourceMgr(), ROOT_MODULE_ID, SECTION_NAME_ACTION_ASSET_FILE_PATHS, SUIT_Session::session(), ShCutDbg(), splitIntoModuleIDAndInModuleID(), SUIT_tools::substituteVars(), and Warning().

◆ getActionID()

QString SUIT_ShortcutMgr::getActionID ( const QAction theAction) const

Get action ID of theActon.

Returns
empty string if theAction is not registered.

References makeActionID(), and myActionIDs.

◆ getActionName()

QString SUIT_ShortcutMgr::getActionName ( const QString &  theModuleID,
const QString &  theInModuleActionID,
const QString &  theLang = "" 
) const

Retrieves action name, if the asset is myModuleAssets. Name of module is not included. If theLang is empty, it is current language.

References getActionAssets().

◆ getActions()

std::set< QAction * > SUIT_ShortcutMgr::getActions ( const QString &  theModuleID,
const QString &  theInModuleActionID 
) const

Get registered actions. If theInModuleActionID is meta-action ID, seeks in all modules.

References isInModuleMetaActionID(), myActionIDs, and myActions.

◆ getIDsOfInterferingModules()

std::set< QString > SUIT_ShortcutMgr::getIDsOfInterferingModules ( const QString &  theModuleID) const
Returns
IDs of modules, which interfere with the module: if the module is root (theModuleID is empty) - returns all module IDs, otherwise returns ["", theModuleID].

References SUIT_ShortcutContainer::getIDsOfInterferingModules(), and myShortcutContainer.

◆ getKeySequence()

const QKeySequence & SUIT_ShortcutMgr::getKeySequence ( const QString &  theModuleID,
const QString &  theInModuleActionID 
) const

Get a key sequence mapped to the action.

References SUIT_ShortcutContainer::getKeySequence(), and myShortcutContainer.

◆ getModuleAssets() [1/2]

const std::map<QString, std::shared_ptr<SUIT_ShortcutModuleAssets> >& SUIT_ShortcutMgr::getModuleAssets ( ) const
inline

◆ getModuleAssets() [2/2]

std::shared_ptr< const SUIT_ShortcutModuleAssets > SUIT_ShortcutMgr::getModuleAssets ( const QString &  theModuleID) const

References myModuleAssets.

◆ getModuleIDAndInModuleID()

std::pair< QString, QString > SUIT_ShortcutMgr::getModuleIDAndInModuleID ( const QAction theAction) const

Get module ID and in-module-ID of theAction.

Returns
{ _ , "" } if theAction is not registered.

References myActionIDs.

◆ getModuleName()

QString SUIT_ShortcutMgr::getModuleName ( const QString &  theModuleID,
const QString &  theLang = "" 
) const

Retrieves module name, if the asset was loaded using setAssetsFromResources(). If theLang is empty, it is current language.

References getModuleAssets().

◆ getModuleShortcutsInversed()

const std::map< QString, QKeySequence > & SUIT_ShortcutMgr::getModuleShortcutsInversed ( const QString &  theModuleID) const
Returns
{inModuleActionID, keySequence}[]

References SUIT_ShortcutContainer::getModuleShortcutsInversed(), and myShortcutContainer.

◆ getShortcutContainer()

const SUIT_ShortcutContainer & SUIT_ShortcutMgr::getShortcutContainer ( ) const

References myShortcutContainer.

◆ getShortcutModuleIDs()

std::set< QString > SUIT_ShortcutMgr::getShortcutModuleIDs ( ) const
Returns
All module IDs, which were added to myShortcutContainer.

References SUIT_ShortcutContainer::getIDsOfAllModules(), and myShortcutContainer.

◆ hasAction()

bool SUIT_ShortcutMgr::hasAction ( const QAction theAction) const

Returns true if theAction is registered.

References myActionIDs.

◆ Init()

◆ isActionIDValid()

bool SUIT_ShortcutMgr::isActionIDValid ( const QString &  theActionID)
static

◆ isInModuleActionIDValid()

bool SUIT_ShortcutMgr::isInModuleActionIDValid ( const QString &  theInModuleActionID)
static

Valid in-module action ID may consist of several tokens, separated by "/": <token_0>/<token_1>...<token_N>/<token_N-1>. Each <token> must be non-empty and be equal to QString(<token>).simplified(). Token "#" is also not valid, since the character in the beginning of the last token means action is meta-action.

References isInModuleIDTokenValid(), and splitIntoTokens().

◆ isInModuleIDTokenMeta()

bool SUIT_ShortcutMgr::isInModuleIDTokenMeta ( const QString &  theInModuleIDToken)
static

References META_ACTION_PREFIX.

◆ isInModuleIDTokenValid()

bool SUIT_ShortcutMgr::isInModuleIDTokenValid ( const QString &  theInModuleIDToken)
static

◆ isInModuleMetaActionID()

bool SUIT_ShortcutMgr::isInModuleMetaActionID ( const QString &  theInModuleActionID)
static
Returns
true, is theInModuleActionID starts with "#".

References isInModuleIDTokenMeta(), and splitIntoTokens().

◆ isKeySequenceValid()

bool SUIT_ShortcutMgr::isKeySequenceValid ( const QKeySequence &  theKeySequence)
static

Checks whether the theKeySequence is platform-compatible.

◆ isModuleIDValid()

bool SUIT_ShortcutMgr::isModuleIDValid ( const QString &  theModuleID)
static

Valid module ID does not contain "/" and equals to result of QString(theModuleID).simplified(). Empty module ID is valid - it is root module ID.

References TOKEN_SEPARATOR.

◆ joinIntoRelativeID()

QString SUIT_ShortcutMgr::joinIntoRelativeID ( const QStringList &  theTokens)
static

Does not check validity.

References TOKEN_SEPARATOR.

◆ makeActionID()

QString SUIT_ShortcutMgr::makeActionID ( const QString &  theModuleID,
const QString &  theInModuleActionID 
)
static

Creates application-unique action ID. Reverse to splitIntoModuleIDAndInModuleID.

Returns
Empty string, if either theModuleID or theInModuleActionID is invalid

References isInModuleActionIDValid(), isModuleIDValid(), and TOKEN_SEPARATOR.

◆ mergeShortcutContainer()

void SUIT_ShortcutMgr::mergeShortcutContainer ( const SUIT_ShortcutContainer theContainer,
bool  theOverride = true,
bool  theTreatAbsentIncomingAsDisabled = false,
bool  theSaveToPreferences = true 
)

Does not perform validity checks on theModuleID and theInModuleActionID.

{ keySequence, {moduleID, isTheKeySequenceBound}[] }[]

References enableAnonymousShortcutsClashingWith(), getActions(), SUIT_ShortcutContainer::merge(), myActiveModuleIDs, myShortcutContainer, NO_KEYSEQUENCE, saveShortcutsToPreferences(), ShCutDbg(), and SUIT_ShortcutContainer::toString().

◆ onActionDestroyed

void SUIT_ShortcutMgr::onActionDestroyed ( QObject theObject)
privateslot

Called when the corresponding action is destroyed. Removes destroyed action from maps of registered actions. Preserves shortcut.

Parameters
theObjectaction being destroyed.

References myActionIDs, and myActions.

◆ onAnonymousActionDestroyed

void SUIT_ShortcutMgr::onAnonymousActionDestroyed ( QObject theObject)
privateslot

◆ operator=()

SUIT_ShortcutMgr& SUIT_ShortcutMgr::operator= ( const SUIT_ShortcutMgr )
privatedelete

◆ rebindActionsToKeySequences()

void SUIT_ShortcutMgr::rebindActionsToKeySequences ( ) const

For all registered actions binds key sequences from myShortcutContainer.

References getKeySequence(), myActionIDs, and ShCutDbg().

◆ registerAction() [1/2]

◆ registerAction() [2/2]

void SUIT_ShortcutMgr::registerAction ( QtxAction theAction)

Add theAction to map of managed actions. QtxAction::ID() is used as action ID.

References QtxAction::ID(), and registerAction().

◆ registerAnonymousShortcut()

◆ saveShortcutsToPreferences() [1/2]

void SUIT_ShortcutMgr::saveShortcutsToPreferences ( const std::map< QString, std::map< QString, QKeySequence >> &  theShortcutsInversed)
staticprivate

Writes shortcuts to preference files.

Parameters
theShortcuts{ moduleID, { inModuleActionID, keySequence }[] }[]. Empty inModuleActionIDs are ignored.

References SUIT_Session::resourceMgr(), SECTION_NAME_PREFIX, QtxResourceMgr::sectionsToken(), SUIT_Session::session(), QtxResourceMgr::setValue(), ShCutDbg(), and Warning().

◆ saveShortcutsToPreferences() [2/2]

void SUIT_ShortcutMgr::saveShortcutsToPreferences ( const std::map< QString, std::map< QString, std::pair< QKeySequence, QKeySequence >>> &  theShortcutsInversed)
staticprivate

Writes shortcuts to preference files.

Parameters
theShortcuts{ moduleID, { inModuleActionID, {oldKeySequence, newKeySequence} }[] }[]. Empty inModuleActionIDs are ignored. OldKeySequences are ignored.

References SUIT_Session::resourceMgr(), SECTION_NAME_PREFIX, QtxResourceMgr::sectionsToken(), SUIT_Session::session(), QtxResourceMgr::setValue(), ShCutDbg(), and Warning().

◆ setActionsOfModuleEnabled()

void SUIT_ShortcutMgr::setActionsOfModuleEnabled ( const QString &  theModuleID,
const bool  theEnable = true 
) const

Enables/disable actions of the module. Only those actions are affected, whose parent widget is active desktop.

References SUIT_Session::activeApplication(), anonymousShortcutsToString(), SUIT_Application::desktop(), enableAnonymousShortcutsClashingWith(), myActions, myActiveModuleIDs, SUIT_Session::session(), and ShCutDbg().

◆ setActionsWithPrefixInIDEnabled()

void SUIT_ShortcutMgr::setActionsWithPrefixInIDEnabled ( const QString &  theInModuleActionIDPrefix,
bool  theEnable = true 
) const

Enables/disables all registered actions whose in-module action ID begins with theInModuleActionIDPrefix. Only those actions are affected, whose parent widget is active desktop.

References SUIT_Session::activeApplication(), SUIT_Application::desktop(), myActionIDs, and SUIT_Session::session().

◆ setAssetsFromResources()

void SUIT_ShortcutMgr::setAssetsFromResources ( QString  theLanguage = QString())
private

Fills myModuleAssets from asset files in theLanguage and EN.

Parameters
theLanguageIf empty, fills assets in current language and EN.

Asset files must be structured like this: { moduleID: { "iconPath": iconPath, "langDependentAssets": { ... lang: { "name": moduleName, "tooltip": moduleTooltip }, ... }, "children": { ... actionA_IDLastToken : { "iconPath": iconPath, "langDependentAssets": { ... lang: { "name": actionName, "tooltip": actionTooltip }, ... }, "children": { // The action has nested actions. actionB_IDLastToken: { ... } } }, ... folderC_IDLastToken: { "isAction": false, // The folder is pure folder. "iconPath": iconPath, "langDependentAssets": { ... }, children: { ... } } ... } } }

The JSON above describes an action-folder with ID "moduleID/actionA_IDLastToken" and a pure folder with ID "moduleID/folderC_IDLastToken". The action-folder has a nested action with "moduleID/actionA_IDLastToken//actionB_IDLastToken". Requirements for action' and folder' IDs are the same.

References SUIT_ShortcutModuleAssets::create(), currentLang(), DEFAULT_LANG, SUIT_ShortcutAssets::forEachDescendant(), isModuleIDValid(), SUIT_ShortcutAssets::loadIcon(), SUIT_ShortcutAssets::merge(), myAssetsLoaded, SUIT_ShortcutAssets::myIcon, SUIT_ShortcutAssets::myIconPath, SUIT_ShortcutAssets::myLangDependentAssets, myModuleAssets, QtxResourceMgr::parameters(), SUIT_Session::resourceMgr(), ROOT_MODULE_ID, SECTION_NAME_ACTION_ASSET_FILE_PATHS, SUIT_Session::session(), ShCutDbg(), SUIT_tools::substituteVars(), QtxResourceMgr::value(), and Warning().

◆ setSectionEnabled()

void SUIT_ShortcutMgr::setSectionEnabled ( const QString &  theInModuleActionIDPrefix,
bool  theEnable = true 
) const

◆ setShortcut() [1/2]

std::set< std::pair< QString, QString > > SUIT_ShortcutMgr::setShortcut ( const QString &  theActionID,
const QKeySequence &  theKeySequence,
bool  theOverride = false 
)

Checks for conflicts. If theOverride, modifies incoming and disables all conflicting shortcuts. Then binds key sequences with corresponding registered actions. Saves changes to preferences.

Redefining a key sequence for the action, if the key sequence does not conflict with other shortcuts, is not considered as a conflict.

Parameters
theInModuleActionIDThe method has no effect if theInModuleActionID is empty.
theKeySequenceEmpty theKeySequence does not cause conflicts, in this case a shortcut for the action is disabled: theInModuleActionID is added/retained in the container but mapped to empty key sequence.
theOverrideIf true, conflicting shortcuts are disabled.
Returns
{moduleID, inModuleActionID}[] - Set of conflicting actions if theOverride = false, otherwise set of actions (without incoming one), whose shortcuts have been disabled.

References setShortcutNoIDChecks(), ShCutDbg(), and splitIntoModuleIDAndInModuleID().

◆ setShortcut() [2/2]

std::set< std::pair< QString, QString > > SUIT_ShortcutMgr::setShortcut ( const QString &  theModuleID,
const QString &  theInModuleActionID,
const QKeySequence &  theKeySequence,
bool  theOverride = false 
)

◆ setShortcutNoIDChecks()

std::set< std::pair< QString, QString > > SUIT_ShortcutMgr::setShortcutNoIDChecks ( const QString &  theModuleID,
const QString &  theInModuleActionID,
const QKeySequence &  theKeySequence,
bool  theOverride 
)
private

Does not perform validity checks on theModuleID and theInModuleActionID.

{ moduleID, {inModuleActionID, keySequence}[] }[]

{ moduleID, isTheKeySequenceBound }[]

References enableAnonymousShortcutsClashingWith(), getActions(), myActiveModuleIDs, myShortcutContainer, NO_KEYSEQUENCE, saveShortcutsToPreferences(), and SUIT_ShortcutContainer::setShortcut().

◆ setShortcutsFromPreferences()

void SUIT_ShortcutMgr::setShortcutsFromPreferences ( )
private

Set shortcuts from preference files. The method is intended to be called before any calls to setShortcut() or mergeShortcutContainer(). Definition of this method assumes, that shortcut settings are serialized as prerefence entries {name=<inModuleActionID>, val=<keySequence>} in dedicated section for each module, with names of sections being composed as "shortcuts_vA1.0:<moduleID>".

E.g. in case of XML file it may look like this:

<section name="shortcuts_vA1.0:"> <parameter name="AboutDialog" value="Alt+Shift+A"> <parameter name="Edit/#Clipboard_Copy" value="Ctrl+C"> <parameter name="Edit/#Clipboard_Paste" value="Ctrl+V"> <parameter name="File/New" value="Ctrl+N"> <parameter name="File/Open" value="Ctrl+O"> </section> <section name="shortcuts_vA1.0:SHAPER"> <parameter name="Part/Dump" value=""> <parameter name="Part/Parameter" value=""> <parameter name="Part/ParametersMgr" value=""> <parameter name="Sketch" value="Ctrl+4"> <parameter name="Sketch/SketchPoint" value="Ctrl+Shift+*"> <parameter name="Sketch/SketchLine" value="Ctrl+Shift+_"> </section>

Empty inModuleActionIDs are ignored.

References fillContainerFromPreferences(), getActionAssets(), SUIT_ShortcutContainer::getIDsOfAllModules(), getModuleShortcutsInversed(), mergeShortcutContainer(), myAssetsLoaded, myShortcutContainer, ShCutDbg(), TOKEN_SEPARATOR, and Warning().

◆ splitIntoModuleIDAndInModuleID()

std::pair< QString, QString > SUIT_ShortcutMgr::splitIntoModuleIDAndInModuleID ( const QString &  theActionID)
static

Extracts module ID and in-module action ID from application-unique action ID. The theActionID must be composed as <moduleID>/<inModuleActionID>.

Returns
{ _ , "" }, if theActionID is invalid.

References isInModuleIDTokenValid(), and TOKEN_SEPARATOR.

◆ splitIntoTokens()

QStringList SUIT_ShortcutMgr::splitIntoTokens ( const QString &  theRelativeID)
static

Does not check validity.

References TOKEN_SEPARATOR.

◆ toKeySequenceIfValid()

std::pair< bool, QKeySequence > SUIT_ShortcutMgr::toKeySequenceIfValid ( const QString &  theKeySequenceString)
static
Returns
{false, _ } if theKeySequenceString is invalid.

References isKeySequenceValid().

◆ updateShortcuts()

void SUIT_ShortcutMgr::updateShortcuts ( ) const

Member Data Documentation

◆ myActionIDs

std::map<QAction*, std::pair<QString, QString> > SUIT_ShortcutMgr::myActionIDs
private

{ action, { moduleID, inModuleActionID } }[].

May contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }.

◆ myActions

std::map<QString, std::map<QString, std::set<QAction*> > > SUIT_ShortcutMgr::myActions
private

{ moduleID, { inModuleActionID, action[] }[] }[].

May contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }.

◆ myActiveModuleIDs

std::set<QString> SUIT_ShortcutMgr::myActiveModuleIDs
mutableprivate

◆ myAnonymousShortcuts

std::map<QAction*, QKeySequence> SUIT_ShortcutMgr::myAnonymousShortcuts
private

Actions without IDs, but with hard-coded non-empty key sequences.

Shortcuts, defined in preferences, override shortcuts of anonymous actions - if an active module has a preference shortcut, anonymous shortcuts with the same key sequence are disabled. If the root module has a preference shortcut, which is in clash with anonymous shortcuts, clashing anonymous actions are always disabled.

◆ myAnonymousShortcutsInverse

std::map<QKeySequence, std::set<QAction*> > SUIT_ShortcutMgr::myAnonymousShortcutsInverse
private

◆ myAssetsLoaded

bool SUIT_ShortcutMgr::myAssetsLoaded
private

◆ myModuleAssets

std::map<QString, std::shared_ptr<SUIT_ShortcutModuleAssets> > SUIT_ShortcutMgr::myModuleAssets
mutableprivate

{moduleID, moduleAssets}[].

Structured assets: module assets refer to folders and actions, folders and actions refer to nested ones, etc.

◆ myShortcutContainer

SUIT_ShortcutContainer SUIT_ShortcutMgr::myShortcutContainer
private

Can not contain entries like { <non-root module ID>, { <meta-action ID>, actions[] } }.

◆ myShortcutMgr

SUIT_ShortcutMgr * SUIT_ShortcutMgr::myShortcutMgr = nullptr
staticprivate

◆ ROOT_MODULE_ID

const QString SUIT_ShortcutMgr::ROOT_MODULE_ID = QString("")
static

The documentation for this class was generated from the following files: