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
68TOOL_ACTION::TOOL_ACTION( int aDefaultHotKey, int aDefaultHotKeyAlt ) :
70 m_group( std::nullopt ),
71 m_defaultHotKey( aDefaultHotKey ),
72 m_defaultHotKeyAlt( aDefaultHotKeyAlt ),
73 m_id( -1 ),
75{
76 SetHotKey( aDefaultHotKey, aDefaultHotKeyAlt );
77}
78
79
81 m_name( aArgs.m_name.value_or( "" ) ),
82 m_scope( aArgs.m_scope.value_or( AS_CONTEXT ) ),
83 m_defaultHotKey( aArgs.m_defaultHotKey.value_or( 0 ) ),
84 m_defaultHotKeyAlt( aArgs.m_defaultHotKeyAlt.value_or( 0 ) ),
85 m_hotKey( aArgs.m_defaultHotKey.value_or( 0 ) ),
86 m_hotKeyAlt( aArgs.m_defaultHotKeyAlt.value_or( 0 ) ),
87 m_legacyName( aArgs.m_legacyName.value_or( "" ) ),
88 m_friendlyName( TowxString( aArgs.m_friendlyName.value_or( "" ) ) ),
89 m_tooltip( TowxString( aArgs.m_tooltip.value_or( "" ) ) ),
90 m_id( -1 ),
91 m_uiid( std::nullopt ),
92 m_flags( aArgs.m_flags.value_or( AF_NONE ) )
93{
94 // Action name is the only mandatory part
95 assert( !m_name.empty() );
96
97 if( aArgs.m_menuText.has_value() )
98 m_menuLabel = TowxString( aArgs.m_menuText.value() );
99
100 if( aArgs.m_uiid.has_value() )
101 m_uiid = aArgs.m_uiid.value();
102
103 if( aArgs.m_param.has_value() )
104 m_param = aArgs.m_param;
105
106 if( aArgs.m_description.has_value() )
107 m_description = TowxString( aArgs.m_description.value() );
108
109 if( aArgs.m_group.has_value() )
110 m_group = aArgs.m_group;
111
112 if( aArgs.m_icon.has_value() )
113 m_icon = aArgs.m_icon.value();
114
115 if( aArgs.m_toolbarState.has_value() )
116 m_toolbarState = aArgs.m_toolbarState.value();
117
118 // If there is no icon, then the action should be hidden from the toolbar
119 if( !m_icon.has_value() )
120 m_toolbarState.set( static_cast<size_t>( TOOLBAR_STATE::HIDDEN ) );
121
122 ACTION_MANAGER::GetActionList().push_back( this );
123}
124
125
130
131
133{
134 TOOL_EVENT evt;
135
136 if( IsActivation() )
138 else if( IsNotification() )
140 else
142
143 if( m_group.has_value() )
144 {
145 evt.SetActionGroup( m_group.value() );
146 }
147
148 if( m_param.has_value() )
149 evt.SetParameter( m_param );
150
151 return evt;
152}
153
154
156{
157 if( m_friendlyName.empty() )
158 return wxEmptyString;
159
160 return wxGetTranslation( m_friendlyName );
161}
162
163
165{
166 if( m_menuLabel.has_value() )
167 return wxGetTranslation( m_menuLabel.value() );
168
169 return GetFriendlyName();
170}
171
172
174{
175 wxString label = GetMenuLabel();
176 label.Replace( wxS( "&" ), wxS( "&&" ) );
177 return AddHotkeyName( label, m_hotKey, IS_HOTKEY );
178}
179
180
182{
183 // If no description provided, use the tooltip without a hotkey
184 if( !m_description.has_value() )
185 return GetTooltip( false );
186
187 return wxGetTranslation( m_description.value() );
188}
189
190
191wxString TOOL_ACTION::GetTooltip( bool aIncludeHotkey ) const
192{
193 wxString tooltip = wxGetTranslation( m_tooltip );
194
195 if( aIncludeHotkey && GetHotKey() )
196 tooltip += wxString::Format( wxT( " (%s)" ), KeyNameFromKeyCode( GetHotKey() ) );
197
198 return tooltip;
199}
200
201
203{
204 // We don't show button text so use the action name as the first line of the tooltip
205 wxString tooltip = GetFriendlyName();
206
207 if( GetHotKey() )
208 tooltip += wxString::Format( wxT( "\t(%s)" ), KeyNameFromKeyCode( GetHotKey() ) );
209
210 if( !GetTooltip( false ).IsEmpty() )
211 tooltip += '\n' + GetTooltip( false );
212
213 return tooltip;
214}
215
216
217void TOOL_ACTION::SetHotKey( int aKeycode, int aKeycodeAlt )
218{
219 m_hotKey = aKeycode;
220 m_hotKeyAlt = aKeycodeAlt;
221}
222
223
224bool TOOL_ACTION::IsHotKeyUserBound( int aMatchedHotKey ) const
225{
226 return ( m_hotKey == aMatchedHotKey && m_hotKey != m_defaultHotKey )
227 || ( m_hotKeyAlt == aMatchedHotKey && m_hotKeyAlt != m_defaultHotKeyAlt );
228}
229
230
231std::string TOOL_ACTION::GetToolName() const
232{
233 int dotCount = std::count( m_name.begin(), m_name.end(), '.' );
234
235 switch( dotCount )
236 {
237 case 0:
238 assert( false ); // Invalid action name format
239 return "";
240
241 case 1:
242 return m_name;
243
244 case 2:
245 return m_name.substr( 0, m_name.rfind( '.' ) );
246
247 default:
248 assert( false ); // TODO not implemented
249 return "";
250 }
251}
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:554
void SetParameter(T aParam)
Set a non-standard parameter assigned to the event.
Definition tool_event.h:539
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)