KiCad PCB EDA Suite
Loading...
Searching...
No Matches
common_control.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) 2014-2016 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// kicad_curl_easy.h must be included before wxWidgets because on Windows (msys2), there are
22// collision with wx headers and curl.h defs
24
25#include <bitmaps.h>
26#include <build_version.h>
27#include <common.h> // for SearchHelpFileFullPath
28#include <pgm_base.h>
29#include <tool/actions.h>
30#include <tool/tool_manager.h>
31#include <eda_draw_frame.h>
32#include <view/view.h>
34#include <base_screen.h>
35#include <tool/common_control.h>
36
38#include <id.h>
39#include <kiface_base.h>
41#include <eda_doc.h>
42#include <launch_ext.h>
43#include <paths.h>
44#include <wx/filename.h>
45#include <wx/msgdlg.h>
46#include <executable_names.h>
47#include <gestfich.h>
49#include <confirm.h>
50#include <reporter.h>
51#include <widgets/kistatusbar.h>
52
53#define URL_GET_INVOLVED wxS( "https://go.kicad.org/contribute/" )
54#define URL_DONATE wxS( "https://go.kicad.org/app-donate" )
55#define URL_DOCUMENTATION wxS( "https://go.kicad.org/docs/" )
56
57
60 wxS( "https://gitlab.com/kicad/code/kicad/-/issues/new?issuable_template=bare&issue"
61 "[description]=%s" );
62
63
66 "```\n"
67 "%s\n"
68 "```" );
69
70
75
76
78{
79 m_frame->ShowPreferences( wxEmptyString, wxEmptyString );
80 return 0;
81}
82
83
85{
86 // If _pcbnew.kiface is running have it put up the dialog so the 3D paths can also
87 // be edited
88 if( KIFACE* pcbnew = m_frame->Kiway().KiFACE( KIWAY::FACE_PCB, false ) )
89 {
90 try
91 {
92 pcbnew->CreateKiWindow( m_frame, DIALOG_CONFIGUREPATHS, &m_frame->Kiway() );
93 }
94 catch( ... )
95 {
96 // Do nothing here.
97 // A error message is displayed after trying to load _pcbnew.kiface.
98 }
99 }
100 else
101 {
103
104 if( dlg.ShowModal() == wxID_OK )
105 m_frame->Kiway().CommonSettingsChanged( ENVVARS_CHANGED );
106 }
107
108 return 0;
109}
110
111
113{
115 {
116 try // Sch frame was not available, try to start it
117 {
118 if( KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_SCH ) )
119 kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
120 }
121 catch( ... )
122 {
123 // _eeschema.kiface is not available: it contains the library table dialog.
124 // Do nothing here.
125 // A error message is displayed after trying to load _eeschema.kiface.
126 }
127 }
128 else if( aEvent.IsAction( &ACTIONS::showFootprintLibTable ) )
129 {
130 try // Pcb frame was not available, try to start it
131 {
132 if( KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_PCB ) )
133 kiface->CreateKiWindow( m_frame, DIALOG_PCB_LIBRARY_TABLE, &m_frame->Kiway() );
134 }
135 catch( ... )
136 {
137 // _pcbnew.kiface is not available: it contains the library table dialog.
138 // Do nothing here.
139 // A error message is displayed after trying to load _pcbnew.kiface.
140 }
141 }
142 else if( aEvent.IsAction( &ACTIONS::showDesignBlockLibTable ) )
143 {
144 try // Kicad frame was not available, try to start it
145 {
146 if( KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_SCH ) )
147 kiface->CreateKiWindow( m_frame, DIALOG_DESIGN_BLOCK_LIBRARY_TABLE, &m_frame->Kiway() );
148 }
149 catch( ... )
150 {
151 // _eeschema.kiface is not available: it contains the library table dialog.
152 // Do nothing here.
153 // A error message is displayed after trying to load _eeschema.kiface.
154 }
155 }
156
157 return 0;
158}
159
160
162{
163 // Needed on Windows, other platforms do not use it, but it creates no issue
164 if( aFrame->IsIconized() )
165 aFrame->Iconize( false );
166
167 aFrame->Raise();
168
169 // Raising the window does not set the focus on Linux. This should work on
170 // any platform.
171 if( wxWindow::FindFocus() != aFrame )
172 aFrame->SetFocus();
173
174 // If the player is currently blocked, focus the user attention on the correct window
175 if( wxWindow* blocking_win = aFrame->Kiway().GetBlockingDialog() )
176 {
177 blocking_win->Raise();
178 blocking_win->SetFocus();
179 }
180}
181
182
184{
185 FRAME_T playerType = aEvent.Parameter<FRAME_T>();
186 KIWAY_PLAYER* editor = m_frame->Kiway().Player( playerType, true );
187
188 // editor can be null if Player() fails:
189 wxCHECK_MSG( editor != nullptr, 0, wxT( "Cannot open/create the editor frame" ) );
190
191 showFrame( editor );
192
193 return 0;
194}
195
196
198{
199 m_frame->CallAfter(
200 [this]()
201 {
202 m_frame->Kiway().OnKiCadExit();
203 } );
204
205 return 0;
206}
207
208
209class TERMINATE_HANDLER : public wxProcess
210{
211public:
212 TERMINATE_HANDLER( const wxString& appName )
213 { }
214
215 void OnTerminate( int pid, int status ) override
216 {
217 delete this;
218 }
219};
220
221
222int COMMON_CONTROL::Execute( const wxString& aExecutible, const wxString& aParam )
223{
224 TERMINATE_HANDLER* callback = new TERMINATE_HANDLER( aExecutible );
225
226 bool isKicadBinary = false;
227
228 if( aExecutible == GERBVIEW_EXE || aExecutible == BITMAPCONVERTER_EXE
229 || aExecutible == PCB_CALCULATOR_EXE || aExecutible == PL_EDITOR_EXE
230 || aExecutible == EESCHEMA_EXE || aExecutible == PCBNEW_EXE )
231 {
232 isKicadBinary = true;
233 }
234
235 long pid = ExecuteFile( aExecutible, aParam, callback, isKicadBinary );
236
237 if( pid > 0 )
238 {
239#ifdef __WXMAC__
240 wxString script;
241
242 script.Printf( wxS( "tell application \"System Events\" to tell application process \"%s\"\n"
243 " set frontmost to true\n"
244 "end tell" ),
245 aExecutible );
246
247 // This non-parameterized use of wxExecute is fine because script is not derived
248 // from user input.
249 wxExecute( wxString::Format( "osascript -e '%s'", script ) );
250#endif
251 }
252 else
253 {
254 delete callback;
255 }
256
257 return 0;
258}
259
260
262{
263 wxString execFile;
264 wxString param;
265
267 execFile = PCB_CALCULATOR_EXE;
268 else
269 wxFAIL_MSG( "Execute(): unexpected request" );
270
271 if( execFile.IsEmpty() )
272 return 0;
273
274 return Execute( execFile, param );
275}
276
277
279{
280 // Note: dynamic_cast doesn't work over the Kiway() on MacOS. We have to use static_cast
281 // here.
282 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_frame->Kiway().GetTop() );
283
284 if( top && top->GetFrameType() == KICAD_MAIN_FRAME_T )
285 showFrame( top );
286 else
287 KICAD_MESSAGE_DIALOG( m_frame, _( "Can not switch to project manager in stand-alone mode." ) );
288
289 return 0;
290}
291
292
294{
295 wxString helpFile;
296 wxString msg;
297
298 // the URL of help files is "https://go.kicad.org/docs/<version>/<language>/<name>/"
299 const wxString baseUrl = URL_DOCUMENTATION + GetMajorMinorVersion() + wxT( "/" )
300 + Pgm().GetLocale()->GetName().BeforeLast( '_' ) + wxT( "/" );
301
302 /* We have to get document for beginners,
303 * or the full specific doc
304 * if event id is wxID_INDEX, we want the document for beginners.
305 * else the specific doc file (its name is in Kiface().GetHelpFileName())
306 * The document for beginners is the same for all KiCad utilities
307 */
308 if( aEvent.IsAction( &ACTIONS::gettingStarted ) )
309 {
310 // List of possible names for Getting Started in KiCad
311 const wxChar* names[2] = {
312 wxT( "getting_started_in_kicad" ),
313 wxT( "Getting_Started_in_KiCad" )
314 };
315
316 // Search for "getting_started_in_kicad.html" or "getting_started_in_kicad.pdf"
317 // or "Getting_Started_in_KiCad.html" or "Getting_Started_in_KiCad.pdf"
318 for( auto& name : names )
319 {
320 helpFile = SearchHelpFileFullPath( name );
321
322 if( !helpFile.IsEmpty() )
323 break;
324 }
325
326 if( !helpFile )
327 {
328 msg = wxString::Format( _( "Help file '%s' or\n'%s' could not be found.\n"
329 "Do you want to access the KiCad online help?" ),
330 names[0], names[1] );
331 KICAD_MESSAGE_DIALOG dlg( nullptr, msg, _( "File Not Found" ),
332 wxYES_NO | wxNO_DEFAULT | wxCANCEL );
333
334 if( dlg.ShowModal() != wxID_YES )
335 return -1;
336
337 helpFile = baseUrl + names[0] + wxS( "/" );
338 }
339 }
340 else
341 {
342 wxString base_name = m_frame->help_name();
343
344 helpFile = SearchHelpFileFullPath( base_name );
345
346 if( !helpFile )
347 {
348 msg = wxString::Format( _( "Help file '%s' could not be found.\n"
349 "Do you want to access the KiCad online help?" ),
350 base_name );
351 KICAD_MESSAGE_DIALOG dlg( nullptr, msg, _( "File Not Found" ),
352 wxYES_NO | wxNO_DEFAULT | wxCANCEL );
353
354 if( dlg.ShowModal() != wxID_YES )
355 return -1;
356
357 helpFile = baseUrl + base_name + wxS( "/" );
358 }
359 }
360
361 GetAssociatedDocument( m_frame, helpFile, &m_frame->Prj() );
362 return 0;
363}
364
365
367{
368 void ShowAboutDialog( EDA_BASE_FRAME * aParent ); // See AboutDialog_main.cpp
370 return 0;
371}
372
373
375{
377 return 0;
378}
379
380
382{
383 if( !wxLaunchDefaultBrowser( URL_GET_INVOLVED ) )
384 {
385 wxString msg;
386 msg.Printf( _( "Could not launch the default browser.\n"
387 "For information on how to help the KiCad project, visit %s" ),
389 wxMessageBox( msg, _( "Get involved with KiCad" ), wxOK, m_frame );
390 }
391
392 return 0;
393}
394
395
397{
398 if( !wxLaunchDefaultBrowser( URL_DONATE ) )
399 {
400 wxString msg;
401 msg.Printf( _( "Could not launch the default browser.\n"
402 "To donate to the KiCad project, visit %s" ),
403 URL_DONATE );
404 wxMessageBox( msg, _( "Donate to KiCad" ), wxOK, m_frame );
405 }
406
407 return 0;
408}
409
410
412{
414 return 0;
415
416 wxString version = GetVersionInfoData( m_frame->GetUntranslatedAboutTitle(), false, true );
417
418 wxString message;
419 message.Printf( m_bugReportTemplate, version );
420
421 KICAD_CURL_EASY kcurl;
422 wxString url_string;
423 url_string.Printf( m_bugReportUrl, kcurl.Escape( std::string( message.utf8_str() ) ) );
424
425 wxLaunchDefaultBrowser( url_string );
426
427 return 0;
428}
429
430
432{
433 if( Pgm().GetCommonSettings()->m_Api.enable_server )
434 {
435 std::shared_ptr<REPORTER> reporter;
436
437 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( m_frame->GetStatusBar() ) )
438 reporter = std::make_shared<STATUSBAR_WARNING_REPORTER>( statusBar, wxS( "plugin" ) );
439
440 Pgm().GetPluginManager().ReloadPlugins( std::nullopt, reporter );
441 }
442 return 0;
443}
444
445
447{
448 wxString dir( PATHS::GetUserPluginsPath() );
449
450 if( !wxFileName::DirExists( dir ) )
451 {
452 if( !PATHS::EnsurePathExists( dir ) )
453 {
455 wxString::Format( _( "Unable to create plugin directory '%s'." ),
456 dir ) );
457 return 0;
458 }
459 }
460
461 if( !LaunchExternal( dir ) )
463 wxString::Format( _( "Unable to open plugin directory '%s'." ),
464 dir ) );
465
466 return 0;
467}
468
469
471{
472 Go( &COMMON_CONTROL::Quit, ACTIONS::quit.MakeEvent() );
473
485
492 Go( &COMMON_CONTROL::About, ACTIONS::about.MakeEvent() );
495}
496
497
void ShowAboutDialog(EDA_BASE_FRAME *aParent)
const char * name
BASE_SCREEN class implementation.
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
wxString GetVersionInfoData(const wxString &aTitle, bool aHtml, bool aBrief)
Create a version info string for bug reports and the about dialog.
static TOOL_ACTION showCalculatorTools
Definition actions.h:259
static TOOL_ACTION about
Definition actions.h:286
static TOOL_ACTION reportBug
Definition actions.h:290
static TOOL_ACTION pluginsReload
Definition actions.h:293
static TOOL_ACTION showSymbolLibTable
Definition actions.h:281
static TOOL_ACTION showSymbolEditor
Definition actions.h:256
static TOOL_ACTION showSymbolBrowser
Definition actions.h:255
static TOOL_ACTION pluginsShowFolder
Definition actions.h:294
static TOOL_ACTION donate
Definition actions.h:288
static TOOL_ACTION listHotKeys
Definition actions.h:287
static TOOL_ACTION openPreferences
Definition actions.h:279
static TOOL_ACTION getInvolved
Definition actions.h:289
static TOOL_ACTION showFootprintLibTable
Definition actions.h:282
static TOOL_ACTION quit
Definition actions.h:62
static TOOL_ACTION showDesignBlockLibTable
Definition actions.h:283
static TOOL_ACTION showFootprintEditor
Definition actions.h:258
static TOOL_ACTION configurePaths
Definition actions.h:280
static TOOL_ACTION showProjectManager
Definition actions.h:253
static TOOL_ACTION gettingStarted
Definition actions.h:284
static TOOL_ACTION showFootprintBrowser
Definition actions.h:257
static TOOL_ACTION help
Definition actions.h:285
void ReloadPlugins(std::optional< wxString > aDirectoryToScan=std::nullopt, std::shared_ptr< REPORTER > aReporter=nullptr)
Clears the loaded plugins and actions and re-scans the filesystem to register new ones.
int ConfigurePaths(const TOOL_EVENT &aEvent)
int ShowHelp(const TOOL_EVENT &aEvent)
EDA_BASE_FRAME * m_frame
Pointer to the currently used edit frame.
int ShowLibraryTable(const TOOL_EVENT &aEvent)
int Quit(const TOOL_EVENT &aEvent)
int ShowPluginFolder(const TOOL_EVENT &aEvent)
int ReloadPlugins(const TOOL_EVENT &aEvent)
int About(const TOOL_EVENT &aEvent)
int ListHotKeys(const TOOL_EVENT &aEvent)
static wxString m_bugReportUrl
URL to launch a new issue with pre-populated description.
int GetInvolved(const TOOL_EVENT &aEvent)
int ShowProjectManager(const TOOL_EVENT &aEvent)
int Execute(const TOOL_EVENT &aEvent)
int ReportBug(const TOOL_EVENT &aEvent)
int ShowPlayer(const TOOL_EVENT &aEvent)
int Donate(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int OpenPreferences(const TOOL_EVENT &aEvent)
static wxString m_bugReportTemplate
Issue template to use for reporting bugs (this should not be translated)
void setTransitions() override
Sets up handlers for various events.
int ShowModal() override
The base frame for deriving all KiCad main window classes.
std::string Escape(const std::string &aUrl)
Escapes a string for use as a URL.
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition kistatusbar.h:50
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition kiway.cpp:680
@ FACE_SCH
eeschema DSO
Definition kiway.h:355
@ FACE_PCB
pcbnew DSO
Definition kiway.h:356
static wxString GetUserPluginsPath()
Gets the user path for plugins.
Definition paths.cpp:49
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition paths.cpp:508
virtual API_PLUGIN_MANAGER & GetPluginManager() const
Definition pgm_base.h:139
virtual wxLocale * GetLocale()
Definition pgm_base.h:174
void OnTerminate(int pid, int status) override
TERMINATE_HANDLER(const wxString &appName)
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
Generic, UI-independent tool event.
Definition tool_event.h:167
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:484
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
bool WarnUserIfOperatingSystemUnsupported()
Checks if the operating system is explicitly unsupported and displays a disclaimer message box.
Definition common.cpp:1001
#define URL_DONATE
#define URL_DOCUMENTATION
void showFrame(EDA_BASE_FRAME *aFrame)
#define URL_GET_INVOLVED
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define KICAD_MESSAGE_DIALOG
Definition confirm.h:48
#define _(s)
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths, std::vector< EMBEDDED_FILES * > aFilesStack)
Open a document (file) with the suitable browser.
Definition eda_doc.cpp:59
This file is part of the common library.
KiCad executable names.
const wxString EESCHEMA_EXE
const wxString GERBVIEW_EXE
const wxString PL_EDITOR_EXE
const wxString BITMAPCONVERTER_EXE
const wxString PCBNEW_EXE
const wxString PCB_CALCULATOR_EXE
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:29
@ DIALOG_PCB_LIBRARY_TABLE
Definition frame_type.h:133
@ DIALOG_SCH_LIBRARY_TABLE
Definition frame_type.h:132
@ DIALOG_CONFIGUREPATHS
Definition frame_type.h:130
@ DIALOG_DESIGN_BLOCK_LIBRARY_TABLE
Definition frame_type.h:131
@ KICAD_MAIN_FRAME_T
Definition frame_type.h:69
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
Definition gestfich.cpp:166
void DisplayHotkeyList(EDA_BASE_FRAME *aParent)
Display the current hotkey list.
std::string message
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
wxString SearchHelpFileFullPath(const wxString &aBaseName)
Return the help file's full path.
Implement a participant in the KIWAY alchemy.
Definition kiway.h:153
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
IbisParser parser & reporter
KIBIS top(path, &reporter)
#define ENVVARS_CHANGED