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 <confirm.h>
50#include <pgm_base.h>
55#include <tool/action_manager.h>
56#include <tool/action_menu.h>
57#include <tool/action_toolbar.h>
58#include <tool/actions.h>
59#include <tool/common_control.h>
60#include <tool/tool_manager.h>
63#include <trace_helpers.h>
66#include <widgets/wx_infobar.h>
69#include <widgets/wx_grid.h>
70#include <widgets/wx_treebook.h>
71#include <wx/app.h>
72#include <wx/config.h>
73#include <wx/display.h>
74#include <wx/stdpaths.h>
75#include <wx/string.h>
76#include <wx/msgdlg.h>
77#include <wx/wupdlock.h>
78#include <kiplatform/app.h>
79#include <kiplatform/io.h>
80#include <kiplatform/ui.h>
81
82#include <nlohmann/json.hpp>
83
84#include <functional>
85#include <kiface_ids.h>
86
87#ifdef KICAD_IPC_API
88#include <api/api_server.h>
89#endif
90
91
92// Minimum window size
93static const wxSize minSizeLookup( FRAME_T aFrameType, wxWindow* aWindow )
94{
95 switch( aFrameType )
96 {
98 return wxWindow::FromDIP( wxSize( 406, 354 ), aWindow );
99
100 default:
101 return wxWindow::FromDIP( wxSize( 500, 400 ), aWindow );
102 }
103}
104
105
106static const wxSize defaultSize( FRAME_T aFrameType, wxWindow* aWindow )
107{
108 switch( aFrameType )
109 {
111 return wxWindow::FromDIP( wxSize( 850, 540 ), aWindow );
112
113 default:
114 return wxWindow::FromDIP( wxSize( 1280, 720 ), aWindow );
115 }
116}
117
118
119BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
120 // These event table entries are needed to handle events from the mac application menu
121 EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::OnKicadAbout )
122 EVT_MENU( wxID_PREFERENCES, EDA_BASE_FRAME::OnPreferences )
123
124 EVT_CHAR_HOOK( EDA_BASE_FRAME::OnCharHook )
125 EVT_MENU_OPEN( EDA_BASE_FRAME::OnMenuEvent )
126 EVT_MENU_CLOSE( EDA_BASE_FRAME::OnMenuEvent )
127 EVT_MENU_HIGHLIGHT_ALL( EDA_BASE_FRAME::OnMenuEvent )
128 EVT_MOVE( EDA_BASE_FRAME::OnMove )
129 EVT_SIZE( EDA_BASE_FRAME::OnSize )
130 EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize )
131
132 EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange )
133 EVT_ICONIZE( EDA_BASE_FRAME::onIconize )
134END_EVENT_TABLE()
135
136
138{
139 m_ident = aFrameType;
140 m_maximizeByDefault = false;
141 m_infoBar = nullptr;
142 m_settingsManager = nullptr;
143 m_fileHistory = nullptr;
144 m_supportsAutoSave = false;
145 m_autoSavePending = false;
147 m_isClosing = false;
148 m_isNonUserClose = false;
149 m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
150 m_autoSaveRequired = false;
153 m_frameSize = defaultSize( aFrameType, this );
154 m_displayIndex = -1;
155
156 m_auimgr.SetArtProvider( new WX_AUI_DOCK_ART() );
157
159
160 // Set a reasonable minimal size for the frame
161 wxSize minSize = minSizeLookup( aFrameType, this );
162 SetSizeHints( minSize.x, minSize.y, -1, -1, -1, -1 );
163
164 // Store dimensions of the user area of the main window.
165 GetClientSize( &m_frameSize.x, &m_frameSize.y );
166
167 Connect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
168 wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
169
170 // hook wxEVT_CLOSE_WINDOW so we can call SaveSettings(). This function seems
171 // to be called before any other hook for wxCloseEvent, which is necessary.
172 Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
173
174 initExitKey();
175}
176
177
178EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle,
179 const wxPoint& aPos, const wxSize& aSize, long aStyle,
180 const wxString& aFrameName, KIWAY* aKiway,
181 const EDA_IU_SCALE& aIuScale ) :
182 wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ),
183 TOOLS_HOLDER(),
184 KIWAY_HOLDER( aKiway, KIWAY_HOLDER::FRAME ),
185 UNITS_PROVIDER( aIuScale, EDA_UNITS::MM )
186{
187 m_tbTopMain = nullptr;
188 m_tbTopAux = nullptr;
189 m_tbRight = nullptr;
190 m_tbLeft = nullptr;
191
192 commonInit( aFrameType );
193}
194
195
196wxWindow* findQuasiModalDialog( wxWindow* aParent )
197{
198 for( wxWindow* child : aParent->GetChildren() )
199 {
200 if( DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( child ) )
201 {
202 if( dlg->IsQuasiModal() )
203 return dlg;
204
205 if( wxWindow* nestedDlg = findQuasiModalDialog( child ) )
206 return nestedDlg;
207 }
208 }
209
210 return nullptr;
211}
212
213
215{
216 if( wxWindow* dlg = ::findQuasiModalDialog( this ) )
217 return dlg;
218
219 // FIXME: CvPcb is currently implemented on top of KIWAY_PLAYER rather than DIALOG_SHIM,
220 // so we have to look for it separately.
221 if( m_ident == FRAME_SCH )
222 {
223 wxWindow* cvpcb = wxWindow::FindWindowByName( wxS( "CvpcbFrame" ) );
224
225 if( cvpcb )
226 return cvpcb;
227 }
228
229 return nullptr;
230}
231
232
233void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
234{
235 // Don't allow closing when a quasi-modal is open.
236 wxWindow* quasiModal = findQuasiModalDialog();
237
238 if( quasiModal )
239 {
240 // Raise and notify; don't give the user a warning regarding "quasi-modal dialogs"
241 // when they have no idea what those are.
242 quasiModal->Raise();
243 wxBell();
244
245 if( event.CanVeto() )
246 event.Veto();
247
248 return;
249 }
250
251
252 if( event.GetId() == wxEVT_QUERY_END_SESSION
253 || event.GetId() == wxEVT_END_SESSION )
254 {
255 // End session means the OS is going to terminate us
256 m_isNonUserClose = true;
257 }
258
259 if( canCloseWindow( event ) )
260 {
261 m_isClosing = true;
262
263 if( m_infoBar )
264 m_infoBar->Dismiss();
265
266 APP_SETTINGS_BASE* cfg = config();
267
268 if( cfg )
269 SaveSettings( cfg ); // virtual, wxFrame specific
270
272
273 // Destroy (safe delete frame) this frame only in non modal mode.
274 // In modal mode, the caller will call Destroy().
275 if( !IsModal() )
276 Destroy();
277 }
278 else
279 {
280 if( event.CanVeto() )
281 event.Veto();
282 }
283}
284
285
287{
288 Disconnect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
289 wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
290 Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
291
292 delete m_autoSaveTimer;
293 delete m_fileHistory;
294
296
298
300}
301
302
303bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent )
304{
305#ifdef __WXMAC__
306 // Apple in its infinite wisdom will raise a disabled window before even passing
307 // us the event, so we have no way to stop it. Instead, we have to catch an
308 // improperly ordered disabled window and quasi-modal dialog here and reorder
309 // them.
310 if( !IsEnabled() && IsActive() )
311 {
312 wxWindow* dlg = findQuasiModalDialog();
313
314 if( dlg )
315 dlg->Raise();
316 }
317#endif
318
319 if( !wxFrame::ProcessEvent( aEvent ) )
320 return false;
321
322 if( Pgm().m_Quitting )
323 return true;
324
325 if( !m_isClosing && m_supportsAutoSave && IsShownOnScreen() && IsActive()
327 && GetAutoSaveInterval() > 0 )
328 {
329 if( !m_autoSavePending )
330 {
331 wxLogTrace( traceAutoSave, wxT( "Starting auto save timer." ) );
332 m_autoSaveTimer->Start( GetAutoSaveInterval() * 1000, wxTIMER_ONE_SHOT );
333 m_autoSavePending = true;
334 }
335 else if( m_autoSaveTimer->IsRunning() )
336 {
337 wxLogTrace( traceAutoSave, wxT( "Stopping auto save timer." ) );
338 m_autoSaveTimer->Stop();
339 m_autoSavePending = false;
340 }
341 }
342
343 return true;
344}
345
346
351
352
353void EDA_BASE_FRAME::onAutoSaveTimer( wxTimerEvent& aEvent )
354{
355 // Don't stomp on someone else's timer event.
356 if( aEvent.GetId() != ID_AUTO_SAVE_TIMER )
357 {
358 aEvent.Skip();
359 return;
360 }
361
362 if( !doAutoSave() )
363 m_autoSaveTimer->Start( GetAutoSaveInterval() * 1000, wxTIMER_ONE_SHOT );
364}
365
366
368{
369 wxCHECK_MSG( false, true, wxT( "Auto save timer function not overridden. Bad programmer!" ) );
370}
371
372
373void EDA_BASE_FRAME::OnCharHook( wxKeyEvent& aKeyEvent )
374{
375 wxLogTrace( kicadTraceKeyEvent, wxS( "EDA_BASE_FRAME::OnCharHook %s" ), dump( aKeyEvent ) );
376
377 // Key events can be filtered here.
378 // Currently no filtering is made.
379 aKeyEvent.Skip();
380}
381
382
383void EDA_BASE_FRAME::OnMenuEvent( wxMenuEvent& aEvent )
384{
385 if( !m_toolDispatcher )
386 aEvent.Skip();
387 else
388 m_toolDispatcher->DispatchWxEvent( aEvent );
389}
390
391
393{
395 std::placeholders::_1,
396 this,
397 aConditions );
398
399 m_uiUpdateMap[aID] = evtFunc;
400
401 Bind( wxEVT_UPDATE_UI, evtFunc, aID );
402}
403
404
406{
407 const auto it = m_uiUpdateMap.find( aID );
408
409 if( it == m_uiUpdateMap.end() )
410 return;
411
412 Unbind( wxEVT_UPDATE_UI, it->second, aID );
413}
414
415
416void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
417 ACTION_CONDITIONS aCond )
418{
419 bool checkRes = false;
420 bool enableRes = true;
421 bool showRes = true;
422 bool isCut = aEvent.GetId() == ACTIONS::cut.GetUIId();
423 bool isCopy = aEvent.GetId() == ACTIONS::copy.GetUIId();
424 bool isPaste = aEvent.GetId() == ACTIONS::paste.GetUIId();
425 SELECTION& selection = aFrame->GetCurrentSelection();
426
427 try
428 {
429 checkRes = aCond.checkCondition( selection );
430 enableRes = aCond.enableCondition( selection );
431 showRes = aCond.showCondition( selection );
432 }
433 catch( std::exception& )
434 {
435 // Something broke with the conditions, just skip the event.
436 aEvent.Skip();
437 return;
438 }
439
440 if( showRes && aEvent.GetId() == ACTIONS::undo.GetUIId() )
441 {
442 wxString msg = _( "Undo" );
443
444 if( enableRes )
445 msg += wxS( " " ) + aFrame->GetUndoActionDescription();
446
447 aEvent.SetText( msg );
448 }
449 else if( showRes && aEvent.GetId() == ACTIONS::redo.GetUIId() )
450 {
451 wxString msg = _( "Redo" );
452
453 if( enableRes )
454 msg += wxS( " " ) + aFrame->GetRedoActionDescription();
455
456 aEvent.SetText( msg );
457 }
458
459 if( isCut || isCopy || isPaste )
460 {
461 wxWindow* focus = wxWindow::FindFocus();
462 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( focus );
463
464 if( textEntry && isCut && textEntry->CanCut() )
465 enableRes = true;
466 else if( textEntry && isCopy && textEntry->CanCopy() )
467 enableRes = true;
468 else if( textEntry && isPaste && textEntry->CanPaste() )
469 enableRes = true;
470 else if( dynamic_cast<WX_GRID*>( focus ) )
471 enableRes = false; // Must disable menu in order to get command as CharHook event
472 }
473
474 aEvent.Enable( enableRes );
475 aEvent.Show( showRes );
476
477 if( aEvent.IsCheckable() )
478 aEvent.Check( checkRes );
479}
480
481
483{
484 // Setup the conditions to check a language menu item
485 auto isCurrentLang =
486 [] ( const SELECTION& aSel, int aLangIdentifier )
487 {
488 return Pgm().GetSelectedLanguageIdentifier() == aLangIdentifier;
489 };
490
491 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
492 {
494 cond.Check( std::bind( isCurrentLang, std::placeholders::_1,
495 LanguagesList[ii].m_WX_Lang_Identifier ) );
496
497 RegisterUIUpdateHandler( LanguagesList[ii].m_KI_Lang_Identifier, cond );
498 }
499}
500
501
503 const ACTION_TOOLBAR_CONTROL_FACTORY& aControlFactory )
504{
505 m_toolbarControlFactories.emplace( aControlDesc.GetName(), aControlFactory );
506}
507
508
510{
511 for( auto& control : m_toolbarControlFactories )
512 {
513 if( control.first == aName )
514 return &control.second;
515 }
516
517 return nullptr;
518}
519
520
524
525
527{
528 wxWindowUpdateLocker dummy( this );
529
530 wxASSERT( m_toolbarSettings );
531
532 std::optional<TOOLBAR_CONFIGURATION> tbConfig;
533
534 // Drawing tools (typically on right edge of window)
535 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::RIGHT, config()->m_CustomToolbars );
536
537 if( tbConfig.has_value() )
538 {
539 if( !m_tbRight )
540 {
541 m_tbRight = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
542 KICAD_AUI_TB_STYLE | wxAUI_TB_VERTICAL );
543 m_tbRight->SetAuiManager( &m_auimgr );
544 }
545
546 m_tbRight->ApplyConfiguration( tbConfig.value() );
547 }
548
549 // Options (typically on left edge of window)
550 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::LEFT, config()->m_CustomToolbars );
551
552 if( tbConfig.has_value() )
553 {
554 if( !m_tbLeft )
555 {
556 m_tbLeft = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
557 KICAD_AUI_TB_STYLE | wxAUI_TB_VERTICAL );
558 m_tbLeft->SetAuiManager( &m_auimgr );
559 }
560
561 m_tbLeft->ApplyConfiguration( tbConfig.value() );
562 }
563
564 // Top main toolbar (the top one)
565 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::TOP_MAIN, config()->m_CustomToolbars );
566
567 if( tbConfig.has_value() )
568 {
569 if( !m_tbTopMain )
570 {
571 m_tbTopMain = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
572 KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_HORIZONTAL );
573 m_tbTopMain->SetAuiManager( &m_auimgr );
574 }
575
576 m_tbTopMain->ApplyConfiguration( tbConfig.value() );
577 }
578
579 // Top aux toolbar (the bottom one)
580 tbConfig = m_toolbarSettings->GetToolbarConfig( TOOLBAR_LOC::TOP_AUX, config()->m_CustomToolbars );
581
582 if( tbConfig.has_value() )
583 {
584 if( !m_tbTopAux )
585 {
586 m_tbTopAux = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
587 KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_HORIZONTAL );
588 m_tbTopAux->SetAuiManager( &m_auimgr );
589 }
590
591 m_tbTopAux->ApplyConfiguration( tbConfig.value() );
592 }
593}
594
595
597{
598 if( m_tbTopMain )
599 m_tbTopMain->UpdateControlWidths();
600
601 if( m_tbRight )
602 m_tbRight->UpdateControlWidths();
603
604 if( m_tbLeft )
605 m_tbLeft->UpdateControlWidths();
606
607 if( m_tbTopAux )
608 m_tbTopAux->UpdateControlWidths();
609
610}
611
612
614{
615 if( m_tbTopMain )
616 m_auimgr.GetPane( m_tbTopMain ).MaxSize( m_tbTopMain->GetSize() );
617
618 if( m_tbRight )
619 m_auimgr.GetPane( m_tbRight ).MaxSize( m_tbRight->GetSize() );
620
621 if( m_tbLeft )
622 m_auimgr.GetPane( m_tbLeft ).MaxSize( m_tbLeft->GetSize() );
623
624 if( m_tbTopAux )
625 m_auimgr.GetPane( m_tbTopAux ).MaxSize( m_tbTopAux->GetSize() );
626
627 m_auimgr.Update();
628}
629
630
632{
639
640 CallAfter( [this]()
641 {
642 if( !m_isClosing )
644 } );
645}
646
647
648void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
649{
650 COMMON_CONTROL* commonControl = m_toolManager->GetTool<COMMON_CONTROL>();
651 ACTION_MENU* helpMenu = new ACTION_MENU( false, commonControl );
652
653 helpMenu->Add( ACTIONS::help );
654 helpMenu->Add( ACTIONS::gettingStarted );
655 helpMenu->Add( ACTIONS::listHotKeys );
656 helpMenu->Add( ACTIONS::getInvolved );
657 helpMenu->Add( ACTIONS::donate );
658 helpMenu->Add( ACTIONS::reportBug );
659
660 helpMenu->AppendSeparator();
661 helpMenu->Add( ACTIONS::about );
662
663 aMenuBar->Append( helpMenu, _( "&Help" ) );
664}
665
666
667
669{
670 wxString menuItemLabel = aAction.GetMenuLabel();
671 wxMenuBar* menuBar = GetMenuBar();
672
673 for( size_t ii = 0; ii < menuBar->GetMenuCount(); ++ii )
674 {
675 for( wxMenuItem* menuItem : menuBar->GetMenu( ii )->GetMenuItems() )
676 {
677 if( menuItem->GetItemLabelText() == menuItemLabel )
678 {
679 wxString menuTitleLabel = menuBar->GetMenuLabelText( ii );
680
681 menuTitleLabel.Replace( wxS( "&" ), wxS( "&&" ) );
682 menuItemLabel.Replace( wxS( "&" ), wxS( "&&" ) );
683
684 return wxString::Format( _( "Run: %s > %s" ),
685 menuTitleLabel,
686 menuItemLabel );
687 }
688 }
689 }
690
691 return wxString::Format( _( "Run: %s" ), aAction.GetFriendlyName() );
692};
693
694
696{
698
699 if( GetMenuBar() )
700 {
702 GetMenuBar()->Refresh();
703 }
704}
705
706
708{
710
711 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
712
713#ifdef KICAD_IPC_API
714 bool running = Pgm().GetApiServer().Running();
715
716 if( running && !settings->m_Api.enable_server )
717 Pgm().GetApiServer().Stop();
718 else if( !running && settings->m_Api.enable_server )
719 Pgm().GetApiServer().Start();
720#endif
721
722 if( m_fileHistory )
723 {
724 int historySize = settings->m_System.file_history_size;
725 m_fileHistory->SetMaxFiles( (unsigned) std::max( 0, historySize ) );
726 }
727
729 ThemeChanged();
730
731 if( GetMenuBar() )
732 {
733 // For icons in menus, icon scaling & hotkeys
735 GetMenuBar()->Refresh();
736 }
737
738 // Update the toolbars
740}
741
742
744{
746
747 // Update all the toolbars to have new icons
748 wxAuiPaneInfoArray panes = m_auimgr.GetAllPanes();
749
750 for( size_t i = 0; i < panes.GetCount(); ++i )
751 {
752 if( ACTION_TOOLBAR* toolbar = dynamic_cast<ACTION_TOOLBAR*>( panes[i].window ) )
753 toolbar->RefreshBitmaps();
754 }
755}
756
757
758void EDA_BASE_FRAME::OnSize( wxSizeEvent& aEvent )
759{
760#ifdef __WXMAC__
761 int currentDisplay = wxDisplay::GetFromWindow( this );
762
763 if( m_displayIndex >= 0 && currentDisplay >= 0 && currentDisplay != m_displayIndex )
764 {
765 wxLogTrace( traceDisplayLocation, wxS( "OnSize: current display changed %d to %d" ),
766 m_displayIndex, currentDisplay );
767 m_displayIndex = currentDisplay;
769 }
770#endif
771
772 aEvent.Skip();
773}
774
775
776void EDA_BASE_FRAME::LoadWindowState( const wxString& aFileName )
777{
778 if( !Pgm().GetCommonSettings()->m_Session.remember_open_files )
779 return;
780
781 const PROJECT_FILE_STATE* state = Prj().GetLocalSettings().GetFileState( aFileName );
782
783 if( state != nullptr )
784 {
785 LoadWindowState( state->window );
786 }
787}
788
789
791{
792 bool wasDefault = false;
793
794 m_framePos.x = aState.pos_x;
795 m_framePos.y = aState.pos_y;
796 m_frameSize.x = aState.size_x;
797 m_frameSize.y = aState.size_y;
798
799 wxLogTrace( traceDisplayLocation, wxS( "Config position (%d, %d) with size (%d, %d)" ),
801
802 // Ensure minimum size is set if the stored config was zero-initialized
803 wxSize minSize = minSizeLookup( m_ident, this );
804
805 if( m_frameSize.x < minSize.x || m_frameSize.y < minSize.y )
806 {
808 wasDefault = true;
809
810 wxLogTrace( traceDisplayLocation, wxS( "Using minimum size (%d, %d)" ),
812 }
813
814 wxLogTrace( traceDisplayLocation, wxS( "Number of displays: %d" ), wxDisplay::GetCount() );
815
816 if( aState.display >= wxDisplay::GetCount() )
817 {
818 wxLogTrace( traceDisplayLocation, wxS( "Previous display not found" ) );
819
820 // If it isn't attached, use the first display
821 // Warning wxDisplay has 2 ctor variants. the parameter needs a type:
822 const unsigned int index = 0;
823 wxDisplay display( index );
824 wxRect clientSize = display.GetGeometry();
825
826 m_framePos = wxDefaultPosition;
827
828 // Ensure the window fits on the display, since the other one could have been larger
829 if( m_frameSize.x > clientSize.width )
830 m_frameSize.x = clientSize.width;
831
832 if( m_frameSize.y > clientSize.height )
833 m_frameSize.y = clientSize.height;
834 }
835 else
836 {
837 wxPoint upperRight( m_framePos.x + m_frameSize.x, m_framePos.y );
838 wxPoint upperLeft( m_framePos.x, m_framePos.y );
839
840 wxDisplay display( aState.display );
841 wxRect clientSize = display.GetClientArea();
842
843 int yLimTop = clientSize.y;
844 int yLimBottom = clientSize.y + clientSize.height;
845 int xLimLeft = clientSize.x;
846 int xLimRight = clientSize.x + clientSize.width;
847
848 if( upperLeft.x > xLimRight || // Upper left corner too close to right edge of screen
849 upperRight.x < xLimLeft || // Upper right corner too close to left edge of screen
850 upperLeft.y < yLimTop || // Upper corner too close to the bottom of the screen
851 upperLeft.y > yLimBottom )
852 {
853 m_framePos = wxDefaultPosition;
854 wxLogTrace( traceDisplayLocation, wxS( "Resetting to default position" ) );
855 }
856 }
857
858 wxLogTrace( traceDisplayLocation, wxS( "Final window position (%d, %d) with size (%d, %d)" ),
860
861 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
862
863 // Center the window if we reset to default
864 if( m_framePos.x == -1 )
865 {
866 wxLogTrace( traceDisplayLocation, wxS( "Centering window" ) );
867 Center();
868 m_framePos = GetPosition();
869 }
870
871 // Record the frame sizes in an un-maximized state
874
875 // Maximize if we were maximized before
876 if( aState.maximized || ( wasDefault && m_maximizeByDefault ) )
877 {
878 wxLogTrace( traceDisplayLocation, wxS( "Maximizing window" ) );
879 Maximize();
880 }
881
882 m_displayIndex = wxDisplay::GetFromWindow( this );
883}
884
885
887{
888 wxDisplay display( wxDisplay::GetFromWindow( this ) );
889 wxRect clientSize = display.GetClientArea();
890 wxPoint pos = GetPosition();
891 wxSize size = GetWindowSize();
892
893 wxLogTrace( traceDisplayLocation,
894 wxS( "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d" ),
895 clientSize.x, clientSize.y,
896 clientSize.width, clientSize.height );
897
898 if( pos.y < clientSize.y )
899 {
900 wxLogTrace( traceDisplayLocation,
901 wxS( "ensureWindowIsOnScreen: y pos %d below minimum, setting to %d" ), pos.y,
902 clientSize.y );
903 pos.y = clientSize.y;
904 }
905
906 if( pos.x < clientSize.x )
907 {
908 wxLogTrace( traceDisplayLocation,
909 wxS( "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d" ),
910 pos.x, clientSize.x );
911 pos.x = clientSize.x;
912 }
913
914 if( pos.x + size.x - clientSize.x > clientSize.width )
915 {
916 int newWidth = clientSize.width - ( pos.x - clientSize.x );
917 wxLogTrace( traceDisplayLocation,
918 wxS( "ensureWindowIsOnScreen: effective width %d above available %d, setting "
919 "to %d" ), pos.x + size.x, clientSize.width, newWidth );
920 size.x = newWidth;
921 }
922
923 if( pos.y + size.y - clientSize.y > clientSize.height )
924 {
925 int newHeight = clientSize.height - ( pos.y - clientSize.y );
926 wxLogTrace( traceDisplayLocation,
927 wxS( "ensureWindowIsOnScreen: effective height %d above available %d, setting "
928 "to %d" ), pos.y + size.y, clientSize.height, newHeight );
929 size.y = newHeight;
930 }
931
932 wxLogTrace( traceDisplayLocation, wxS( "Updating window position (%d, %d) with size (%d, %d)" ),
933 pos.x, pos.y, size.x, size.y );
934
935 SetSize( pos.x, pos.y, size.x, size.y );
936}
937
938
949
950
952{
953 if( IsIconized() )
954 return;
955
956 // If the window is maximized, we use the saved window size from before it was maximized
957 if( IsMaximized() )
958 {
961 }
962 else
963 {
965 m_framePos = GetPosition();
966 }
967
968 aCfg->state.pos_x = m_framePos.x;
969 aCfg->state.pos_y = m_framePos.y;
970 aCfg->state.size_x = m_frameSize.x;
971 aCfg->state.size_y = m_frameSize.y;
972 aCfg->state.maximized = IsMaximized();
973 aCfg->state.display = wxDisplay::GetFromWindow( this );
974
975 wxLogTrace( traceDisplayLocation, wxS( "Saving window maximized: %s" ),
976 IsMaximized() ? wxS( "true" ) : wxS( "false" ) );
977 wxLogTrace( traceDisplayLocation, wxS( "Saving config position (%d, %d) with size (%d, %d)" ),
979
980 // Once this is fully implemented, wxAuiManager will be used to maintain
981 // the persistence of the main frame and all it's managed windows and
982 // all of the legacy frame persistence position code can be removed.
983#if wxCHECK_VERSION( 3, 3, 0 )
984 {
985 WX_AUI_JSON_SERIALIZER serializer( m_auimgr );
986 nlohmann::json state = serializer.Serialize();
987
988 if( state.is_null() || state.empty() )
989 aCfg->aui_state = nlohmann::json();
990 else
991 aCfg->aui_state = state;
992
993 aCfg->perspective.clear();
994 }
995#else
996 aCfg->perspective = m_auimgr.SavePerspective().ToStdString();
997 aCfg->aui_state = nlohmann::json();
998#endif
999
1000 aCfg->mru_path = m_mruPath;
1001}
1002
1003
1005{
1007
1008 // Get file history size from common settings
1009 int fileHistorySize = Pgm().GetCommonSettings()->m_System.file_history_size;
1010
1011 // Load the recently used files into the history menu
1012 m_fileHistory = new FILE_HISTORY( (unsigned) std::max( 1, fileHistorySize ),
1014 m_fileHistory->Load( *aCfg );
1015}
1016
1017
1019{
1020 wxCHECK( config(), /* void */ );
1021
1023
1024 bool fileOpen = m_isClosing && m_isNonUserClose;
1025
1026 wxString currentlyOpenedFile = GetCurrentFileName();
1027
1028 if( Pgm().GetCommonSettings()->m_Session.remember_open_files && !currentlyOpenedFile.IsEmpty() )
1029 {
1030 wxFileName rfn( currentlyOpenedFile );
1031 rfn.MakeRelativeTo( Prj().GetProjectPath() );
1032 Prj().GetLocalSettings().SaveFileState( rfn.GetFullPath(), &aCfg->m_Window, fileOpen );
1033 }
1034
1035 // Save the recently used files list
1036 if( m_fileHistory )
1037 {
1038 // Save the currently opened file in the file history
1039 if( !currentlyOpenedFile.IsEmpty() )
1040 UpdateFileHistory( currentlyOpenedFile );
1041
1042 m_fileHistory->Save( *aCfg );
1043 }
1044}
1045
1046
1051
1052
1054{
1055 // KICAD_MANAGER_FRAME overrides this
1056 return Kiface().KifaceSettings();
1057}
1058
1059
1061{
1062 return Kiface().KifaceSearch();
1063}
1064
1065
1067{
1068 return Kiface().GetHelpFileName();
1069}
1070
1071
1072void EDA_BASE_FRAME::PrintMsg( const wxString& text )
1073{
1074 SetStatusText( text );
1075}
1076
1077
1079{
1080#if defined( __WXOSX_MAC__ )
1082#else
1083 m_infoBar = new WX_INFOBAR( this, &m_auimgr );
1084
1085 m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) ).Top().Layer(1) );
1086#endif
1087}
1088
1089
1091{
1092#if defined( __WXOSX_MAC__ )
1093 m_auimgr.Update();
1094#else
1095 // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
1096 // hiding it.
1097 m_auimgr.Update();
1098
1099 // We don't want the infobar displayed right away
1100 m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
1101 m_auimgr.Update();
1102#endif
1103}
1104
1105
1107{
1108 if( !ADVANCED_CFG::GetCfg().m_EnableUseAuiPerspective )
1109 return;
1110
1111#if wxCHECK_VERSION( 3, 3, 0 )
1112 bool restored = false;
1113
1114 if( !m_auiLayoutState.is_null() && !m_auiLayoutState.empty() )
1115 {
1116 WX_AUI_JSON_SERIALIZER serializer( m_auimgr );
1117
1118 if( serializer.Deserialize( m_auiLayoutState ) )
1119 restored = true;
1120 }
1121
1122 if( !restored && !m_perspective.IsEmpty() )
1123 m_auimgr.LoadPerspective( m_perspective );
1124#else
1125 if( !m_perspective.IsEmpty() )
1126 m_auimgr.LoadPerspective( m_perspective );
1127#endif
1128}
1129
1130
1131void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
1133{
1134 m_infoBar->RemoveAllButtons();
1135
1136 if( aShowCloseButton )
1137 m_infoBar->AddCloseButton();
1138
1139 GetInfoBar()->ShowMessageFor( aErrorMsg, 8000, wxICON_ERROR, aType );
1140}
1141
1142
1143void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
1144 std::function<void(void)> aCallback )
1145{
1146 m_infoBar->RemoveAllButtons();
1147
1148 if( aShowCloseButton )
1149 m_infoBar->AddCloseButton();
1150
1151 if( aCallback )
1152 m_infoBar->SetCallback( aCallback );
1153
1154 GetInfoBar()->ShowMessageFor( aErrorMsg, 6000, wxICON_ERROR );
1155}
1156
1157
1158void EDA_BASE_FRAME::ShowInfoBarWarning( const wxString& aWarningMsg, bool aShowCloseButton )
1159{
1160 m_infoBar->RemoveAllButtons();
1161
1162 if( aShowCloseButton )
1163 m_infoBar->AddCloseButton();
1164
1165 GetInfoBar()->ShowMessageFor( aWarningMsg, 6000, wxICON_WARNING );
1166}
1167
1168
1169void EDA_BASE_FRAME::ShowInfoBarMsg( const wxString& aMsg, bool aShowCloseButton )
1170{
1171 m_infoBar->RemoveAllButtons();
1172
1173 if( aShowCloseButton )
1174 m_infoBar->AddCloseButton();
1175
1176 GetInfoBar()->ShowMessageFor( aMsg, 8000, wxICON_INFORMATION );
1177}
1178
1179
1180void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory )
1181{
1182 if( !aFileHistory )
1183 aFileHistory = m_fileHistory;
1184
1185 wxASSERT( aFileHistory );
1186
1187 aFileHistory->AddFileToHistory( FullFileName );
1188
1189 // Update the menubar to update the file history menu
1190 if( !m_isClosing && GetMenuBar() )
1191 {
1193 GetMenuBar()->Refresh();
1194 }
1195}
1196
1197
1198wxString EDA_BASE_FRAME::GetFileFromHistory( int cmdId, const wxString& type,
1199 FILE_HISTORY* aFileHistory )
1200{
1201 if( !aFileHistory )
1202 aFileHistory = m_fileHistory;
1203
1204 wxASSERT( aFileHistory );
1205
1206 int baseId = aFileHistory->GetBaseId();
1207
1208 wxASSERT( cmdId >= baseId && cmdId < baseId + (int) aFileHistory->GetCount() );
1209
1210 unsigned i = cmdId - baseId;
1211
1212 if( i < aFileHistory->GetCount() )
1213 {
1214 wxString fn = aFileHistory->GetHistoryFile( i );
1215
1216 if( wxFileName::FileExists( fn ) )
1217 {
1218 return fn;
1219 }
1220 else
1221 {
1222 DisplayErrorMessage( this, wxString::Format( _( "File '%s' was not found." ), fn ) );
1223 aFileHistory->RemoveFileFromHistory( i );
1224 }
1225 }
1226
1227 // Update the menubar to update the file history menu
1228 if( GetMenuBar() )
1229 {
1231 GetMenuBar()->Refresh();
1232 }
1233
1234 return wxEmptyString;
1235}
1236
1237
1239{
1240 wxASSERT( m_fileHistory );
1241
1242 m_fileHistory->ClearFileHistory();
1243
1244 // Update the menubar to update the file history menu
1245 if( GetMenuBar() )
1246 {
1248 GetMenuBar()->Refresh();
1249 }
1250}
1251
1252
1253void EDA_BASE_FRAME::OnKicadAbout( wxCommandEvent& event )
1254{
1255 void ShowAboutDialog( EDA_BASE_FRAME * aParent ); // See AboutDialog_main.cpp
1256 ShowAboutDialog( this );
1257}
1258
1259
1260void EDA_BASE_FRAME::OnPreferences( wxCommandEvent& event )
1261{
1262 ShowPreferences( wxEmptyString, wxEmptyString );
1263}
1264
1265
1266void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParentPage )
1267{
1268 PAGED_DIALOG dlg( this, _( "Preferences" ), true, true, wxEmptyString,
1269 wxWindow::FromDIP( wxSize( 980, 560 ), nullptr ) );
1270
1271 dlg.SetEvtHandlerEnabled( false );
1272
1273 {
1274 WX_BUSY_INDICATOR busy_cursor;
1275
1276 WX_TREEBOOK* book = dlg.GetTreebook();
1277 PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( this, book, false );
1278 std::vector<int> expand;
1279
1280 wxWindow* kicadMgr_window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
1281
1282 if( KICAD_MANAGER_FRAME* kicadMgr = static_cast<KICAD_MANAGER_FRAME*>( kicadMgr_window ) )
1283 {
1284 ACTION_MANAGER* actionMgr = kicadMgr->GetToolManager()->GetActionManager();
1285
1286 for( const auto& [name, action] : actionMgr->GetActions() )
1287 hotkeysPanel->ActionsList().push_back( action );
1288 }
1289
1290 book->AddLazyPage(
1291 []( wxWindow* aParent ) -> wxWindow*
1292 {
1293 return new PANEL_COMMON_SETTINGS( aParent );
1294 },
1295 _( "Common" ) );
1296
1297 book->AddLazyPage(
1298 []( wxWindow* aParent ) -> wxWindow*
1299 {
1300 return new PANEL_MOUSE_SETTINGS( aParent );
1301 }, _( "Mouse and Touchpad" ) );
1302
1303 book->AddLazyPage(
1304 [] ( wxWindow* aParent ) -> wxWindow*
1305 {
1306 return new PANEL_SPACEMOUSE( aParent );
1307 }, _( "SpaceMouse" ) );
1308
1309 book->AddPage( hotkeysPanel, _( "Hotkeys" ) );
1310
1311 book->AddLazyPage(
1312 []( wxWindow* aParent ) -> wxWindow*
1313 {
1314 return new PANEL_GIT_REPOS( aParent );
1315 }, _( "Version Control" ) );
1316
1317#ifdef KICAD_USE_SENTRY
1318 book->AddLazyPage(
1319 []( wxWindow* aParent ) -> wxWindow*
1320 {
1321 return new PANEL_DATA_COLLECTION( aParent );
1322 }, _( "Data Collection" ) );
1323#endif
1324
1325#define LAZY_CTOR( key ) \
1326 [this, kiface]( wxWindow* aParent ) \
1327 { \
1328 return kiface->CreateKiWindow( aParent, key, &Kiway() ); \
1329 }
1330
1331 // If a dll is not loaded, the loader will show an error message.
1332
1333 try
1334 {
1335 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_SCH ) )
1336 {
1337 kiface->GetActions( hotkeysPanel->ActionsList() );
1338
1340 expand.push_back( (int) book->GetPageCount() );
1341
1342 book->AddPage( new wxPanel( book ), _( "Symbol Editor" ) );
1343 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_DISP_OPTIONS ), _( "Display Options" ) );
1344 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_GRIDS ), _( "Grids" ) );
1345 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_OPTIONS ), _( "Editing Options" ) );
1346 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_COLORS ), _( "Colors" ) );
1347
1348 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1349 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_TOOLBARS ), _( "Toolbars" ) );
1350
1351 if( GetFrameType() == FRAME_SCH )
1352 expand.push_back( (int) book->GetPageCount() );
1353
1354 book->AddPage( new wxPanel( book ), _( "Schematic Editor" ) );
1355 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_DISP_OPTIONS ), _( "Display Options" ) );
1356 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_GRIDS ), _( "Grids" ) );
1357 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_EDIT_OPTIONS ), _( "Editing Options" ) );
1358 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_COLORS ), _( "Colors" ) );
1359
1360 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1361 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_TOOLBARS ), _( "Toolbars" ) );
1362
1363 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_FIELD_NAME_TEMPLATES ), _( "Field Name Templates" ) );
1364 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_SIMULATOR ), _( "Simulator" ) );
1365 }
1366 }
1367 catch( ... )
1368 {
1369 }
1370
1371 try
1372 {
1373 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PCB ) )
1374 {
1375 kiface->GetActions( hotkeysPanel->ActionsList() );
1376
1378 expand.push_back( (int) book->GetPageCount() );
1379
1380 book->AddPage( new wxPanel( book ), _( "Footprint Editor" ) );
1381 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DISPLAY_OPTIONS ), _( "Display Options" ) );
1382 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_GRIDS ), _( "Grids" ) );
1383 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_ORIGINS_AXES ), _( "Origins & Axes" ) );
1384 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_EDIT_OPTIONS ), _( "Editing Options" ) );
1385 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_COLORS ), _( "Colors" ) );
1386
1387 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1388 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_TOOLBARS ), _( "Toolbars" ) );
1389
1390 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DEFAULT_FIELDS ), _( "Footprint Defaults" ) );
1391 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DEFAULT_GRAPHICS_VALUES ), _( "Graphics Defaults" ) );
1392
1394 expand.push_back( (int) book->GetPageCount() );
1395
1396 book->AddPage( new wxPanel( book ), _( "PCB Editor" ) );
1397 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_DISPLAY_OPTS ), _( "Display Options" ) );
1398 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_GRIDS ), _( "Grids" ) );
1399 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ORIGINS_AXES ), _( "Origins & Axes" ) );
1400 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_EDIT_OPTIONS ), _( "Editing Options" ) );
1401 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_COLORS ), _( "Colors" ) );
1402
1403 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1404 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_TOOLBARS ), _( "Toolbars" ) );
1405
1406 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ACTION_PLUGINS ), _( "Plugins" ) );
1407
1409 expand.push_back( (int) book->GetPageCount() );
1410
1411 book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
1412 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_DISPLAY_OPTIONS ), _( "General" ) );
1413
1414 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1415 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_TOOLBARS ), _( "Toolbars" ) );
1416
1417 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_OPENGL ), _( "Realtime Renderer" ) );
1418 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_RAYTRACING ), _( "Raytracing Renderer" ) );
1419 }
1420 }
1421 catch( ... )
1422 {
1423 }
1424
1425 try
1426 {
1427 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_GERBVIEW ) )
1428 {
1429 kiface->GetActions( hotkeysPanel->ActionsList() );
1430
1431 if( GetFrameType() == FRAME_GERBER )
1432 expand.push_back( (int) book->GetPageCount() );
1433
1434 book->AddPage( new wxPanel( book ), _( "Gerber Viewer" ) );
1435 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
1436 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_COLORS ), _( "Colors" ) );
1437
1438 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1439 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_TOOLBARS ), _( "Toolbars" ) );
1440
1441 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_GRIDS ), _( "Grids" ) );
1442 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
1443 }
1444 }
1445 catch( ... )
1446 {
1447 }
1448
1449 try
1450 {
1451 if( KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PL_EDITOR ) )
1452 {
1453 kiface->GetActions( hotkeysPanel->ActionsList() );
1454
1455 if( GetFrameType() == FRAME_PL_EDITOR )
1456 expand.push_back( (int) book->GetPageCount() );
1457
1458 book->AddPage( new wxPanel( book ), _( "Drawing Sheet Editor" ) );
1459 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_DISPLAY_OPTIONS ), _( "Display Options" ) );
1460 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_GRIDS ), _( "Grids" ) );
1461 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_COLORS ), _( "Colors" ) );
1462
1463 if( ADVANCED_CFG::GetCfg().m_ConfigurableToolbars )
1464 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_TOOLBARS ), _( "Toolbars" ) );
1465
1466 book->AddLazyPage(
1467 []( wxWindow* aParent ) -> wxWindow*
1468 {
1469 return new PANEL_PACKAGES_AND_UPDATES( aParent );
1470 }, _( "Packages and Updates" ) );
1471 }
1472 }
1473 catch( ... )
1474 {
1475 }
1476
1477#ifdef KICAD_IPC_API
1478 book->AddPage( new PANEL_PLUGIN_SETTINGS( book ), _( "Plugins" ) );
1479#endif
1480
1481 book->AddPage( new PANEL_MAINTENANCE( book, this ), _( "Maintenance" ) );
1482
1483 // Update all of the action hotkeys. The process of loading the actions through
1484 // the KiFACE will only get us the default hotkeys
1485 ReadHotKeyConfigIntoActions( wxEmptyString, hotkeysPanel->ActionsList() );
1486
1487 for( size_t i = 0; i < book->GetPageCount(); ++i )
1488 book->GetPage( i )->Layout();
1489
1490 for( int page : expand )
1491 book->ExpandNode( page );
1492
1493 if( !aStartPage.IsEmpty() )
1494 dlg.SetInitialPage( aStartPage, aStartParentPage );
1495
1496 dlg.SetEvtHandlerEnabled( true );
1497#undef LAZY_CTOR
1498 }
1499
1500 if( dlg.ShowModal() == wxID_OK )
1501 {
1502 // Update our grids that are cached in the tool
1503 m_toolManager->ResetTools( TOOL_BASE::REDRAW );
1506 }
1507
1508}
1509
1510
1511void EDA_BASE_FRAME::OnDropFiles( wxDropFilesEvent& aEvent )
1512{
1513 Raise();
1514
1515 wxString* files = aEvent.GetFiles();
1516
1517 for( int nb = 0; nb < aEvent.GetNumberOfFiles(); nb++ )
1518 {
1519 const wxFileName fn = wxFileName( files[nb] );
1520 wxString ext = fn.GetExt();
1521
1522 // Alias all gerber files as GerberFileExtension
1525
1526 if( m_acceptedExts.find( ext.ToStdString() ) != m_acceptedExts.end() )
1527 m_AcceptedFiles.emplace_back( fn );
1528 }
1529
1531 m_AcceptedFiles.clear();
1532}
1533
1534
1536{
1537 for( const wxFileName& file : m_AcceptedFiles )
1538 {
1539 wxString fn = file.GetFullPath();
1540 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( file.GetExt() ), &fn );
1541 }
1542}
1543
1544
1545bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName, bool aVerbose )
1546{
1547 wxString msg;
1548 wxFileName fn = aFileName;
1549
1550 // Check for absence of a file path with a file name. Unfortunately KiCad
1551 // uses paths relative to the current project path without the ./ part which
1552 // confuses wxFileName. Making the file name path absolute may be less than
1553 // elegant but it solves the problem.
1554 if( fn.GetPath().IsEmpty() && fn.HasName() )
1555 fn.MakeAbsolute();
1556
1557 wxCHECK_MSG( fn.IsOk(), false,
1558 wxT( "File name object is invalid. Bad programmer!" ) );
1559 wxCHECK_MSG( !fn.GetPath().IsEmpty(), false,
1560 wxT( "File name object path <" ) + fn.GetFullPath() +
1561 wxT( "> is not set. Bad programmer!" ) );
1562
1563 if( fn.IsDir() && !fn.IsDirWritable() )
1564 {
1565 msg.Printf( _( "Insufficient permissions to folder '%s'." ), fn.GetPath() );
1566 }
1567 else if( !fn.FileExists() && !fn.IsDirWritable() )
1568 {
1569 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fn.GetFullPath() );
1570 }
1571 else if( fn.FileExists() && !fn.IsFileWritable() )
1572 {
1573 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fn.GetFullPath() );
1574 }
1575
1576 if( !msg.IsEmpty() )
1577 {
1578 if( aVerbose )
1579 DisplayErrorMessage( this, msg );
1580
1581 return false;
1582 }
1583
1584 return true;
1585}
1586
1587
1588void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
1589{
1590 if( !Pgm().IsGUI() )
1591 return;
1592
1593 wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
1594
1595 wxFileName autoSaveFileName = aFileName;
1596
1597 // Check for auto save file.
1598 autoSaveFileName.SetName( FILEEXT::AutoSaveFilePrefix + aFileName.GetName() );
1599
1600 wxLogTrace( traceAutoSave,
1601 wxT( "Checking for auto save file " ) + autoSaveFileName.GetFullPath() );
1602
1603 if( !autoSaveFileName.FileExists() )
1604 return;
1605
1606 wxString msg = wxString::Format( _( "Well this is potentially embarrassing!\n"
1607 "It appears that the last time you were editing\n"
1608 "%s\n"
1609 "KiCad exited before saving.\n"
1610 "\n"
1611 "Do you wish to open the auto-saved file instead?" ),
1612 aFileName.GetFullName() );
1613
1614 int response = wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
1615 this );
1616
1617 // Make a backup of the current file, delete the file, and rename the auto save file to
1618 // the file name.
1619 if( response == wxYES )
1620 {
1621 // Preserve the permissions of the current file
1622 KIPLATFORM::IO::DuplicatePermissions( aFileName.GetFullPath(),
1623 autoSaveFileName.GetFullPath() );
1624
1625 if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
1626 {
1627 wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
1628 Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION, this );
1629 }
1630 }
1631 else
1632 {
1633 DeleteAutoSaveFile( aFileName );
1634 }
1635}
1636
1637
1638void EDA_BASE_FRAME::DeleteAutoSaveFile( const wxFileName& aFileName )
1639{
1640 if( !Pgm().IsGUI() )
1641 return;
1642
1643 wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
1644
1645 wxFileName autoSaveFn = aFileName;
1646 autoSaveFn.SetName( FILEEXT::AutoSaveFilePrefix + aFileName.GetName() );
1647
1648 if( autoSaveFn.FileExists() )
1649 {
1650 wxLogTrace( traceAutoSave, wxT( "Removing auto save file " ) + autoSaveFn.GetFullPath() );
1651 wxRemoveFile( autoSaveFn.GetFullPath() );
1652 }
1653}
1654
1655
1657{
1658 // This function should be overridden in child classes
1659 return false;
1660}
1661
1662
1664{
1665 wxAcceleratorEntry entries[1];
1666 entries[0].Set( wxACCEL_CTRL, int( 'Q' ), wxID_EXIT );
1667 wxAcceleratorTable accel( 1, entries );
1668 SetAcceleratorTable( accel );
1669}
1670
1671
1677
1678
1680{
1681 m_undoList.PushCommand( aNewitem );
1682
1683 // Delete the extra items, if count max reached
1684 if( m_undoRedoCountMax > 0 )
1685 {
1686 int extraitems = GetUndoCommandCount() - m_undoRedoCountMax;
1687
1688 if( extraitems > 0 )
1689 ClearUndoORRedoList( UNDO_LIST, extraitems );
1690 }
1691}
1692
1693
1695{
1696 m_redoList.PushCommand( aNewitem );
1697
1698 // Delete the extra items, if count max reached
1699 if( m_undoRedoCountMax > 0 )
1700 {
1701 int extraitems = GetRedoCommandCount() - m_undoRedoCountMax;
1702
1703 if( extraitems > 0 )
1704 ClearUndoORRedoList( REDO_LIST, extraitems );
1705 }
1706}
1707
1708
1713
1714
1719
1720
1722{
1723 if( GetUndoCommandCount() > 0 )
1724 return m_undoList.m_CommandsList.back()->GetDescription();
1725
1726 return wxEmptyString;
1727}
1728
1729
1731{
1732 if( GetRedoCommandCount() > 0 )
1733 return m_redoList.m_CommandsList.back()->GetDescription();
1734
1735 return wxEmptyString;
1736}
1737
1738
1740{
1741 m_autoSaveRequired = true;
1742}
1743
1744
1746{
1747 SetUserUnits( aUnits );
1749
1750 wxCommandEvent e( EDA_EVT_UNITS_CHANGED );
1751 e.SetInt( static_cast<int>( aUnits ) );
1752 e.SetClientData( this );
1753 ProcessEventLocally( e );
1754}
1755
1756
1757void EDA_BASE_FRAME::OnMaximize( wxMaximizeEvent& aEvent )
1758{
1759 // When we maximize the window, we want to save the old information
1760 // so that we can add it to the settings on next window load.
1761 // Contrary to the documentation, this event seems to be generated
1762 // when the window is also being unmaximized on OSX, so we only
1763 // capture the size information when we maximize the window when on OSX.
1764#ifdef __WXOSX__
1765 if( !IsMaximized() )
1766#endif
1767 {
1769 m_normalFramePos = GetPosition();
1770 wxLogTrace( traceDisplayLocation,
1771 "Maximizing window - Saving position (%d, %d) with size (%d, %d)",
1774 }
1775
1776 // Skip event to actually maximize the window
1777 aEvent.Skip();
1778}
1779
1780
1782{
1783#ifdef __WXGTK__
1784 wxSize winSize = GetSize();
1785
1786 // GTK includes the window decorations in the normal GetSize call,
1787 // so we have to use a GTK-specific sizing call that returns the
1788 // non-decorated window size.
1790 {
1791 int width = 0;
1792 int height = 0;
1793 GTKDoGetSize( &width, &height );
1794
1795 winSize.Set( width, height );
1796 }
1797#else
1798 wxSize winSize = GetSize();
1799#endif
1800
1801 return winSize;
1802}
1803
1804
1806{
1807 // Update the icon theme when the system theme changes and update the toolbars
1809 ThemeChanged();
1810
1811 // This isn't handled by ThemeChanged()
1812 if( GetMenuBar() )
1813 {
1814 // For icons in menus, icon scaling & hotkeys
1816 GetMenuBar()->Refresh();
1817 }
1818}
1819
1820
1821void EDA_BASE_FRAME::onSystemColorChange( wxSysColourChangedEvent& aEvent )
1822{
1823 // Call the handler to update the colors used in the frame
1825
1826 // Skip the change event to ensure the rest of the window controls get it
1827 aEvent.Skip();
1828}
1829
1830
1831void EDA_BASE_FRAME::onIconize( wxIconizeEvent& aEvent )
1832{
1833 // Call the handler
1834 handleIconizeEvent( aEvent );
1835
1836 // Skip the event.
1837 aEvent.Skip();
1838}
1839
1840
1841#ifdef __WXMSW__
1842WXLRESULT EDA_BASE_FRAME::MSWWindowProc( WXUINT message, WXWPARAM wParam, WXLPARAM lParam )
1843{
1844 // This will help avoid the menu keeping focus when the alt key is released
1845 // You can still trigger accelerators as long as you hold down alt
1846 if( message == WM_SYSCOMMAND )
1847 {
1848 if( wParam == SC_KEYMENU && ( lParam >> 16 ) <= 0 )
1849 return 0;
1850 }
1851
1852 return wxFrame::MSWWindowProc( message, wParam, lParam );
1853}
1854#endif
1855
1856
1858{
1859 ACTION_MENU* langsMenu = new ACTION_MENU( false, aControlTool );
1860 langsMenu->SetTitle( _( "Set Language" ) );
1861 langsMenu->SetIcon( BITMAPS::language );
1862
1863 wxString tooltip;
1864
1865 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
1866 {
1867 wxString label;
1868
1869 if( LanguagesList[ii].m_DoNotTranslate )
1870 label = LanguagesList[ii].m_Lang_Label;
1871 else
1872 label = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
1873
1874 wxMenuItem* item =
1875 new wxMenuItem( langsMenu,
1876 LanguagesList[ii].m_KI_Lang_Identifier, // wxMenuItem wxID
1877 label, tooltip, wxITEM_CHECK );
1878
1879 langsMenu->Append( item );
1880 }
1881
1882 // This must be done after the items are added
1883 aMasterMenu->Add( langsMenu );
1884}
void ShowAboutDialog(EDA_BASE_FRAME *aParent)
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:172
BITMAP_STORE * GetBitmapStore()
Definition bitmap.cpp:92
static TOOL_ACTION paste
Definition actions.h:80
static TOOL_ACTION about
Definition actions.h:288
static TOOL_ACTION reportBug
Definition actions.h:292
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION donate
Definition actions.h:290
static TOOL_ACTION listHotKeys
Definition actions.h:289
static TOOL_ACTION getInvolved
Definition actions.h:291
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:286
static TOOL_ACTION help
Definition actions.h:287
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
virtual void CheckForAutoSaveFile(const wxFileName &aFileName)
Check if an auto save file exists for aFileName and takes the appropriate action depending on the use...
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 DeleteAutoSaveFile(const wxFileName &aFileName)
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:286
@ FACE_SCH
eeschema DSO
Definition kiway.h:293
@ FACE_PL_EDITOR
Definition kiway.h:297
@ FACE_PCB
pcbnew DSO
Definition kiway.h:294
@ FACE_GERBVIEW
Definition kiway.h:296
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:589
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:136
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:576
virtual int GetSelectedLanguageIdentifier() const
Definition pgm_base.h:229
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:125
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:210
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:194
This file is part of the common library.
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:96
@ 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:106
@ PANEL_SCH_FIELD_NAME_TEMPLATES
Definition frame_type.h:83
@ PANEL_DS_TOOLBARS
Definition frame_type.h:118
@ PANEL_SCH_TOOLBARS
Definition frame_type.h:82
@ PANEL_GBR_DISPLAY_OPTIONS
Definition frame_type.h:108
@ PANEL_3DV_OPENGL
Definition frame_type.h:104
@ PANEL_FP_DEFAULT_GRAPHICS_VALUES
Definition frame_type.h:92
@ PANEL_PCB_TOOLBARS
Definition frame_type.h:99
@ PANEL_PCB_ORIGINS_AXES
Definition frame_type.h:101
@ PANEL_PCB_EDIT_OPTIONS
Definition frame_type.h:97
@ PANEL_SCH_DISP_OPTIONS
Definition frame_type.h:78
@ PANEL_FP_DISPLAY_OPTIONS
Definition frame_type.h:86
@ PANEL_SCH_SIMULATOR
Definition frame_type.h:84
@ FRAME_SCH
Definition frame_type.h:34
@ PANEL_DS_COLORS
Definition frame_type.h:117
@ PANEL_PCB_COLORS
Definition frame_type.h:98
@ PANEL_SYM_TOOLBARS
Definition frame_type.h:76
@ PANEL_3DV_RAYTRACING
Definition frame_type.h:105
@ PANEL_SYM_EDIT_OPTIONS
Definition frame_type.h:74
@ PANEL_FP_GRIDS
Definition frame_type.h:87
@ PANEL_SCH_EDIT_OPTIONS
Definition frame_type.h:80
@ PANEL_FP_ORIGINS_AXES
Definition frame_type.h:93
@ PANEL_SYM_DISP_OPTIONS
Definition frame_type.h:72
@ PANEL_PCB_DISPLAY_OPTS
Definition frame_type.h:95
@ PANEL_FP_COLORS
Definition frame_type.h:89
@ PANEL_FP_DEFAULT_FIELDS
Definition frame_type.h:91
@ PANEL_SYM_COLORS
Definition frame_type.h:75
@ FRAME_PL_EDITOR
Definition frame_type.h:59
@ PANEL_GBR_GRIDS
Definition frame_type.h:111
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
@ FRAME_GERBER
Definition frame_type.h:57
@ PANEL_DS_GRIDS
Definition frame_type.h:116
@ FRAME_PCB_DISPLAY3D
Definition frame_type.h:47
@ PANEL_GBR_TOOLBARS
Definition frame_type.h:113
@ PANEL_FP_EDIT_OPTIONS
Definition frame_type.h:88
@ PANEL_SCH_GRIDS
Definition frame_type.h:79
@ PANEL_FP_TOOLBARS
Definition frame_type.h:90
@ PANEL_PCB_ACTION_PLUGINS
Definition frame_type.h:100
@ PANEL_3DV_DISPLAY_OPTIONS
Definition frame_type.h:103
@ PANEL_DS_DISPLAY_OPTIONS
Definition frame_type.h:115
@ PANEL_SCH_COLORS
Definition frame_type.h:81
@ PANEL_GBR_COLORS
Definition frame_type.h:112
@ PANEL_GBR_EXCELLON_OPTIONS
Definition frame_type.h:110
@ KICAD_MAIN_FRAME_T
Definition frame_type.h:68
static const std::string GerberFileExtension
static const std::string AutoSaveFilePrefix
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
bool DuplicatePermissions(const wxString &aSrc, const wxString &aDest)
Duplicates the file security data from one file to another ensuring that they are the same between bo...
Definition unix/io.cpp:47
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:913
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition pgm_base.cpp:92
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:153
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.