KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eda_base_frame.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2013 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2023 CERN (www.cern.ch)
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
28#include "kicad_manager_frame.h"
29#include <eda_base_frame.h>
30
31#include <advanced_config.h>
32#include <bitmaps.h>
33#include <bitmap_store.h>
34#include <dialog_shim.h>
41#include <eda_dde.h>
42#include <file_history.h>
43#include <id.h>
44#include <kiface_base.h>
45#include <hotkeys_basic.h>
47#include <paths.h>
48#include <local_history.h>
49#include <confirm.h>
51#include <pgm_base.h>
56#include <tool/action_manager.h>
57#include <tool/action_menu.h>
58#include <tool/action_toolbar.h>
59#include <tool/actions.h>
60#include <tool/common_control.h>
61#include <tool/tool_manager.h>
64#include <trace_helpers.h>
67#include <widgets/wx_infobar.h>
70#include <widgets/wx_grid.h>
71#include <widgets/wx_treebook.h>
72#include <wx/app.h>
73#include <wx/config.h>
74#include <wx/display.h>
75#include <wx/stdpaths.h>
76#include <wx/string.h>
77#include <wx/msgdlg.h>
78#include <wx/wupdlock.h>
79#include <kiplatform/app.h>
80#include <kiplatform/io.h>
81#include <kiplatform/ui.h>
82
83#include <nlohmann/json.hpp>
84
85#include <functional>
86#include <kiface_ids.h>
87
88#ifdef KICAD_IPC_API
89#include <api/api_server.h>
90#endif
91
92
93// Minimum window size
94static const wxSize minSizeLookup( FRAME_T aFrameType, wxWindow* aWindow )
95{
96 switch( aFrameType )
97 {
99 return wxWindow::FromDIP( wxSize( 406, 354 ), aWindow );
100
101 default:
102 return wxWindow::FromDIP( wxSize( 500, 400 ), aWindow );
103 }
104}
105
106
107static const wxSize defaultSize( FRAME_T aFrameType, wxWindow* aWindow )
108{
109 switch( aFrameType )
110 {
112 return wxWindow::FromDIP( wxSize( 850, 540 ), aWindow );
113
114 default:
115 return wxWindow::FromDIP( wxSize( 1280, 720 ), aWindow );
116 }
117}
118
119
120BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
121 // These event table entries are needed to handle events from the mac application menu
122 EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::OnKicadAbout )
123 EVT_MENU( wxID_PREFERENCES, EDA_BASE_FRAME::OnPreferences )
124
125 EVT_CHAR_HOOK( EDA_BASE_FRAME::OnCharHook )
126 EVT_MENU_OPEN( EDA_BASE_FRAME::OnMenuEvent )
127 EVT_MENU_CLOSE( EDA_BASE_FRAME::OnMenuEvent )
128 EVT_MENU_HIGHLIGHT_ALL( EDA_BASE_FRAME::OnMenuEvent )
129 EVT_MOVE( EDA_BASE_FRAME::OnMove )
130 EVT_SIZE( EDA_BASE_FRAME::OnSize )
131 EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize )
132
133 EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange )
134 EVT_ICONIZE( EDA_BASE_FRAME::onIconize )
135END_EVENT_TABLE()
136
137
139{
140 m_ident = aFrameType;
141 m_maximizeByDefault = false;
142 m_infoBar = nullptr;
143 m_settingsManager = nullptr;
144 m_fileHistory = nullptr;
145 m_supportsAutoSave = false;
146 m_autoSavePending = false;
148 m_isClosing = false;
149 m_isNonUserClose = false;
150 m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
151 m_autoSaveRequired = false;
154 m_frameSize = defaultSize( aFrameType, this );
155 m_displayIndex = -1;
156
157 m_auimgr.SetArtProvider( new WX_AUI_DOCK_ART() );
158
160
161 // Set a reasonable minimal size for the frame
162 wxSize minSize = minSizeLookup( aFrameType, this );
163 SetSizeHints( minSize.x, minSize.y, -1, -1, -1, -1 );
164
165 // Store dimensions of the user area of the main window.
166 GetClientSize( &m_frameSize.x, &m_frameSize.y );
167
168 Connect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
169 wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
170
171 // hook wxEVT_CLOSE_WINDOW so we can call SaveSettings(). This function seems
172 // to be called before any other hook for wxCloseEvent, which is necessary.
173 Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
174
175 initExitKey();
176}
177
178
179EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle,
180 const wxPoint& aPos, const wxSize& aSize, long aStyle,
181 const wxString& aFrameName, KIWAY* aKiway,
182 const EDA_IU_SCALE& aIuScale ) :
183 wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ),
184 TOOLS_HOLDER(),
185 KIWAY_HOLDER( aKiway, KIWAY_HOLDER::FRAME ),
186 UNITS_PROVIDER( aIuScale, EDA_UNITS::MM )
187{
188 m_tbTopMain = nullptr;
189 m_tbTopAux = nullptr;
190 m_tbRight = nullptr;
191 m_tbLeft = nullptr;
192
193 commonInit( aFrameType );
194
195 Bind( wxEVT_DPI_CHANGED,
196 [&]( wxDPIChangedEvent& aEvent )
197 {
198#ifdef __WXMSW__
199 // Workaround to update toolbar sizes on MSW
200 if( m_auimgr.GetManagedWindow() )
201 {
202 wxAuiPaneInfoArray& panes = m_auimgr.GetAllPanes();
203
204 for( size_t ii = 0; ii < panes.GetCount(); ii++ )
205 {
206 wxAuiPaneInfo& pinfo = panes.Item( ii );
207 pinfo.best_size = pinfo.window->GetSize();
208
209 // But we still shouldn't make it too small.
210 pinfo.best_size.IncTo( pinfo.window->GetBestSize() );
211 pinfo.best_size.IncTo( pinfo.min_size );
212 }
213
214 m_auimgr.Update();
215 }
216#endif
217
218 aEvent.Skip();
219 } );
220}
221
222
223wxWindow* findQuasiModalDialog( wxWindow* aParent )
224{
225 for( wxWindow* child : aParent->GetChildren() )
226 {
227 if( DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( child ) )
228 {
229 if( dlg->IsQuasiModal() )
230 return dlg;
231
232 if( wxWindow* nestedDlg = findQuasiModalDialog( child ) )
233 return nestedDlg;
234 }
235 }
236
237 return nullptr;
238}
239
240
242{
243 if( wxWindow* dlg = ::findQuasiModalDialog( this ) )
244 return dlg;
245
246 // FIXME: CvPcb is currently implemented on top of KIWAY_PLAYER rather than DIALOG_SHIM,
247 // so we have to look for it separately.
248 if( m_ident == FRAME_SCH )
249 {
250 wxWindow* cvpcb = wxWindow::FindWindowByName( wxS( "CvpcbFrame" ) );
251
252 if( cvpcb )
253 return cvpcb;
254 }
255
256 return nullptr;
257}
258
259
260void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
261{
262 // Don't allow closing when a quasi-modal is open.
263 wxWindow* quasiModal = findQuasiModalDialog();
264
265 if( quasiModal )
266 {
267 // Raise and notify; don't give the user a warning regarding "quasi-modal dialogs"
268 // when they have no idea what those are.
269 quasiModal->Raise();
270 wxBell();
271
272 if( event.CanVeto() )
273 event.Veto();
274
275 return;
276 }
277
278
279 if( event.GetId() == wxEVT_QUERY_END_SESSION
280 || event.GetId() == wxEVT_END_SESSION )
281 {
282 // End session means the OS is going to terminate us
283 m_isNonUserClose = true;
284 }
285
286 if( canCloseWindow( event ) )
287 {
288 m_isClosing = true;
289
290 if( m_infoBar )
291 m_infoBar->Dismiss();
292
293 APP_SETTINGS_BASE* cfg = config();
294
295 if( cfg )
296 SaveSettings( cfg ); // virtual, wxFrame specific
297
299
300 // Destroy (safe delete frame) this frame only in non modal mode.
301 // In modal mode, the caller will call Destroy().
302 if( !IsModal() )
303 Destroy();
304 }
305 else
306 {
307 if( event.CanVeto() )
308 event.Veto();
309 }
310}
311
312
314{
315 Disconnect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
316 wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
317 Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
318
319 delete m_autoSaveTimer;
320 delete m_fileHistory;
321
323
325
327}
328
329
330bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent )
331{
332#ifdef __WXMAC__
333 // Apple in its infinite wisdom will raise a disabled window before even passing
334 // us the event, so we have no way to stop it. Instead, we have to catch an
335 // improperly ordered disabled window and quasi-modal dialog here and reorder
336 // them.
337 if( !IsEnabled() && IsActive() )
338 {
339 wxWindow* dlg = findQuasiModalDialog();
340
341 if( dlg )
342 dlg->Raise();
343 }
344#endif
345
346#ifdef __WXMSW__
347 // When changing DPI to a lower value, somehow, called from wxNonOwnedWindow::HandleDPIChange,
348 // our sizers compute a min size that is larger than the old frame size. wx then sets this wrong size.
349 // This shouldn't be needed since the OS have already sent a size event.
350 // Avoid this wx behaviour by pretending we've processed the event even if we use Skip in handlers.
351 if( aEvent.GetEventType() == wxEVT_DPI_CHANGED )
352 {
353 wxFrame::ProcessEvent( aEvent );
354 return true;
355 }
356#endif
357
358 if( !wxFrame::ProcessEvent( aEvent ) )
359 return false;
360
361 if( Pgm().m_Quitting )
362 return true;
363
364 if( !m_isClosing && m_supportsAutoSave && IsShownOnScreen() && IsActive()
366 && GetAutoSaveInterval() > 0 )
367 {
368 if( !m_autoSavePending )
369 {
370 wxLogTrace( traceAutoSave, wxT( "Starting auto save timer." ) );
371 m_autoSaveTimer->Start( GetAutoSaveInterval() * 1000, wxTIMER_ONE_SHOT );
372 m_autoSavePending = true;
373 }
374 else if( m_autoSaveTimer->IsRunning() )
375 {
376 wxLogTrace( traceAutoSave, wxT( "Stopping auto save timer." ) );
377 m_autoSaveTimer->Stop();
378 m_autoSavePending = false;
379 }
380 }
381
382 return true;
383}
384
385
390
391
392void EDA_BASE_FRAME::onAutoSaveTimer( wxTimerEvent& aEvent )
393{
394 // Don't stomp on someone else's timer event.
395 if( aEvent.GetId() != ID_AUTO_SAVE_TIMER )
396 {
397 aEvent.Skip();
398 return;
399 }
400
401 if( !doAutoSave() )
402 m_autoSaveTimer->Start( GetAutoSaveInterval() * 1000, wxTIMER_ONE_SHOT );
403}
404
405
407{
408 m_autoSaveRequired = false;
409 m_autoSavePending = false;
410
411 // Use registered saver callbacks to snapshot editor state into .history and only commit
412 // if there are material changes.
413 if( !Prj().IsReadOnly() )
414 Kiway().LocalHistory().RunRegisteredSaversAndCommit( Prj().GetProjectPath(), wxS( "Autosave" ) );
415
416 return true;
417}
418
419
420void EDA_BASE_FRAME::OnCharHook( wxKeyEvent& aKeyEvent )
421{
422 wxLogTrace( kicadTraceKeyEvent, wxS( "EDA_BASE_FRAME::OnCharHook %s" ), dump( aKeyEvent ) );
423
424 // Key events can be filtered here.
425 // Currently no filtering is made.
426 aKeyEvent.Skip();
427}
428
429
430void EDA_BASE_FRAME::OnMenuEvent( wxMenuEvent& aEvent )
431{
432 if( !m_toolDispatcher )
433 aEvent.Skip();
434 else
435 m_toolDispatcher->DispatchWxEvent( aEvent );
436}
437
438
440{
442 std::placeholders::_1,
443 this,
444 aConditions );
445
446 m_uiUpdateMap[aID] = evtFunc;
447
448 Bind( wxEVT_UPDATE_UI, evtFunc, aID );
449}
450
451
453{
454 const auto it = m_uiUpdateMap.find( aID );
455
456 if( it == m_uiUpdateMap.end() )
457 return;
458
459 Unbind( wxEVT_UPDATE_UI, it->second, aID );
460}
461
462
463void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
464 ACTION_CONDITIONS aCond )
465{
466 bool checkRes = false;
467 bool enableRes = true;
468 bool showRes = true;
469 bool isCut = aEvent.GetId() == ACTIONS::cut.GetUIId();
470 bool isCopy = aEvent.GetId() == ACTIONS::copy.GetUIId();
471 bool isPaste = aEvent.GetId() == ACTIONS::paste.GetUIId();
472 SELECTION& selection = aFrame->GetCurrentSelection();
473
474 try
475 {
476 checkRes = aCond.checkCondition( selection );
477 enableRes = aCond.enableCondition( selection );
478 showRes = aCond.showCondition( selection );
479 }
480 catch( std::exception& )
481 {
482 // Something broke with the conditions, just skip the event.
483 aEvent.Skip();
484 return;
485 }
486
487 if( showRes && aEvent.GetId() == ACTIONS::undo.GetUIId() )
488 {
489 wxString msg = _( "Undo" );
490
491 if( enableRes )
492 msg += wxS( " " ) + aFrame->GetUndoActionDescription();
493
494 aEvent.SetText( msg );
495 }
496 else if( showRes && aEvent.GetId() == ACTIONS::redo.GetUIId() )
497 {
498 wxString msg = _( "Redo" );
499
500 if( enableRes )
501 msg += wxS( " " ) + aFrame->GetRedoActionDescription();
502
503 aEvent.SetText( msg );
504 }
505
506 if( isCut || isCopy || isPaste )
507 {
508 wxWindow* focus = wxWindow::FindFocus();
509 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( focus );
510
511 if( textEntry && isCut && textEntry->CanCut() )
512 enableRes = true;
513 else if( textEntry && isCopy && textEntry->CanCopy() )
514 enableRes = true;
515 else if( textEntry && isPaste && textEntry->CanPaste() )
516 enableRes = true;
517 else if( dynamic_cast<WX_GRID*>( focus ) )
518 enableRes = false; // Must disable menu in order to get command as CharHook event
519 }
520
521 aEvent.Enable( enableRes );
522 aEvent.Show( showRes );
523
524 if( aEvent.IsCheckable() )
525 aEvent.Check( checkRes );
526}
527
528
530{
531 // Setup the conditions to check a language menu item
532 auto isCurrentLang =
533 [] ( const SELECTION& aSel, int aLangIdentifier )
534 {
535 return Pgm().GetSelectedLanguageIdentifier() == aLangIdentifier;
536 };
537
538 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
539 {
541 cond.Check( std::bind( isCurrentLang, std::placeholders::_1,
542 LanguagesList[ii].m_WX_Lang_Identifier ) );
543 RegisterUIUpdateHandler( LanguagesList[ii].m_KI_Lang_Identifier, cond );
544 }
545}
546
547
549 const ACTION_TOOLBAR_CONTROL_FACTORY& aControlFactory )
550{
551 m_toolbarControlFactories.emplace( aControlDesc.GetName(), aControlFactory );
552}
553
554
556{
557 for( auto& control : m_toolbarControlFactories )
558 {
559 if( control.first == aName )
560 return &control.second;
561 }
562
563 return nullptr;
564}
565
566
570
571
573{
574 wxWindowUpdateLocker dummy( this );
575
576 wxASSERT( m_toolbarSettings );
577
578 std::optional<TOOLBAR_CONFIGURATION> tbConfig;
579
580 // Drawing tools (typically on right edge of window)
581 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::RIGHT, config()->m_CustomToolbars );
582
583 if( tbConfig.has_value() )
584 {
585 if( !m_tbRight )
586 {
587 m_tbRight =
588 new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
589 KICAD_AUI_TB_STYLE | wxAUI_TB_VERTICAL | wxAUI_TB_TEXT | wxAUI_TB_OVERFLOW );
590 m_tbRight->SetAuiManager( &m_auimgr );
591 }
592
593 m_tbRight->ApplyConfiguration( tbConfig.value() );
594 }
595
596 // Options (typically on left edge of window)
597 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::LEFT, config()->m_CustomToolbars );
598
599 if( tbConfig.has_value() )
600 {
601 if( !m_tbLeft )
602 {
603 m_tbLeft = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
604 KICAD_AUI_TB_STYLE | wxAUI_TB_VERTICAL | wxAUI_TB_TEXT | wxAUI_TB_OVERFLOW );
605 m_tbLeft->SetAuiManager( &m_auimgr );
606 }
607
608 m_tbLeft->ApplyConfiguration( tbConfig.value() );
609 }
610
611 // Top main toolbar (the top one)
612 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::TOP_MAIN, config()->m_CustomToolbars );
613
614 if( tbConfig.has_value() )
615 {
616 if( !m_tbTopMain )
617 {
618 m_tbTopMain = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
619 KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_HORIZONTAL
620 | wxAUI_TB_TEXT | wxAUI_TB_OVERFLOW );
621 m_tbTopMain->SetAuiManager( &m_auimgr );
622 }
623
624 m_tbTopMain->ApplyConfiguration( tbConfig.value() );
625 }
626
627 // Top aux toolbar (the bottom one)
628 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::TOP_AUX, config()->m_CustomToolbars );
629
630 if( tbConfig.has_value() )
631 {
632 if( !m_tbTopAux )
633 {
634 m_tbTopAux = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
635 KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_HORIZONTAL
636 | wxAUI_TB_TEXT | wxAUI_TB_OVERFLOW );
637 m_tbTopAux->SetAuiManager( &m_auimgr );
638 }
639
640 m_tbTopAux->ApplyConfiguration( tbConfig.value() );
641 }
642}
643
644
646{
647 if( m_tbTopMain )
648 m_tbTopMain->UpdateControlWidths();
649
650 if( m_tbRight )
651 m_tbRight->UpdateControlWidths();
652
653 if( m_tbLeft )
654 m_tbLeft->UpdateControlWidths();
655
656 if( m_tbTopAux )
657 m_tbTopAux->UpdateControlWidths();
658
659}
660
661
663{
664 if( m_tbTopMain )
665 m_auimgr.GetPane( m_tbTopMain ).MaxSize( m_tbTopMain->GetSize() );
666
667 if( m_tbRight )
668 m_auimgr.GetPane( m_tbRight ).MaxSize( m_tbRight->GetSize() );
669
670 if( m_tbLeft )
671 m_auimgr.GetPane( m_tbLeft ).MaxSize( m_tbLeft->GetSize() );
672
673 if( m_tbTopAux )
674 m_auimgr.GetPane( m_tbTopAux ).MaxSize( m_tbTopAux->GetSize() );
675
676 m_auimgr.Update();
677}
678
679
681{
688
689 CallAfter( [this]()
690 {
691 if( !m_isClosing )
693 } );
694}
695
696
697void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
698{
699 COMMON_CONTROL* commonControl = m_toolManager->GetTool<COMMON_CONTROL>();
700 ACTION_MENU* helpMenu = new ACTION_MENU( false, commonControl );
701
702 helpMenu->Add( ACTIONS::help );
703 helpMenu->Add( ACTIONS::gettingStarted );
704 helpMenu->Add( ACTIONS::listHotKeys );
705 helpMenu->Add( ACTIONS::getInvolved );
706 helpMenu->Add( ACTIONS::donate );
707 helpMenu->Add( ACTIONS::reportBug );
708
709 helpMenu->AppendSeparator();
710 helpMenu->Add( ACTIONS::about );
711
712 aMenuBar->Append( helpMenu, _( "&Help" ) );
713}
714
715
716
718{
719 wxString menuItemLabel = aAction.GetMenuLabel();
720 wxMenuBar* menuBar = GetMenuBar();
721
722 for( size_t ii = 0; ii < menuBar->GetMenuCount(); ++ii )
723 {
724 for( wxMenuItem* menuItem : menuBar->GetMenu( ii )->GetMenuItems() )
725 {
726 if( menuItem->GetItemLabelText() == menuItemLabel )
727 {
728 wxString menuTitleLabel = menuBar->GetMenuLabelText( ii );
729
730 menuTitleLabel.Replace( wxS( "&" ), wxS( "&&" ) );
731 menuItemLabel.Replace( wxS( "&" ), wxS( "&&" ) );
732
733 return wxString::Format( _( "Run: %s > %s" ),
734 menuTitleLabel,
735 menuItemLabel );
736 }
737 }
738 }
739
740 return wxString::Format( _( "Run: %s" ), aAction.GetFriendlyName() );
741};
742
743
745{
747
748 if( GetMenuBar() )
749 {
751 GetMenuBar()->Refresh();
752 }
753}
754
755
757{
759
760 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
761
762#ifdef KICAD_IPC_API
763 bool running = Pgm().GetApiServer().Running();
764
765 if( running && !settings->m_Api.enable_server )
766 Pgm().GetApiServer().Stop();
767 else if( !running && settings->m_Api.enable_server )
768 Pgm().GetApiServer().Start();
769#endif
770
771 if( m_fileHistory )
772 {
773 int historySize = settings->m_System.file_history_size;
774 m_fileHistory->SetMaxFiles( (unsigned) std::max( 0, historySize ) );
775 }
776
777 if( Pgm().GetCommonSettings()->m_Backup.enabled )
778 Kiway().LocalHistory().Init( Prj().GetProjectPath() );
779
781 ThemeChanged();
782
783 if( GetMenuBar() )
784 {
785 // For icons in menus, icon scaling & hotkeys
787 GetMenuBar()->Refresh();
788 }
789
790 // Update the toolbars
792}
793
794
796{
798
799 // Update all the toolbars to have new icons
800 wxAuiPaneInfoArray panes = m_auimgr.GetAllPanes();
801
802 for( size_t i = 0; i < panes.GetCount(); ++i )
803 {
804 if( ACTION_TOOLBAR* toolbar = dynamic_cast<ACTION_TOOLBAR*>( panes[i].window ) )
805 toolbar->RefreshBitmaps();
806 }
807}
808
809
810void EDA_BASE_FRAME::OnSize( wxSizeEvent& aEvent )
811{
812#ifdef __WXMAC__
813 int currentDisplay = wxDisplay::GetFromWindow( this );
814
815 if( m_displayIndex >= 0 && currentDisplay >= 0 && currentDisplay != m_displayIndex )
816 {
817 wxLogTrace( traceDisplayLocation, wxS( "OnSize: current display changed %d to %d" ),
818 m_displayIndex, currentDisplay );
819 m_displayIndex = currentDisplay;
821 }
822#endif
823
824 aEvent.Skip();
825}
826
827
828void EDA_BASE_FRAME::LoadWindowState( const wxString& aFileName )
829{
830 if( !Pgm().GetCommonSettings()->m_Session.remember_open_files )
831 return;
832
833 const PROJECT_FILE_STATE* state = Prj().GetLocalSettings().GetFileState( aFileName );
834
835 if( state != nullptr )
836 {
837 LoadWindowState( state->window );
838 }
839}
840
841
843{
844 bool wasDefault = false;
845
846 m_framePos.x = aState.pos_x;
847 m_framePos.y = aState.pos_y;
848 m_frameSize.x = aState.size_x;
849 m_frameSize.y = aState.size_y;
850
851 wxLogTrace( traceDisplayLocation, wxS( "Config position (%d, %d) with size (%d, %d)" ),
853
854 // Ensure minimum size is set if the stored config was zero-initialized
855 wxSize minSize = minSizeLookup( m_ident, this );
856
857 if( m_frameSize.x < minSize.x || m_frameSize.y < minSize.y )
858 {
860 wasDefault = true;
861
862 wxLogTrace( traceDisplayLocation, wxS( "Using minimum size (%d, %d)" ),
864 }
865
866 wxLogTrace( traceDisplayLocation, wxS( "Number of displays: %d" ), wxDisplay::GetCount() );
867
868 if( aState.display >= wxDisplay::GetCount() )
869 {
870 wxLogTrace( traceDisplayLocation, wxS( "Previous display not found" ) );
871
872 // If it isn't attached, use the first display
873 // Warning wxDisplay has 2 ctor variants. the parameter needs a type:
874 const unsigned int index = 0;
875 wxDisplay display( index );
876 wxRect clientSize = display.GetGeometry();
877
878 m_framePos = wxDefaultPosition;
879
880 // Ensure the window fits on the display, since the other one could have been larger
881 if( m_frameSize.x > clientSize.width )
882 m_frameSize.x = clientSize.width;
883
884 if( m_frameSize.y > clientSize.height )
885 m_frameSize.y = clientSize.height;
886 }
887 else
888 {
889 wxPoint upperRight( m_framePos.x + m_frameSize.x, m_framePos.y );
890 wxPoint upperLeft( m_framePos.x, m_framePos.y );
891
892 wxDisplay display( aState.display );
893 wxRect clientSize = display.GetClientArea();
894
895 int yLimTop = clientSize.y;
896 int yLimBottom = clientSize.y + clientSize.height;
897 int xLimLeft = clientSize.x;
898 int xLimRight = clientSize.x + clientSize.width;
899
900 if( upperLeft.x > xLimRight || // Upper left corner too close to right edge of screen
901 upperRight.x < xLimLeft || // Upper right corner too close to left edge of screen
902 upperLeft.y < yLimTop || // Upper corner too close to the bottom of the screen
903 upperLeft.y > yLimBottom )
904 {
905 m_framePos = wxDefaultPosition;
906 wxLogTrace( traceDisplayLocation, wxS( "Resetting to default position" ) );
907 }
908 }
909
910 wxLogTrace( traceDisplayLocation, wxS( "Final window position (%d, %d) with size (%d, %d)" ),
912
913 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
914
915 // Center the window if we reset to default
916 if( m_framePos.x == -1 )
917 {
918 wxLogTrace( traceDisplayLocation, wxS( "Centering window" ) );
919 Center();
920 m_framePos = GetPosition();
921 }
922
923 // Record the frame sizes in an un-maximized state
926
927 // Maximize if we were maximized before
928 if( aState.maximized || ( wasDefault && m_maximizeByDefault ) )
929 {
930 wxLogTrace( traceDisplayLocation, wxS( "Maximizing window" ) );
931 Maximize();
932 }
933
934 m_displayIndex = wxDisplay::GetFromWindow( this );
935}
936
937
939{
940 wxDisplay display( wxDisplay::GetFromWindow( this ) );
941 wxRect clientSize = display.GetClientArea();
942 wxPoint pos = GetPosition();
943 wxSize size = GetWindowSize();
944
945 wxLogTrace( traceDisplayLocation,
946 wxS( "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d" ),
947 clientSize.x, clientSize.y,
948 clientSize.width, clientSize.height );
949
950 if( pos.y < clientSize.y )
951 {
952 wxLogTrace( traceDisplayLocation,
953 wxS( "ensureWindowIsOnScreen: y pos %d below minimum, setting to %d" ), pos.y,
954 clientSize.y );
955 pos.y = clientSize.y;
956 }
957
958 if( pos.x < clientSize.x )
959 {
960 wxLogTrace( traceDisplayLocation,
961 wxS( "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d" ),
962 pos.x, clientSize.x );
963 pos.x = clientSize.x;
964 }
965
966 if( pos.x + size.x - clientSize.x > clientSize.width )
967 {
968 int newWidth = clientSize.width - ( pos.x - clientSize.x );
969 wxLogTrace( traceDisplayLocation,
970 wxS( "ensureWindowIsOnScreen: effective width %d above available %d, setting "
971 "to %d" ), pos.x + size.x, clientSize.width, newWidth );
972 size.x = newWidth;
973 }
974
975 if( pos.y + size.y - clientSize.y > clientSize.height )
976 {
977 int newHeight = clientSize.height - ( pos.y - clientSize.y );
978 wxLogTrace( traceDisplayLocation,
979 wxS( "ensureWindowIsOnScreen: effective height %d above available %d, setting "
980 "to %d" ), pos.y + size.y, clientSize.height, newHeight );
981 size.y = newHeight;
982 }
983
984 wxLogTrace( traceDisplayLocation, wxS( "Updating window position (%d, %d) with size (%d, %d)" ),
985 pos.x, pos.y, size.x, size.y );
986
987 SetSize( pos.x, pos.y, size.x, size.y );
988}
989
990
1001
1002
1004{
1005 if( IsIconized() )
1006 return;
1007
1008 // If the window is maximized, we use the saved window size from before it was maximized
1009 if( IsMaximized() )
1010 {
1013 }
1014 else
1015 {
1017 m_framePos = GetPosition();
1018 }
1019
1020 aCfg->state.pos_x = m_framePos.x;
1021 aCfg->state.pos_y = m_framePos.y;
1022 aCfg->state.size_x = m_frameSize.x;
1023 aCfg->state.size_y = m_frameSize.y;
1024 aCfg->state.maximized = IsMaximized();
1025 aCfg->state.display = wxDisplay::GetFromWindow( this );
1026
1027 wxLogTrace( traceDisplayLocation, wxS( "Saving window maximized: %s" ),
1028 IsMaximized() ? wxS( "true" ) : wxS( "false" ) );
1029 wxLogTrace( traceDisplayLocation, wxS( "Saving config position (%d, %d) with size (%d, %d)" ),
1031
1032 // Once this is fully implemented, wxAuiManager will be used to maintain
1033 // the persistence of the main frame and all it's managed windows and
1034 // all of the legacy frame persistence position code can be removed.
1035#if wxCHECK_VERSION( 3, 3, 0 )
1036 {
1037 WX_AUI_JSON_SERIALIZER serializer( m_auimgr );
1038 nlohmann::json state = serializer.Serialize();
1039
1040 if( state.is_null() || state.empty() )
1041 aCfg->aui_state = nlohmann::json();
1042 else
1043 aCfg->aui_state = state;
1044
1045 aCfg->perspective.clear();
1046 }
1047#else
1048 aCfg->perspective = m_auimgr.SavePerspective().ToStdString();
1049 aCfg->aui_state = nlohmann::json();
1050#endif
1051
1052 aCfg->mru_path = m_mruPath;
1053}
1054
1055
1057{
1059
1060 // Get file history size from common settings
1061 int fileHistorySize = Pgm().GetCommonSettings()->m_System.file_history_size;
1062
1063 // Load the recently used files into the history menu
1064 m_fileHistory = new FILE_HISTORY( (unsigned) std::max( 1, fileHistorySize ),
1066 m_fileHistory->Load( *aCfg );
1067}
1068
1069
1071{
1072 wxCHECK( config(), /* void */ );
1073
1075
1076 bool fileOpen = m_isClosing && m_isNonUserClose;
1077
1078 wxString currentlyOpenedFile = GetCurrentFileName();
1079
1080 if( Pgm().GetCommonSettings()->m_Session.remember_open_files && !currentlyOpenedFile.IsEmpty() )
1081 {
1082 wxFileName rfn( currentlyOpenedFile );
1083 rfn.MakeRelativeTo( Prj().GetProjectPath() );
1084 Prj().GetLocalSettings().SaveFileState( rfn.GetFullPath(), &aCfg->m_Window, fileOpen );
1085 }
1086
1087 // Save the recently used files list
1088 if( m_fileHistory )
1089 {
1090 // Save the currently opened file in the file history
1091 if( !currentlyOpenedFile.IsEmpty() )
1092 UpdateFileHistory( currentlyOpenedFile );
1093
1094 m_fileHistory->Save( *aCfg );
1095 }
1096}
1097
1098
1103
1104
1106{
1107 // KICAD_MANAGER_FRAME overrides this
1108 return Kiface().KifaceSettings();
1109}
1110
1111
1113{
1114 return Kiface().KifaceSearch();
1115}
1116
1117
1119{
1120 return Kiface().GetHelpFileName();
1121}
1122
1123
1124void EDA_BASE_FRAME::PrintMsg( const wxString& text )
1125{
1126 SetStatusText( text );
1127}
1128
1129
1131{
1132#if defined( __WXOSX_MAC__ )
1134#else
1135 m_infoBar = new WX_INFOBAR( this, &m_auimgr );
1136
1137 m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) ).Top().Layer(1) );
1138#endif
1139}
1140
1141
1143{
1144#if defined( __WXOSX_MAC__ )
1145 m_auimgr.Update();
1146#else
1147 // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
1148 // hiding it.
1149 m_auimgr.Update();
1150
1151 // We don't want the infobar displayed right away
1152 m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
1153 m_auimgr.Update();
1154#endif
1155}
1156
1157
1159{
1160 if( !ADVANCED_CFG::GetCfg().m_EnableUseAuiPerspective )
1161 return;
1162
1163#if wxCHECK_VERSION( 3, 3, 0 )
1164 bool restored = false;
1165
1166 if( !m_auiLayoutState.is_null() && !m_auiLayoutState.empty() )
1167 {
1168 WX_AUI_JSON_SERIALIZER serializer( m_auimgr );
1169
1170 if( serializer.Deserialize( m_auiLayoutState ) )
1171 restored = true;
1172 }
1173
1174 if( !restored && !m_perspective.IsEmpty() )
1175 m_auimgr.LoadPerspective( m_perspective );
1176#else
1177 if( !m_perspective.IsEmpty() )
1178 {
1179 m_auimgr.LoadPerspective( m_perspective );
1180
1181 // Workaround for wx 3.2: LoadPerspective() hides all panes first, then shows only
1182 // those in the saved string. If toolbar names changed or new toolbars were added,
1183 // they'd stay hidden. Ensure all toolbars are visible after restore.
1184 wxAuiPaneInfoArray& panes = m_auimgr.GetAllPanes();
1185
1186 for( size_t i = 0; i < panes.GetCount(); ++i )
1187 {
1188 if( panes.Item( i ).IsToolbar() )
1189 panes.Item( i ).Show( true );
1190 }
1191 }
1192#endif
1193}
1194
1195
1196void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
1198{
1199 m_infoBar->RemoveAllButtons();
1200
1201 if( aShowCloseButton )
1202 m_infoBar->AddCloseButton();
1203
1204 GetInfoBar()->ShowMessageFor( aErrorMsg, 8000, wxICON_ERROR, aType );
1205}
1206
1207
1208void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
1209 std::function<void(void)> aCallback )
1210{
1211 m_infoBar->RemoveAllButtons();
1212
1213 if( aShowCloseButton )
1214 m_infoBar->AddCloseButton();
1215
1216 if( aCallback )
1217 m_infoBar->SetCallback( aCallback );
1218
1219 GetInfoBar()->ShowMessageFor( aErrorMsg, 6000, wxICON_ERROR );
1220}
1221
1222
1223void EDA_BASE_FRAME::ShowInfoBarWarning( const wxString& aWarningMsg, bool aShowCloseButton )
1224{
1225 m_infoBar->RemoveAllButtons();
1226
1227 if( aShowCloseButton )
1228 m_infoBar->AddCloseButton();
1229
1230 GetInfoBar()->ShowMessageFor( aWarningMsg, 6000, wxICON_WARNING );
1231}
1232
1233
1234void EDA_BASE_FRAME::ShowInfoBarMsg( const wxString& aMsg, bool aShowCloseButton )
1235{
1236 m_infoBar->RemoveAllButtons();
1237
1238 if( aShowCloseButton )
1239 m_infoBar->AddCloseButton();
1240
1241 GetInfoBar()->ShowMessageFor( aMsg, 8000, wxICON_INFORMATION );
1242}
1243
1244
1245void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory )
1246{
1247 if( !aFileHistory )
1248 aFileHistory = m_fileHistory;
1249
1250 wxASSERT( aFileHistory );
1251
1252 aFileHistory->AddFileToHistory( FullFileName );
1253
1254 // Update the menubar to update the file history menu
1255 if( !m_isClosing && GetMenuBar() )
1256 {
1258 GetMenuBar()->Refresh();
1259 }
1260}
1261
1262
1263wxString EDA_BASE_FRAME::GetFileFromHistory( int cmdId, const wxString& type, FILE_HISTORY* aFileHistory )
1264{
1265 if( !aFileHistory )
1266 aFileHistory = m_fileHistory;
1267
1268 wxASSERT( aFileHistory );
1269
1270 int baseId = aFileHistory->GetBaseId();
1271
1272 wxASSERT( cmdId >= baseId && cmdId < baseId + (int) aFileHistory->GetCount() );
1273 int i = cmdId - baseId;
1274
1275 wxString fn = aFileHistory->GetHistoryFile( i );
1276
1277 if( !wxFileName::FileExists( fn ) )
1278 {
1279 KICAD_MESSAGE_DIALOG dlg( this, wxString::Format( _( "File '%s' was not found.\n" ), fn ), _( "Error" ),
1280 wxYES_NO | wxYES_DEFAULT | wxICON_ERROR | wxCENTER );
1281
1282 dlg.SetExtendedMessage( _( "Do you want to remove it from list of recently opened files?" ) );
1283 dlg.SetYesNoLabels( KICAD_MESSAGE_DIALOG::ButtonLabel( _( "Remove" ) ),
1284 KICAD_MESSAGE_DIALOG::ButtonLabel( _( "Keep" ) ) );
1285
1286 if( dlg.ShowModal() == wxID_YES )
1287 aFileHistory->RemoveFileFromHistory( i );
1288
1289 fn.Clear();
1290 }
1291
1292 // Update the menubar to update the file history menu
1293 if( GetMenuBar() )
1294 {
1296 GetMenuBar()->Refresh();
1297 }
1298
1299 return fn;
1300}
1301
1302
1304{
1305 wxASSERT( m_fileHistory );
1306
1307 m_fileHistory->ClearFileHistory();
1308
1309 // Update the menubar to update the file history menu
1310 if( GetMenuBar() )
1311 {
1313 GetMenuBar()->Refresh();
1314 }
1315}
1316
1317
1318void EDA_BASE_FRAME::OnKicadAbout( wxCommandEvent& event )
1319{
1320 void ShowAboutDialog( EDA_BASE_FRAME * aParent ); // See AboutDialog_main.cpp
1321 ShowAboutDialog( this );
1322}
1323
1324
1325void EDA_BASE_FRAME::OnPreferences( wxCommandEvent& event )
1326{
1327 ShowPreferences( wxEmptyString, wxEmptyString );
1328}
1329
1330
1331void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParentPage )
1332{
1333 PAGED_DIALOG dlg( this, _( "Preferences" ), true, true, wxEmptyString,
1334 wxWindow::FromDIP( wxSize( 980, 560 ), nullptr ) );
1335
1336 dlg.SetEvtHandlerEnabled( false );
1337
1338 {
1339 WX_BUSY_INDICATOR busy_cursor;
1340
1341 WX_TREEBOOK* book = dlg.GetTreebook();
1342 PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( this, book );
1343 std::vector<int> expand;
1344
1345 wxWindow* kicadMgr_window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
1346
1347 if( KICAD_MANAGER_FRAME* kicadMgr = static_cast<KICAD_MANAGER_FRAME*>( kicadMgr_window ) )
1348 {
1349 ACTION_MANAGER* actionMgr = kicadMgr->GetToolManager()->GetActionManager();
1350
1351 for( const auto& [name, action] : actionMgr->GetActions() )
1352 hotkeysPanel->ActionsList().push_back( action );
1353 }
1354
1355 book->AddLazyPage(
1356 []( wxWindow* aParent ) -> wxWindow*
1357 {
1358 return new PANEL_COMMON_SETTINGS( aParent );
1359 },
1360 _( "Common" ) );
1361
1362 book->AddLazyPage(
1363 []( wxWindow* aParent ) -> wxWindow*
1364 {
1365 return new PANEL_MOUSE_SETTINGS( aParent );
1366 }, _( "Mouse and Touchpad" ) );
1367
1368 book->AddLazyPage(
1369 [] ( wxWindow* aParent ) -> wxWindow*
1370 {
1371 return new PANEL_SPACEMOUSE( aParent );
1372 }, _( "SpaceMouse" ) );
1373
1374 book->AddPage( hotkeysPanel, _( "Hotkeys" ) );
1375
1376 book->AddLazyPage(
1377 []( wxWindow* aParent ) -> wxWindow*
1378 {
1379 return new PANEL_GIT_REPOS( aParent );
1380 }, _( "Version Control" ) );
1381
1382#ifdef KICAD_USE_SENTRY
1383 book->AddLazyPage(
1384 []( wxWindow* aParent ) -> wxWindow*
1385 {
1386 return new PANEL_DATA_COLLECTION( aParent );
1387 }, _( "Data Collection" ) );
1388#endif
1389
1390#define LAZY_CTOR( key ) \
1391 [this, kiface]( wxWindow* aParent ) \
1392 { \
1393 return kiface->CreateKiWindow( aParent, key, &Kiway() ); \
1394 }
1395
1396 // If a dll is not loaded, the loader will show an error message.
1397
1398 try
1399 {
1400 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_SCH ) )
1401 {
1402 kiface->GetActions( hotkeysPanel->ActionsList() );
1403
1405 expand.push_back( (int) book->GetPageCount() );
1406
1407 book->AddPage( new wxPanel( book ), _( "Symbol Editor" ) );
1408 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_DISP_OPTIONS ), _( "Display Options" ) );
1409 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_GRIDS ), _( "Grids" ) );
1410 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_OPTIONS ), _( "Editing Options" ) );
1411 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_COLORS ), _( "Colors" ) );
1412 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_TOOLBARS ), _( "Toolbars" ) );
1413
1414 if( GetFrameType() == FRAME_SCH )
1415 expand.push_back( (int) book->GetPageCount() );
1416
1417 book->AddPage( new wxPanel( book ), _( "Schematic Editor" ) );
1418 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_DISP_OPTIONS ), _( "Display Options" ) );
1419 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_GRIDS ), _( "Grids" ) );
1420 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_EDIT_OPTIONS ), _( "Editing Options" ) );
1421 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_COLORS ), _( "Colors" ) );
1422 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_TOOLBARS ), _( "Toolbars" ) );
1423 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_FIELD_NAME_TEMPLATES ), _( "Field Name Templates" ) );
1424 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_DATA_SOURCES ), _( "Data Sources" ) );
1425 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_SIMULATOR ), _( "Simulator" ) );
1426 }
1427 }
1428 catch( ... )
1429 {
1430 }
1431
1432 try
1433 {
1434 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PCB ) )
1435 {
1436 kiface->GetActions( hotkeysPanel->ActionsList() );
1437
1439 expand.push_back( (int) book->GetPageCount() );
1440
1441 book->AddPage( new wxPanel( book ), _( "Footprint Editor" ) );
1442 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DISPLAY_OPTIONS ), _( "Display Options" ) );
1443 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_GRIDS ), _( "Grids" ) );
1444 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_ORIGINS_AXES ), _( "Origins & Axes" ) );
1445 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_EDIT_OPTIONS ), _( "Editing Options" ) );
1446 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_COLORS ), _( "Colors" ) );
1447 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_TOOLBARS ), _( "Toolbars" ) );
1448 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DEFAULT_FIELDS ), _( "Footprint Defaults" ) );
1449 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DEFAULT_GRAPHICS_VALUES ), _( "Graphics Defaults" ) );
1450 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_USER_LAYER_NAMES ), _( "User Layer Names" ) );
1451
1453 expand.push_back( (int) book->GetPageCount() );
1454
1455 book->AddPage( new wxPanel( book ), _( "PCB Editor" ) );
1456 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_DISPLAY_OPTS ), _( "Display Options" ) );
1457 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_GRIDS ), _( "Grids" ) );
1458 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ORIGINS_AXES ), _( "Origins & Axes" ) );
1459 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_EDIT_OPTIONS ), _( "Editing Options" ) );
1460 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_COLORS ), _( "Colors" ) );
1461 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_TOOLBARS ), _( "Toolbars" ) );
1462 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ACTION_PLUGINS ), _( "Plugins" ) );
1463
1465 expand.push_back( (int) book->GetPageCount() );
1466
1467 book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
1468 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_DISPLAY_OPTIONS ), _( "General" ) );
1469 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_TOOLBARS ), _( "Toolbars" ) );
1470 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_OPENGL ), _( "Realtime Renderer" ) );
1471 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_RAYTRACING ), _( "Raytracing Renderer" ) );
1472 }
1473 }
1474 catch( ... )
1475 {
1476 }
1477
1478 try
1479 {
1480 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_GERBVIEW ) )
1481 {
1482 kiface->GetActions( hotkeysPanel->ActionsList() );
1483
1484 if( GetFrameType() == FRAME_GERBER )
1485 expand.push_back( (int) book->GetPageCount() );
1486
1487 book->AddPage( new wxPanel( book ), _( "Gerber Viewer" ) );
1488 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
1489 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_COLORS ), _( "Colors" ) );
1490 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_TOOLBARS ), _( "Toolbars" ) );
1491 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_GRIDS ), _( "Grids" ) );
1492 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
1493 }
1494 }
1495 catch( ... )
1496 {
1497 }
1498
1499 try
1500 {
1501 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PL_EDITOR ) )
1502 {
1503 kiface->GetActions( hotkeysPanel->ActionsList() );
1504
1505 if( GetFrameType() == FRAME_PL_EDITOR )
1506 expand.push_back( (int) book->GetPageCount() );
1507
1508 book->AddPage( new wxPanel( book ), _( "Drawing Sheet Editor" ) );
1509 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_DISPLAY_OPTIONS ), _( "Display Options" ) );
1510 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_GRIDS ), _( "Grids" ) );
1511 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_COLORS ), _( "Colors" ) );
1512 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_TOOLBARS ), _( "Toolbars" ) );
1513
1514 book->AddLazyPage(
1515 []( wxWindow* aParent ) -> wxWindow*
1516 {
1517 return new PANEL_PACKAGES_AND_UPDATES( aParent );
1518 }, _( "Packages and Updates" ) );
1519 }
1520 }
1521 catch( ... )
1522 {
1523 }
1524
1525#ifdef KICAD_IPC_API
1526 book->AddPage( new PANEL_PLUGIN_SETTINGS( book ), _( "Plugins" ) );
1527#endif
1528
1529 book->AddPage( new PANEL_MAINTENANCE( book, this ), _( "Maintenance" ) );
1530
1531 // Update all of the action hotkeys. The process of loading the actions through
1532 // the KiFACE will only get us the default hotkeys
1533 ReadHotKeyConfigIntoActions( wxEmptyString, hotkeysPanel->ActionsList() );
1534
1535 for( size_t i = 0; i < book->GetPageCount(); ++i )
1536 book->GetPage( i )->Layout();
1537
1538 for( int page : expand )
1539 book->ExpandNode( page );
1540
1541 if( !aStartPage.IsEmpty() )
1542 dlg.SetInitialPage( aStartPage, aStartParentPage );
1543
1544 dlg.SetEvtHandlerEnabled( true );
1545#undef LAZY_CTOR
1546 }
1547
1548 if( dlg.ShowModal() == wxID_OK )
1549 {
1550 // Update our grids that are cached in the tool
1551 m_toolManager->ResetTools( TOOL_BASE::REDRAW );
1554 }
1555
1556}
1557
1558
1559void EDA_BASE_FRAME::OnDropFiles( wxDropFilesEvent& aEvent )
1560{
1561 Raise();
1562
1563 wxString* files = aEvent.GetFiles();
1564
1565 for( int nb = 0; nb < aEvent.GetNumberOfFiles(); nb++ )
1566 {
1567 const wxFileName fn = wxFileName( files[nb] );
1568 wxString ext = fn.GetExt();
1569
1570 // Alias all gerber files as GerberFileExtension
1573
1574 if( m_acceptedExts.find( ext.ToStdString() ) != m_acceptedExts.end() )
1575 m_AcceptedFiles.emplace_back( fn );
1576 }
1577
1579 m_AcceptedFiles.clear();
1580}
1581
1582
1584{
1585 for( const wxFileName& file : m_AcceptedFiles )
1586 {
1587 wxString fn = file.GetFullPath();
1588 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( file.GetExt() ), &fn );
1589 }
1590}
1591
1592
1593bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName, bool aVerbose )
1594{
1595 wxString msg;
1596 wxFileName fn = aFileName;
1597
1598 // Check for absence of a file path with a file name. Unfortunately KiCad
1599 // uses paths relative to the current project path without the ./ part which
1600 // confuses wxFileName. Making the file name path absolute may be less than
1601 // elegant but it solves the problem.
1602 if( fn.GetPath().IsEmpty() && fn.HasName() )
1603 fn.MakeAbsolute();
1604
1605 wxCHECK_MSG( fn.IsOk(), false,
1606 wxT( "File name object is invalid. Bad programmer!" ) );
1607 wxCHECK_MSG( !fn.GetPath().IsEmpty(), false,
1608 wxT( "File name object path <" ) + fn.GetFullPath() +
1609 wxT( "> is not set. Bad programmer!" ) );
1610
1611 if( fn.IsDir() && !fn.IsDirWritable() )
1612 {
1613 msg.Printf( _( "Insufficient permissions to folder '%s'." ), fn.GetPath() );
1614 }
1615 else if( !fn.FileExists() && !fn.IsDirWritable() )
1616 {
1617 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fn.GetFullPath() );
1618 }
1619 else if( fn.FileExists() && !fn.IsFileWritable() )
1620 {
1621 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fn.GetFullPath() );
1622 }
1623
1624 if( !msg.IsEmpty() )
1625 {
1626 if( aVerbose )
1627 DisplayErrorMessage( this, msg );
1628
1629 return false;
1630 }
1631
1632 return true;
1633}
1634
1635
1637{
1638 // This function should be overridden in child classes
1639 return false;
1640}
1641
1642
1644{
1645 wxAcceleratorEntry entries[1];
1646 entries[0].Set( wxACCEL_CTRL, int( 'Q' ), wxID_EXIT );
1647 wxAcceleratorTable accel( 1, entries );
1648 SetAcceleratorTable( accel );
1649}
1650
1651
1657
1658
1660{
1661 m_undoList.PushCommand( aNewitem );
1662
1663 // Delete the extra items, if count max reached
1664 if( m_undoRedoCountMax > 0 )
1665 {
1666 int extraitems = GetUndoCommandCount() - m_undoRedoCountMax;
1667
1668 if( extraitems > 0 )
1669 ClearUndoORRedoList( UNDO_LIST, extraitems );
1670 }
1671}
1672
1673
1675{
1676 m_redoList.PushCommand( aNewitem );
1677
1678 // Delete the extra items, if count max reached
1679 if( m_undoRedoCountMax > 0 )
1680 {
1681 int extraitems = GetRedoCommandCount() - m_undoRedoCountMax;
1682
1683 if( extraitems > 0 )
1684 ClearUndoORRedoList( REDO_LIST, extraitems );
1685 }
1686}
1687
1688
1693
1694
1699
1700
1702{
1703 if( GetUndoCommandCount() > 0 )
1704 return m_undoList.m_CommandsList.back()->GetDescription();
1705
1706 return wxEmptyString;
1707}
1708
1709
1711{
1712 if( GetRedoCommandCount() > 0 )
1713 return m_redoList.m_CommandsList.back()->GetDescription();
1714
1715 return wxEmptyString;
1716}
1717
1718
1720{
1721 m_autoSaveRequired = true;
1722}
1723
1724
1726{
1727 SetUserUnits( aUnits );
1729
1730 wxCommandEvent e( EDA_EVT_UNITS_CHANGED );
1731 e.SetInt( static_cast<int>( aUnits ) );
1732 e.SetClientData( this );
1733 ProcessEventLocally( e );
1734}
1735
1736
1737void EDA_BASE_FRAME::OnMaximize( wxMaximizeEvent& aEvent )
1738{
1739 // When we maximize the window, we want to save the old information
1740 // so that we can add it to the settings on next window load.
1741 // Contrary to the documentation, this event seems to be generated
1742 // when the window is also being unmaximized on OSX, so we only
1743 // capture the size information when we maximize the window when on OSX.
1744#ifdef __WXOSX__
1745 if( !IsMaximized() )
1746#endif
1747 {
1749 m_normalFramePos = GetPosition();
1750 wxLogTrace( traceDisplayLocation,
1751 "Maximizing window - Saving position (%d, %d) with size (%d, %d)",
1754 }
1755
1756 // Skip event to actually maximize the window
1757 aEvent.Skip();
1758}
1759
1760
1762{
1763#ifdef __WXGTK__
1764 wxSize winSize = GetSize();
1765
1766 // GTK includes the window decorations in the normal GetSize call,
1767 // so we have to use a GTK-specific sizing call that returns the
1768 // non-decorated window size.
1770 {
1771 int width = 0;
1772 int height = 0;
1773 GTKDoGetSize( &width, &height );
1774
1775 winSize.Set( width, height );
1776 }
1777#else
1778 wxSize winSize = GetSize();
1779#endif
1780
1781 return winSize;
1782}
1783
1784
1786{
1787 // Update the icon theme when the system theme changes and update the toolbars
1789 ThemeChanged();
1790
1791 // This isn't handled by ThemeChanged()
1792 if( GetMenuBar() )
1793 {
1794 // For icons in menus, icon scaling & hotkeys
1796 GetMenuBar()->Refresh();
1797 }
1798}
1799
1800
1801void EDA_BASE_FRAME::onSystemColorChange( wxSysColourChangedEvent& aEvent )
1802{
1803 // Call the handler to update the colors used in the frame
1805
1806 // Skip the change event to ensure the rest of the window controls get it
1807 aEvent.Skip();
1808}
1809
1810
1811void EDA_BASE_FRAME::onIconize( wxIconizeEvent& aEvent )
1812{
1813 // Call the handler
1814 handleIconizeEvent( aEvent );
1815
1816 // Skip the event.
1817 aEvent.Skip();
1818}
1819
1820
1821#ifdef __WXMSW__
1822WXLRESULT EDA_BASE_FRAME::MSWWindowProc( WXUINT message, WXWPARAM wParam, WXLPARAM lParam )
1823{
1824 // This will help avoid the menu keeping focus when the alt key is released
1825 // You can still trigger accelerators as long as you hold down alt
1826 if( message == WM_SYSCOMMAND )
1827 {
1828 if( wParam == SC_KEYMENU && ( lParam >> 16 ) <= 0 )
1829 return 0;
1830 }
1831
1832 return wxFrame::MSWWindowProc( message, wParam, lParam );
1833}
1834#endif
1835
1836
1838{
1839 ACTION_MENU* langsMenu = new ACTION_MENU( false, aControlTool );
1840 langsMenu->SetTitle( _( "Set Language" ) );
1841 langsMenu->SetIcon( BITMAPS::language );
1842
1843 wxString tooltip;
1844
1845 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
1846 {
1847 wxString label;
1848
1849 if( LanguagesList[ii].m_DoNotTranslate )
1850 label = LanguagesList[ii].m_Lang_Label;
1851 else
1852 label = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
1853
1854 wxMenuItem* item =
1855 new wxMenuItem( langsMenu,
1856 LanguagesList[ii].m_KI_Lang_Identifier, // wxMenuItem wxID
1857 label, tooltip, wxITEM_CHECK );
1858
1859 langsMenu->Append( item );
1860 }
1861
1862 // This must be done after the items are added
1863 aMasterMenu->Add( langsMenu );
1864}
void ShowAboutDialog(EDA_BASE_FRAME *aParent)
int index
const char * name
std::function< void(ACTION_TOOLBAR *)> ACTION_TOOLBAR_CONTROL_FACTORY
Type for the function signature that is used to add custom controls to the toolbar.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
void ClearScaledBitmapCache()
Wipes out the scaled bitmap cache so that the icon theme can be changed.
Definition bitmap.cpp:184
BITMAP_STORE * GetBitmapStore()
Definition bitmap.cpp:92
static TOOL_ACTION paste
Definition actions.h:80
static TOOL_ACTION about
Definition actions.h:287
static TOOL_ACTION reportBug
Definition actions.h:291
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION donate
Definition actions.h:289
static TOOL_ACTION listHotKeys
Definition actions.h:288
static TOOL_ACTION getInvolved
Definition actions.h:290
static TOOL_ACTION undo
Definition actions.h:75
static TOOL_ACTION redo
Definition actions.h:76
static TOOL_ACTION cut
Definition actions.h:77
static TOOL_ACTION gettingStarted
Definition actions.h:285
static TOOL_ACTION help
Definition actions.h:286
Manage TOOL_ACTION objects.
const std::map< std::string, TOOL_ACTION * > & GetActions() const
Get a list of currently-registered actions mapped by their name.
Define the structure of a menu based on ACTIONs.
Definition action_menu.h:47
void SetTitle(const wxString &aTitle) override
Set title for the menu.
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
Class to hold basic information about controls that can be added to the toolbars.
const std::string & GetName() const
Define the structure of a toolbar with buttons that invoke ACTIONs.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
WINDOW_SETTINGS m_Window
void ThemeChanged()
Notifies the store that the icon theme has been changed by the user, so caches must be invalidated.
Handle actions that are shared between different applications.
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition dialog_shim.h:68
int ShowModal() override
The base frame for deriving all KiCad main window classes.
virtual wxString help_name()
virtual bool doAutoSave()
This should be overridden by the derived class to handle the auto save feature.
void LoadWindowState(const wxString &aFileName)
FRAME_T GetFrameType() const
virtual void UnregisterUIUpdateHandler(int aID) override
Unregister a UI handler for a given ID that was registered using RegisterUIUpdateHandler.
virtual bool isAutoSaveRequired() const
Return the auto save status of the application.
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
virtual void handleIconizeEvent(wxIconizeEvent &aEvent)
Handle a window iconize event.
virtual void PushCommandToUndoList(PICKED_ITEMS_LIST *aItem)
Add a command to undo in the undo list.
void windowClosing(wxCloseEvent &event)
(with its unexpected name so it does not collide with the real OnWindowClose() function provided in d...
virtual void OnCharHook(wxKeyEvent &aKeyEvent)
Capture the key event before it is sent to the GUI.
virtual int GetRedoCommandCount() const
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
UNDO_REDO_CONTAINER m_undoList
virtual void OnMove(wxMoveEvent &aEvent)
virtual WINDOW_SETTINGS * GetWindowSettings(APP_SETTINGS_BASE *aCfg)
Return a pointer to the window settings for this frame.
virtual void doCloseWindow()
void OnToolbarSizeChanged()
Update toolbars if desired toolbar icon changed.
void OnMenuEvent(wxMenuEvent &event)
The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu events aren't ...
virtual bool IsModal() const
Return true if the frame is shown in our modal mode and false if the frame is shown as an usual frame...
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
virtual void HandleSystemColorChange()
Update the UI in response to a change in the system colors.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
void ensureWindowIsOnScreen()
bool m_isNonUserClose
Set by NonUserClose() to indicate that the user did not request the current close.
void LoadWindowSettings(const WINDOW_SETTINGS *aCfg)
Load window settings from the given settings object.
std::vector< wxFileName > m_AcceptedFiles
bool m_autoSavePermissionError
void OnKicadAbout(wxCommandEvent &event)
virtual void UpdateToolbarControlSizes()
Update the sizes of any controls in the toolbars of the frame.
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
virtual void DoWithAcceptedFiles()
Execute action on accepted dropped file.
virtual void OnModify()
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
wxWindow * findQuasiModalDialog()
static void HandleUpdateUIEvent(wxUpdateUIEvent &aEvent, EDA_BASE_FRAME *aFrame, ACTION_CONDITIONS aCond)
Handle events generated when the UI is trying to figure out the current state of the UI controls rela...
wxString m_perspective
virtual void ClearUndoORRedoList(UNDO_REDO_LIST aList, int aItemCount=-1)
Remove the aItemCount of old commands from aList and delete commands, pickers and picked items if nee...
virtual void ThemeChanged()
Process light/dark theme change.
EDA_BASE_FRAME(wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, KIWAY *aKiway, const EDA_IU_SCALE &aIuScale)
static constexpr int KICAD_AUI_TB_STYLE
Default style flags used for wxAUI toolbars.
ACTION_TOOLBAR * m_tbRight
void ShowPreferences(wxString aStartPage, wxString aStartParentPage)
Display the preferences and settings of all opened editors paged dialog, starting with a particular p...
void initExitKey()
Set the common key-pair for exiting the application (Ctrl-Q) and ties it to the wxID_EXIT event id.
void OnPreferences(wxCommandEvent &event)
virtual const SEARCH_STACK & sys_search()
Return a SEARCH_STACK pertaining to entire program.
WX_INFOBAR * m_infoBar
void onAutoSaveTimer(wxTimerEvent &aEvent)
Handle the auto save timer event.
void SaveWindowSettings(WINDOW_SETTINGS *aCfg)
Save window settings to the given settings object.
virtual wxString GetRedoActionDescription() const
TOOLBAR_SETTINGS * m_toolbarSettings
virtual wxString GetCurrentFileName() const
Get the full filename + path of the currently opened file in the frame.
void ChangeUserUnits(EDA_UNITS aUnits)
void AddMenuLanguageList(ACTION_MENU *aMasterMenu, TOOL_INTERACTIVE *aControlTool)
Create a menu list for language choice, and add it as submenu to MasterMenu.
void RegisterCustomToolbarControlFactory(const ACTION_TOOLBAR_CONTROL &aControlDesc, const ACTION_TOOLBAR_CONTROL_FACTORY &aControlFactory)
Register a creation factory for toolbar controls that are present in this frame.
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
virtual void configureToolbars()
wxTimer * m_autoSaveTimer
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
wxAuiManager m_auimgr
void PrintMsg(const wxString &text)
void commonInit(FRAME_T aFrameType)
Collect common initialization functions used in all CTORs.
virtual bool IsContentModified() const
Get if the contents of the frame have been modified since the last save.
void ShowInfoBarWarning(const wxString &aWarningMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and a warning icon on the left ...
virtual PICKED_ITEMS_LIST * PopCommandFromRedoList()
Return the last command to undo and remove it from list, nothing is deleted.
virtual void RecreateToolbars()
std::map< int, UIUpdateHandler > m_uiUpdateMap
Map containing the UI update handlers registered with wx for each action.
std::map< std::string, ACTION_TOOLBAR_CONTROL_FACTORY > m_toolbarControlFactories
ACTION_TOOLBAR_CONTROL_FACTORY * GetCustomToolbarControlFactory(const std::string &aName)
UNDO_REDO_CONTAINER m_redoList
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
FILE_HISTORY * m_fileHistory
ACTION_TOOLBAR * m_tbLeft
SETTINGS_MANAGER * m_settingsManager
virtual void OnSize(wxSizeEvent &aEvent)
virtual wxString GetUndoActionDescription() const
virtual PICKED_ITEMS_LIST * PopCommandFromUndoList()
Return the last command to undo and remove it from list, nothing is deleted.
wxString GetRunMenuCommandDescription(const TOOL_ACTION &aAction)
virtual bool canCloseWindow(wxCloseEvent &aCloseEvent)
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Check if aFileName can be written.
wxPoint m_normalFramePos
void OnMaximize(wxMaximizeEvent &aEvent)
virtual void ClearFileHistory()
Remove all files from the file history.
ACTION_TOOLBAR * m_tbTopAux
virtual void OnDropFiles(wxDropFilesEvent &aEvent)
Handle event fired when a file is dropped to the window.
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associate file extensions with action to execute.
void onIconize(wxIconizeEvent &aEvent)
virtual void unitsChangeRefresh()
Called when when the units setting has changed to allow for any derived classes to handle refreshing ...
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
wxSize GetWindowSize()
Get the undecorated window size that can be used for restoring the window size.
int GetAutoSaveInterval() const
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
void onSystemColorChange(wxSysColourChangedEvent &aEvent)
virtual int GetUndoCommandCount() const
virtual void RegisterUIUpdateHandler(int aID, const ACTION_CONDITIONS &aConditions) override
Register a UI update handler for the control with ID aID.
ACTION_TOOLBAR * m_tbTopMain
virtual void PushCommandToRedoList(PICKED_ITEMS_LIST *aItem)
Add a command to redo in the redo list.
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
bool m_isClosing
Set by the close window event handler after frames are asked if they can close.
void AddStandardHelpMenu(wxMenuBar *aMenuBar)
Add the standard KiCad help menu to the menubar.
nlohmann::json m_auiLayoutState
void ReCreateMenuBar()
Recreate the menu bar.
virtual void doReCreateMenuBar()
WX_INFOBAR * GetInfoBar()
Specialization of the wxAuiPaneInfo class for KiCad panels.
This class implements a file history object to store a list of files, that can then be added to a men...
void AddFileToHistory(const wxString &aFile) override
Adds a file to the history.
The main KiCad project manager frame.
SEARCH_STACK & KifaceSearch()
Only for DSO specific 'non-library' files.
APP_SETTINGS_BASE * KifaceSettings() const
Definition kiface_base.h:95
const wxString & GetHelpFileName() const
Return just the basename portion of the current help file.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY_HOLDER(KIWAY *aKiway, HOLDER_TYPE aType)
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:294
@ FACE_SCH
eeschema DSO
Definition kiway.h:301
@ FACE_PL_EDITOR
Definition kiway.h:305
@ FACE_PCB
pcbnew DSO
Definition kiway.h:302
@ FACE_GERBVIEW
Definition kiway.h:304
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:406
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:600
bool Init(const wxString &aProjectPath)
Initialize the local history repository for the given project path.
bool RunRegisteredSaversAndCommit(const wxString &aProjectPath, const wxString &aTitle)
Run all registered savers and, if any staged changes differ from HEAD, create a commit.
WX_TREEBOOK * GetTreebook()
void SetInitialPage(const wxString &aPage, const wxString &aParentPage=wxEmptyString)
std::vector< TOOL_ACTION * > & ActionsList()
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:137
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:535
virtual int GetSelectedLanguageIdentifier() const
Definition pgm_base.h:238
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:132
A holder to handle information on schematic or board items.
void SaveFileState(const wxString &aFileName, const WINDOW_SETTINGS *aWindowCfg, bool aOpen)
const PROJECT_FILE_STATE * GetFileState(const wxString &aFileName)
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:209
Look for files in a number of paths.
virtual wxWindow * GetToolCanvas() const =0
Canvas access.
virtual void CommonSettingsChanged(int aFlags=0)
Notification event that some of the common (suite-wide) settings have changed.
TOOL_MANAGER * m_toolManager
virtual void ShowChangedLanguage()
TOOL_DISPATCHER * m_toolDispatcher
virtual SELECTION & GetCurrentSelection()
Get the current selection from the canvas area.
Represent a single user action.
wxString GetMenuLabel() const
Return the translated label for the action.
wxString GetFriendlyName() const
Return the translated user-friendly name of the action.
@ REDRAW
Full drawing refresh.
Definition tool_base.h:83
UNITS_PROVIDER(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits)
void SetUserUnits(EDA_UNITS aUnits)
bool Deserialize(const nlohmann::json &aState) const
nlohmann::json Serialize() const
Simple wrapper around wxBusyCursor for used with the generic BUSY_INDICATOR interface.
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:76
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
MESSAGE_TYPE
Sets the type of message for special handling if needed.
Definition wx_infobar.h:94
bool AddLazyPage(std::function< wxWindow *(wxWindow *aParent)> aLazyCtor, const wxString &text, bool bSelect=false, int imageId=NO_IMAGE)
bool AddLazySubPage(std::function< wxWindow *(wxWindow *aParent)> aLazyCtor, const wxString &text, bool bSelect=false, int imageId=NO_IMAGE)
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
This file is part of the common library.
#define KICAD_MESSAGE_DIALOG
Definition confirm.h:52
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
static const wxSize minSizeLookup(FRAME_T aFrameType, wxWindow *aWindow)
#define LAZY_CTOR(key)
static const wxSize defaultSize(FRAME_T aFrameType, wxWindow *aWindow)
wxWindow * findQuasiModalDialog(wxWindow *aParent)
Base window classes and related definitions.
#define KICAD_MANAGER_FRAME_NAME
#define DEFAULT_MAX_UNDO_ITEMS
std::function< void(wxUpdateUIEvent &) > UIUpdateHandler
This is the handler functor for the update UI events.
void SocketCleanup()
Must be called to clean up the socket thread used by SendCommand.
Definition eda_dde.cpp:319
DDE server & client.
EDA_UNITS
Definition eda_units.h:48
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:33
@ PANEL_PCB_GRIDS
Definition frame_type.h:98
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ PANEL_SYM_EDIT_GRIDS
Definition frame_type.h:73
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:35
@ PANEL_3DV_TOOLBARS
Definition frame_type.h:108
@ PANEL_SCH_FIELD_NAME_TEMPLATES
Definition frame_type.h:83
@ PANEL_DS_TOOLBARS
Definition frame_type.h:120
@ PANEL_SCH_TOOLBARS
Definition frame_type.h:82
@ PANEL_GBR_DISPLAY_OPTIONS
Definition frame_type.h:110
@ PANEL_3DV_OPENGL
Definition frame_type.h:106
@ PANEL_FP_DEFAULT_GRAPHICS_VALUES
Definition frame_type.h:93
@ PANEL_PCB_TOOLBARS
Definition frame_type.h:101
@ PANEL_PCB_ORIGINS_AXES
Definition frame_type.h:103
@ PANEL_PCB_EDIT_OPTIONS
Definition frame_type.h:99
@ PANEL_SCH_DISP_OPTIONS
Definition frame_type.h:78
@ PANEL_FP_DISPLAY_OPTIONS
Definition frame_type.h:87
@ PANEL_SCH_SIMULATOR
Definition frame_type.h:84
@ FRAME_SCH
Definition frame_type.h:34
@ PANEL_DS_COLORS
Definition frame_type.h:119
@ PANEL_PCB_COLORS
Definition frame_type.h:100
@ PANEL_SYM_TOOLBARS
Definition frame_type.h:76
@ PANEL_3DV_RAYTRACING
Definition frame_type.h:107
@ PANEL_SYM_EDIT_OPTIONS
Definition frame_type.h:74
@ PANEL_FP_GRIDS
Definition frame_type.h:88
@ PANEL_SCH_EDIT_OPTIONS
Definition frame_type.h:80
@ PANEL_FP_ORIGINS_AXES
Definition frame_type.h:95
@ PANEL_SYM_DISP_OPTIONS
Definition frame_type.h:72
@ PANEL_PCB_DISPLAY_OPTS
Definition frame_type.h:97
@ PANEL_FP_COLORS
Definition frame_type.h:90
@ PANEL_FP_DEFAULT_FIELDS
Definition frame_type.h:92
@ PANEL_SYM_COLORS
Definition frame_type.h:75
@ FRAME_PL_EDITOR
Definition frame_type.h:59
@ PANEL_GBR_GRIDS
Definition frame_type.h:113
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
@ FRAME_GERBER
Definition frame_type.h:57
@ PANEL_DS_GRIDS
Definition frame_type.h:118
@ FRAME_PCB_DISPLAY3D
Definition frame_type.h:47
@ PANEL_GBR_TOOLBARS
Definition frame_type.h:115
@ PANEL_FP_EDIT_OPTIONS
Definition frame_type.h:89
@ PANEL_SCH_GRIDS
Definition frame_type.h:79
@ PANEL_FP_TOOLBARS
Definition frame_type.h:91
@ PANEL_PCB_ACTION_PLUGINS
Definition frame_type.h:102
@ PANEL_3DV_DISPLAY_OPTIONS
Definition frame_type.h:105
@ PANEL_DS_DISPLAY_OPTIONS
Definition frame_type.h:117
@ PANEL_SCH_COLORS
Definition frame_type.h:81
@ PANEL_GBR_COLORS
Definition frame_type.h:114
@ PANEL_GBR_EXCELLON_OPTIONS
Definition frame_type.h:112
@ KICAD_MAIN_FRAME_T
Definition frame_type.h:68
static const std::string GerberFileExtension
static bool IsGerberFileExtension(const wxString &ext)
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
const wxChar *const kicadTraceKeyEvent
Flag to enable wxKeyEvent debug tracing.
const wxChar *const traceDisplayLocation
Flag to enable debug output of display positioning logic.
void ReadHotKeyConfigIntoActions(const wxString &aFileName, std::vector< TOOL_ACTION * > &aActions)
Read a hotkey config file into a list of actions.
@ ID_FILE_LIST_CLEAR
Definition id.h:62
@ ID_FILE1
Definition id.h:59
@ ID_AUTO_SAVE_TIMER
Definition id.h:54
void RemoveShutdownBlockReason(wxWindow *aWindow)
Removes any shutdown block reason set.
Definition unix/app.cpp:85
PGM_BASE & Pgm()
The global program "get" accessor.
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition pgm_base.cpp:95
see class PGM_BASE
std::vector< FAB_LAYER_COLOR > dummy
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
SELECTION_CONDITION enableCondition
Returns true if the UI control should be enabled.
SELECTION_CONDITION checkCondition
Returns true if the UI control should be checked.
SELECTION_CONDITION showCondition
Returns true if the UI control should be shown.
ACTION_CONDITIONS & Check(const SELECTION_CONDITION &aCondition)
Implement a participant in the KIWAY alchemy.
Definition kiway.h:155
struct WINDOW_STATE window
Store the common settings that are saved and loaded for each window / frame.
WINDOW_STATE state
wxString mru_path
nlohmann::json aui_state
wxString perspective
Store the window positioning/state.
unsigned int display
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
@ RIGHT
Toolbar on the right side of the canvas.
@ LEFT
Toolbar on the left side of the canvas.
@ TOP_AUX
Toolbar on the top of the canvas.
@ TOP_MAIN
Toolbar on the top of the canvas.
#define HOTKEYS_CHANGED
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
wxLogTrace helper definitions.