KiCad PCB EDA Suite
Loading...
Searching...
No Matches
tool_action.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013-2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
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 General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <optional>
23#include <tool/tool_action.h>
24#include <tool/tool_event.h>
25#include <tool/action_manager.h>
26
27#include <algorithm>
28#include <bitmaps.h>
29#include <hotkeys_basic.h>
30
31#include <core/wx_stl_compat.h>
32#include <wx/string.h>
33#include <wx/translation.h>
34
35TOOL_ACTION::TOOL_ACTION( const std::string& aName, TOOL_ACTION_SCOPE aScope,
36 int aDefaultHotKey, const std::string& aLegacyHotKeyName,
37 const wxString& aLabel, const wxString& aTooltip,
38 BITMAPS aIcon, TOOL_ACTION_FLAGS aFlags ) :
39 m_name( aName ),
40 m_scope( aScope ),
41 m_group( std::nullopt ),
42 m_defaultHotKey( aDefaultHotKey ),
44 m_legacyName( aLegacyHotKeyName ),
45 m_menuLabel( aLabel ),
46 m_tooltip( aTooltip ),
47 m_icon( aIcon ),
48 m_id( -1 ),
49 m_flags( aFlags )
50{
51 SetHotKey( aDefaultHotKey );
52 ACTION_MANAGER::GetActionList().push_back( this );
53}
54
55
58 m_group( std::nullopt ),
59 m_defaultHotKey( 0 ),
61 m_id( -1 ),
63{
64 SetHotKey( 0 );
65}
66
67
69 m_name( aArgs.m_name.value_or( "" ) ),
70 m_scope( aArgs.m_scope.value_or( AS_CONTEXT ) ),
71 m_defaultHotKey( aArgs.m_defaultHotKey.value_or( 0 ) ),
72 m_defaultHotKeyAlt( aArgs.m_defaultHotKeyAlt.value_or( 0 ) ),
73 m_hotKey( aArgs.m_defaultHotKey.value_or( 0 ) ),
74 m_hotKeyAlt( 0 ),
75 m_legacyName( aArgs.m_legacyName.value_or( "" ) ),
76 m_friendlyName( TowxString( aArgs.m_friendlyName.value_or( "" ) ) ),
77 m_tooltip( TowxString( aArgs.m_tooltip.value_or( "" ) ) ),
78 m_id( -1 ),
79 m_uiid( std::nullopt ),
80 m_flags( aArgs.m_flags.value_or( AF_NONE ) )
81{
82 // Action name is the only mandatory part
83 assert( !m_name.empty() );
84
85 if( aArgs.m_menuText.has_value() )
86 m_menuLabel = TowxString( aArgs.m_menuText.value() );
87
88 if( aArgs.m_uiid.has_value() )
89 m_uiid = aArgs.m_uiid.value();
90
91 if( aArgs.m_param.has_value() )
92 m_param = aArgs.m_param;
93
94 if( aArgs.m_description.has_value() )
95 m_description = TowxString( aArgs.m_description.value() );
96
97 if( aArgs.m_group.has_value() )
98 m_group = aArgs.m_group;
99
100 if( aArgs.m_icon.has_value() )
101 m_icon = aArgs.m_icon.value();
102
103 if( aArgs.m_toolbarState.has_value() )
104 m_toolbarState = aArgs.m_toolbarState.value();
105
106 // If there is no icon, then the action should be hidden from the toolbar
107 if( !m_icon.has_value() )
108 m_toolbarState.set( static_cast<size_t>( TOOLBAR_STATE::HIDDEN ) );
109
110 ACTION_MANAGER::GetActionList().push_back( this );
111}
112
113
118
119
121{
122 TOOL_EVENT evt;
123
124 if( IsActivation() )
126 else if( IsNotification() )
128 else
130
131 if( m_group.has_value() )
132 {
133 evt.SetActionGroup( m_group.value() );
134 }
135
136 if( m_param.has_value() )
137 evt.SetParameter( m_param );
138
139 return evt;
140}
141
142
144{
145 if( m_friendlyName.empty() )
146 return wxEmptyString;
147
148 return wxGetTranslation( m_friendlyName );
149}
150
151
153{
154 if( m_menuLabel.has_value() )
155 return wxGetTranslation( m_menuLabel.value() );
156
157 return GetFriendlyName();
158}
159
160
162{
163 wxString label = GetMenuLabel();
164 label.Replace( wxS( "&" ), wxS( "&&" ) );
165 return AddHotkeyName( label, m_hotKey, IS_HOTKEY );
166}
167
168
170{
171 // If no description provided, use the tooltip without a hotkey
172 if( !m_description.has_value() )
173 return GetTooltip( false );
174
175 return wxGetTranslation( m_description.value() );
176}
177
178
179wxString TOOL_ACTION::GetTooltip( bool aIncludeHotkey ) const
180{
181 wxString tooltip = wxGetTranslation( m_tooltip );
182
183 if( aIncludeHotkey && GetHotKey() )
184 tooltip += wxString::Format( wxT( " (%s)" ), KeyNameFromKeyCode( GetHotKey() ) );
185
186 return tooltip;
187}
188
189
191{
192 // We don't show button text so use the action name as the first line of the tooltip
193 wxString tooltip = GetFriendlyName();
194
195 if( GetHotKey() )
196 tooltip += wxString::Format( wxT( "\t(%s)" ), KeyNameFromKeyCode( GetHotKey() ) );
197
198 if( !GetTooltip( false ).IsEmpty() )
199 tooltip += '\n' + GetTooltip( false );
200
201 return tooltip;
202}
203
204
205void TOOL_ACTION::SetHotKey( int aKeycode, int aKeycodeAlt )
206{
207 m_hotKey = aKeycode;
208 m_hotKeyAlt = aKeycodeAlt;
209}
210
211
212bool TOOL_ACTION::IsHotKeyUserBound( int aMatchedHotKey ) const
213{
214 return ( m_hotKey == aMatchedHotKey && m_hotKey != m_defaultHotKey )
215 || ( m_hotKeyAlt == aMatchedHotKey && m_hotKeyAlt != m_defaultHotKeyAlt );
216}
217
218
219std::string TOOL_ACTION::GetToolName() const
220{
221 int dotCount = std::count( m_name.begin(), m_name.end(), '.' );
222
223 switch( dotCount )
224 {
225 case 0:
226 assert( false ); // Invalid action name format
227 return "";
228
229 case 1:
230 return m_name;
231
232 case 2:
233 return m_name.substr( 0, m_name.rfind( '.' ) );
234
235 default:
236 assert( false ); // TODO not implemented
237 return "";
238 }
239}
BITMAPS
A list of all bitmap identifiers.
static std::list< TOOL_ACTION * > & GetActionList()
Return list of TOOL_ACTIONs.
Build up the properties of a TOOL_ACTION in an incremental manner that is static-construction safe.
std::optional< std::string_view > m_description
std::optional< int > m_uiid
std::optional< TOOL_ACTION_GROUP > m_group
std::optional< BITMAPS > m_icon
std::optional< TOOLBAR_STATE_FLAGS > m_toolbarState
std::optional< std::string_view > m_menuText
int m_id
Unique ID for maps. Assigned by ACTION_MANAGER.
bool IsHotKeyUserBound(int aMatchedHotKey) const
Return true if the matched hotkey slot (primary or alternate) holds a value different from its compil...
std::optional< wxString > m_description
Description of the action.
wxString GetMenuLabel() const
Return the translated label for the action.
wxString GetTooltip(bool aIncludeHotkey=true) const
std::optional< wxString > m_menuLabel
Menu label.
TOOL_ACTION_SCOPE m_scope
bool IsActivation() const
Return true if the action is intended to activate a tool.
TOOL_ACTION_FLAGS m_flags
void SetHotKey(int aKeycode, int aKeycodeAlt=0)
std::string GetToolName() const
Return name of the tool associated with the action.
std::optional< int > m_uiid
ID to use when interacting with the UI (if empty, generate one).
wxString m_friendlyName
User-friendly name.
bool IsNotification() const
Return true if the action is a notification.
std::optional< BITMAPS > m_icon
Icon for the menu entry.
wxString m_tooltip
User facing tooltip help text.
int m_hotKeyAlt
The alternate hotkey (post-user-settings-application).
TOOLBAR_STATE_FLAGS m_toolbarState
Toolbar state behavior for the action.
wxString GetDescription() const
wxString GetMenuItem() const
int GetHotKey() const
Return the hotkey keycode which initiates the action.
ki::any m_param
Generic parameter.
const int m_defaultHotKey
Default hot key.
int m_hotKey
The current hotkey (post-user-settings-application).
TOOL_EVENT MakeEvent() const
Return the event associated with the action (i.e.
const std::string m_legacyName
Name for reading legacy hotkey settings.
std::string m_name
Name of the action (convention is "app.tool.actionName")
wxString GetFriendlyName() const
Return the translated user-friendly name of the action.
wxString GetButtonTooltip() const
std::optional< TOOL_ACTION_GROUP > m_group
Optional group for the action to belong to.
const int m_defaultHotKeyAlt
Default hot key alternate.
Generic, UI-independent tool event.
Definition tool_event.h:167
void SetActionGroup(const TOOL_ACTION_GROUP &aGroup)
Definition tool_event.h:539
void SetParameter(T aParam)
Set a non-standard parameter assigned to the event.
Definition tool_event.h:524
bool has_value() const noexcept
Report whether there is a contained object or not.
Definition ki_any.h:311
wxString AddHotkeyName(const wxString &aText, int aHotKey, HOTKEY_ACTION_TYPE aStyle)
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
@ IS_HOTKEY
STL namespace.
@ HIDDEN
Action is hidden from the toolbar.
Definition tool_action.h:59
TOOL_ACTION_SCOPE
Scope of tool actions.
Definition tool_action.h:42
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition tool_action.h:45
@ AS_CONTEXT
Action belongs to a particular tool (i.e. a part of a pop-up menu)
Definition tool_action.h:43
TOOL_ACTION_FLAGS
Flags for tool actions.
Definition tool_action.h:50
@ AF_NONE
Definition tool_action.h:51
@ TA_ACTIVATE
Tool activation event.
Definition tool_event.h:111
@ TA_ACTION
Tool action (allows one to control tools).
Definition tool_event.h:108
@ TA_NONE
Definition tool_event.h:62
@ TC_COMMAND
Definition tool_event.h:53
@ TC_MESSAGE
Definition tool_event.h:54
wxString TowxString(const std::string_view &view)