KiCad PCB EDA Suite
Loading...
Searching...
No Matches
hotkey_store.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) 1992-2019 Kicad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <hotkey_store.h>
25#include <eda_base_frame.h>
26#include <tool/tool_manager.h>
27#include <tool/action_manager.h>
28#include <tool/tool_event.h>
29#include <tool/tool_action.h>
30#include <advanced_config.h>
31
33{
34public:
35 PSEUDO_ACTION( const wxString& aLabel, int aHotKey )
36 {
37 m_label = aLabel;
38 m_hotKey = aHotKey;
39 }
40};
41
43 new PSEUDO_ACTION( _( "Pan Left/Right" ), MD_CTRL + PSEUDO_WXK_WHEEL ),
44 new PSEUDO_ACTION( _( "Pan Up/Down" ), MD_SHIFT + PSEUDO_WXK_WHEEL ),
45 new PSEUDO_ACTION( _( "Finish Drawing" ), PSEUDO_WXK_DBLCLICK ),
46 new PSEUDO_ACTION( _( "Add to Selection" ), MD_SHIFT + PSEUDO_WXK_CLICK ),
47 new PSEUDO_ACTION( _( "Highlight Net" ), MD_CTRL + PSEUDO_WXK_CLICK ),
48 new PSEUDO_ACTION( _( "Remove from Selection" ), MD_SHIFT + MD_CTRL + PSEUDO_WXK_CLICK ),
49 new PSEUDO_ACTION( _( "Ignore Grid Snaps" ), MD_CTRL ),
50 new PSEUDO_ACTION( _( "Ignore Other Snaps" ), MD_SHIFT ),
51};
52
54#ifndef __WINDOWS__
55 new PSEUDO_ACTION( _( "Close" ), MD_CTRL + 'W' ),
56#endif
57 new PSEUDO_ACTION( _( "Quit" ), MD_CTRL + 'Q' )
58};
59
60
62{
63 wxString name( aAction->GetName() );
64 return name.BeforeFirst( '.' );
65}
66
67
69{
70 std::map<wxString, wxString> s_AppNames = {
71 { wxT( "common" ), _( "Common" ) },
72 { wxT( "kicad" ), _( "Project Manager" ) },
73 { wxT( "eeschema" ), _( "Schematic Editor" ) },
74 { wxT( "pcbnew" ), _( "PCB Editor" ) },
75 { wxT( "plEditor" ), _( "Drawing Sheet Editor" ), },
76 { wxT( "3DViewer" ), _( "3D Viewer" ) },
77 { wxT( "gerbview" ), _( "Gerber Viewer" ) }
78 };
79
80 wxString appName = GetAppName( aAction );
81
82 if( s_AppNames.count( appName ) )
83 return s_AppNames[ appName ];
84 else
85 return appName;
86}
87
88
90{
91}
92
93
94void HOTKEY_STORE::Init( std::vector<TOOL_ACTION*> aActionsList, bool aIncludeReadOnlyCmds )
95{
96 std::map<std::string, HOTKEY> masterMap;
97
98 for( TOOL_ACTION* action : aActionsList )
99 {
100 // Internal actions probably shouldn't be allowed hotkeys
101 if( action->GetLabel().IsEmpty() )
102 continue;
103
104 if( !ADVANCED_CFG::GetCfg().m_ExtraZoneDisplayModes )
105 {
106 if( action->GetName() == "pcbnew.Control.zoneDisplayOutlines"
107 || action->GetName() == "pcbnew.Control.zoneDisplayTesselation" )
108 {
109 continue;
110 }
111 }
112
113 HOTKEY& hotkey = masterMap[ action->GetName() ];
114 hotkey.m_Actions.push_back( action );
115
116 if( !hotkey.m_EditKeycode )
117 hotkey.m_EditKeycode = action->GetHotKey();
118 }
119
120 wxString currentApp;
121 HOTKEY_SECTION* currentSection = nullptr;
122
123 // If a previous list was built, ensure this previous list is cleared:
124 m_hk_sections.clear();
125
126 for( const std::pair<const std::string, HOTKEY>& entry : masterMap )
127 {
128 TOOL_ACTION* entryAction = entry.second.m_Actions[ 0 ];
129 wxString entryApp = GetAppName( entryAction );
130
131 if( !currentSection || entryApp != currentApp )
132 {
133 m_hk_sections.emplace_back( HOTKEY_SECTION() );
134 currentApp = entryApp;
135 currentSection = &m_hk_sections.back();
136 currentSection->m_SectionName = GetSectionName( entryAction );
137
138 if( aIncludeReadOnlyCmds && currentApp == "common" )
139 {
141 currentSection->m_HotKeys.emplace_back( HOTKEY( command ) );
142 }
143 }
144
145 currentSection->m_HotKeys.emplace_back( HOTKEY( entry.second ) );
146 }
147
148 if( aIncludeReadOnlyCmds )
149 {
150 m_hk_sections.emplace_back( HOTKEY_SECTION() );
151 currentSection = &m_hk_sections.back();
152 currentSection->m_SectionName = _( "Gestures" );
153
154 for( TOOL_ACTION* gesture : g_gesturePseudoActions )
155 currentSection->m_HotKeys.emplace_back( HOTKEY( gesture ) );
156 }
157}
158
159
160std::vector<HOTKEY_SECTION>& HOTKEY_STORE::GetSections()
161{
162 return m_hk_sections;
163}
164
165
167{
168 for( HOTKEY_SECTION& section : m_hk_sections )
169 {
170 for( HOTKEY& hotkey : section.m_HotKeys )
171 {
172 for( TOOL_ACTION* action : hotkey.m_Actions )
173 action->SetHotKey( hotkey.m_EditKeycode );
174 }
175 }
176}
177
178
180{
181 for( HOTKEY_SECTION& section : m_hk_sections )
182 {
183 for( HOTKEY& hotkey : section.m_HotKeys )
184 hotkey.m_EditKeycode = hotkey.m_Actions[ 0 ]->GetDefaultHotKey();
185 }
186}
187
188
190{
191 for( HOTKEY_SECTION& section : m_hk_sections )
192 {
193 for( HOTKEY& hotkey : section.m_HotKeys )
194 hotkey.m_EditKeycode = hotkey.m_Actions[ 0 ]->GetHotKey();
195 }
196}
197
198
199bool HOTKEY_STORE::CheckKeyConflicts( TOOL_ACTION* aAction, long aKey, HOTKEY** aConflict )
200{
201 wxString sectionName = GetSectionName( aAction );
202
203 // Create a fake "TOOL_ACTION" so we can get the section name for "Common" through the API.
204 // Simply declaring a wxString with the value "Common" works, but the goal is to futureproof
205 // the code here as much as possible.
206 TOOL_ACTION commonAction( "common.Control.Fake", AS_GLOBAL, 0, "", "", "" );
207 wxString commonName = GetSectionName( &commonAction );
208
209 for( HOTKEY_SECTION& section : m_hk_sections )
210 {
211 // We can have the same hotkey in multiple sections (i.e. Kicad programs), but if a hotkey
212 // is in "Common" it can't be in any other section and vice versa.
213
214 if( !( section.m_SectionName == sectionName || section.m_SectionName == commonName ) )
215 continue;
216
217 for( HOTKEY& hotkey : section.m_HotKeys )
218 {
219 if( hotkey.m_Actions[0] == aAction )
220 continue;
221
222 if( hotkey.m_EditKeycode == aKey )
223 {
224 // We can use the same key for a different action if both actions are contextual and
225 // for different tools.
226 if( hotkey.m_Actions[0]->GetScope() == AS_CONTEXT &&
227 aAction->GetScope() == AS_CONTEXT &&
228 hotkey.m_Actions[0]->GetToolName() != aAction->GetToolName() )
229 {
230 continue;
231 }
232
233 *aConflict = &hotkey;
234 return true;
235 }
236 }
237 }
238
239 return false;
240}
const char * name
Definition: DXF_plotter.cpp:56
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
bool CheckKeyConflicts(TOOL_ACTION *aAction, long aKey, HOTKEY **aConflict)
Check whether the given key conflicts with anything in this store.
void ResetAllHotkeysToOriginal()
Resets every hotkey to the original values.
void ResetAllHotkeysToDefault()
Reset every hotkey in the store to the default values.
HOTKEY_STORE()
Construct a HOTKEY_STORE from a list of hotkey sections.
void Init(std::vector< TOOL_ACTION * > aActionsList, bool aIncludeReadOnlyCmds)
std::vector< HOTKEY_SECTION > & GetSections()
Get the list of sections managed by this store.
std::vector< HOTKEY_SECTION > m_hk_sections
Definition: hotkey_store.h:111
void SaveAllHotkeys()
Persist all changes to hotkeys in the store to the underlying data structures.
static wxString GetSectionName(TOOL_ACTION *aAction)
static wxString GetAppName(TOOL_ACTION *aAction)
PSEUDO_ACTION(const wxString &aLabel, int aHotKey)
Represent a single user action.
Definition: tool_action.h:68
void SetHotKey(int aKeycode)
TOOL_ACTION_SCOPE GetScope() const
Definition: tool_action.h:160
std::string GetToolName() const
Return name of the tool associated with the action.
wxString m_label
Definition: tool_action.h:213
const std::string & GetName() const
Return name of the action.
Definition: tool_action.h:101
#define _(s)
Base window classes and related definitions.
static PSEUDO_ACTION * g_gesturePseudoActions[]
static PSEUDO_ACTION * g_standardPlatformCommands[]
#define PSEUDO_WXK_WHEEL
Definition: hotkeys_basic.h:52
#define PSEUDO_WXK_DBLCLICK
Definition: hotkeys_basic.h:51
#define PSEUDO_WXK_CLICK
Definition: hotkeys_basic.h:50
std::vector< HOTKEY > m_HotKeys
Definition: hotkey_store.h:54
wxString m_SectionName
Definition: hotkey_store.h:53
int m_EditKeycode
Definition: hotkey_store.h:37
std::vector< TOOL_ACTION * > m_Actions
Definition: hotkey_store.h:36
@ 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
@ MD_CTRL
Definition: tool_event.h:139
@ MD_SHIFT
Definition: tool_event.h:138