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 (C) 1992-2023 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
27#include <advanced_config.h>
28#include <bitmaps.h>
29#include <bitmap_store.h>
30#include <dialog_shim.h>
35#include <eda_dde.h>
36#include <file_history.h>
37#include <id.h>
38#include <kiface_base.h>
39#include <hotkeys_basic.h>
41#include <paths.h>
42#include <confirm.h>
43#include <panel_pcm_settings.h>
44#include <pgm_base.h>
49#include <tool/action_manager.h>
50#include <tool/action_menu.h>
51#include <tool/action_toolbar.h>
52#include <tool/actions.h>
53#include <tool/common_control.h>
54#include <tool/tool_manager.h>
56#include <trace_helpers.h>
58#include <widgets/wx_infobar.h>
60#include <widgets/wx_grid.h>
61#include <widgets/wx_treebook.h>
62#include <wx/app.h>
63#include <wx/config.h>
64#include <wx/display.h>
65#include <wx/stdpaths.h>
66#include <wx/string.h>
67#include <kiplatform/app.h>
68#include <kiplatform/io.h>
69#include <kiplatform/ui.h>
70
71#include <functional>
72#include <kiface_ids.h>
73
74wxDEFINE_EVENT( EDA_EVT_UNITS_CHANGED, wxCommandEvent );
75
76
77// Minimum window size
78static const wxSize minSize( FRAME_T aFrameType )
79{
80 switch( aFrameType )
81 {
83 return wxSize( 406, 354 );
84
85 default:
86 return wxSize( 500, 400 );
87 }
88}
89
90
91static const wxSize defaultSize( FRAME_T aFrameType )
92{
93 switch( aFrameType )
94 {
96 return wxSize( 850, 540 );
97
98 default:
99 return wxSize( 1280, 720 );
100 }
101}
102
103
104BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
105 // These event table entries are needed to handle events from the mac application menu
106 EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::OnKicadAbout )
107 EVT_MENU( wxID_PREFERENCES, EDA_BASE_FRAME::OnPreferences )
108
109 EVT_CHAR_HOOK( EDA_BASE_FRAME::OnCharHook )
110 EVT_MENU_OPEN( EDA_BASE_FRAME::OnMenuEvent )
111 EVT_MENU_CLOSE( EDA_BASE_FRAME::OnMenuEvent )
112 EVT_MENU_HIGHLIGHT_ALL( EDA_BASE_FRAME::OnMenuEvent )
113 EVT_MOVE( EDA_BASE_FRAME::OnMove )
114 EVT_SIZE( EDA_BASE_FRAME::OnSize )
115 EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize )
116
117 EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange )
118 EVT_ICONIZE( EDA_BASE_FRAME::onIconize )
119END_EVENT_TABLE()
120
121
122void EDA_BASE_FRAME::commonInit( FRAME_T aFrameType )
123{
124 m_ident = aFrameType;
125 m_maximizeByDefault = false;
126 m_infoBar = nullptr;
127 m_settingsManager = nullptr;
128 m_fileHistory = nullptr;
129 m_supportsAutoSave = false;
130 m_autoSavePending = false;
131 m_undoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
132 m_isClosing = false;
133 m_isNonUserClose = false;
134 m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
135 m_autoSaveRequired = false;
137 m_frameSize = defaultSize( aFrameType );
138 m_displayIndex = -1;
139
140 m_auimgr.SetArtProvider( new WX_AUI_DOCK_ART() );
141
142 m_settingsManager = &Pgm().GetSettingsManager();
143
144 // Set a reasonable minimal size for the frame
145 SetSizeHints( minSize( aFrameType ).x, minSize( aFrameType ).y, -1, -1, -1, -1 );
146
147 // Store dimensions of the user area of the main window.
148 GetClientSize( &m_frameSize.x, &m_frameSize.y );
149
150 Connect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
151 wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
152
153 // hook wxEVT_CLOSE_WINDOW so we can call SaveSettings(). This function seems
154 // to be called before any other hook for wxCloseEvent, which is necessary.
155 Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
156
157 initExitKey();
158}
159
160
161EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle,
162 const wxPoint& aPos, const wxSize& aSize, long aStyle,
163 const wxString& aFrameName, KIWAY* aKiway,
164 const EDA_IU_SCALE& aIuScale ) :
165 wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ),
166 TOOLS_HOLDER(),
167 KIWAY_HOLDER( aKiway, KIWAY_HOLDER::FRAME ),
169{
170 commonInit( aFrameType );
171}
172
173
174wxWindow* findQuasiModalDialog( wxWindow* aParent )
175{
176 for( wxWindow* child : aParent->GetChildren() )
177 {
178 if( DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( child ) )
179 {
180 if( dlg->IsQuasiModal() )
181 return dlg;
182
183 if( wxWindow* nestedDlg = findQuasiModalDialog( child ) )
184 return nestedDlg;
185 }
186 }
187
188 return nullptr;
189}
190
191
193{
194 if( wxWindow* dlg = ::findQuasiModalDialog( this ) )
195 return dlg;
196
197 // FIXME: CvPcb is currently implemented on top of KIWAY_PLAYER rather than DIALOG_SHIM,
198 // so we have to look for it separately.
199 if( m_ident == FRAME_SCH )
200 {
201 wxWindow* cvpcb = wxWindow::FindWindowByName( wxS( "CvpcbFrame" ) );
202
203 if( cvpcb )
204 return cvpcb;
205 }
206
207 return nullptr;
208}
209
210
211void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
212{
213 // Don't allow closing when a quasi-modal is open.
214 wxWindow* quasiModal = findQuasiModalDialog();
215
216 if( quasiModal )
217 {
218 // Raise and notify; don't give the user a warning regarding "quasi-modal dialogs"
219 // when they have no idea what those are.
220 quasiModal->Raise();
221 wxBell();
222
223 if( event.CanVeto() )
224 event.Veto();
225
226 return;
227 }
228
229
230 if( event.GetId() == wxEVT_QUERY_END_SESSION
231 || event.GetId() == wxEVT_END_SESSION )
232 {
233 // End session means the OS is going to terminate us
234 m_isNonUserClose = true;
235 }
236
237 if( canCloseWindow( event ) )
238 {
239 m_isClosing = true;
240
241 if( m_infoBar )
243
244 APP_SETTINGS_BASE* cfg = config();
245
246 if( cfg )
247 SaveSettings( cfg ); // virtual, wxFrame specific
248
250
251 // Destroy (safe delete frame) this frame only in non modal mode.
252 // In modal mode, the caller will call Destroy().
253 if( !IsModal() )
254 Destroy();
255 }
256 else
257 {
258 if( event.CanVeto() )
259 event.Veto();
260 }
261}
262
263
265{
266 delete m_autoSaveTimer;
267 delete m_fileHistory;
268
270
272
274}
275
276
277bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent )
278{
279#ifdef __WXMAC__
280 // Apple in its infinite wisdom will raise a disabled window before even passing
281 // us the event, so we have no way to stop it. Instead, we have to catch an
282 // improperly ordered disabled window and quasi-modal dialog here and reorder
283 // them.
284 if( !IsEnabled() && IsActive() )
285 {
286 wxWindow* dlg = findQuasiModalDialog();
287 if( dlg )
288 dlg->Raise();
289 }
290#endif
291
292 if( !wxFrame::ProcessEvent( aEvent ) )
293 return false;
294
295 if( Pgm().m_Quitting )
296 return true;
297
298 if( !m_isClosing && m_supportsAutoSave && IsShownOnScreen() && IsActive()
300 && GetAutoSaveInterval() > 0 )
301 {
302 if( !m_autoSavePending )
303 {
304 wxLogTrace( traceAutoSave, wxT( "Starting auto save timer." ) );
305 m_autoSaveTimer->Start( GetAutoSaveInterval() * 1000, wxTIMER_ONE_SHOT );
306 m_autoSavePending = true;
307 }
308 else if( m_autoSaveTimer->IsRunning() )
309 {
310 wxLogTrace( traceAutoSave, wxT( "Stopping auto save timer." ) );
311 m_autoSaveTimer->Stop();
312 m_autoSavePending = false;
313 }
314 }
315
316 return true;
317}
318
319
321{
322 return Pgm().GetCommonSettings()->m_System.autosave_interval;
323}
324
325
326void EDA_BASE_FRAME::onAutoSaveTimer( wxTimerEvent& aEvent )
327{
328 // Don't stomp on someone else's timer event.
329 if( aEvent.GetId() != ID_AUTO_SAVE_TIMER )
330 {
331 aEvent.Skip();
332 return;
333 }
334
335 if( !doAutoSave() )
336 m_autoSaveTimer->Start( GetAutoSaveInterval() * 1000, wxTIMER_ONE_SHOT );
337}
338
339
341{
342 wxCHECK_MSG( false, true, wxT( "Auto save timer function not overridden. Bad programmer!" ) );
343}
344
345
346void EDA_BASE_FRAME::OnCharHook( wxKeyEvent& aKeyEvent )
347{
348 wxLogTrace( kicadTraceKeyEvent, wxS( "EDA_BASE_FRAME::OnCharHook %s" ), dump( aKeyEvent ) );
349
350 // Key events can be filtered here.
351 // Currently no filtering is made.
352 aKeyEvent.Skip();
353}
354
355
356void EDA_BASE_FRAME::OnMenuEvent( wxMenuEvent& aEvent )
357{
358 if( !m_toolDispatcher )
359 aEvent.Skip();
360 else
362}
363
364
366{
368 std::placeholders::_1,
369 this,
370 aConditions );
371
372 m_uiUpdateMap[aID] = evtFunc;
373
374 Bind( wxEVT_UPDATE_UI, evtFunc, aID );
375}
376
377
379{
380 const auto it = m_uiUpdateMap.find( aID );
381
382 if( it == m_uiUpdateMap.end() )
383 return;
384
385 Unbind( wxEVT_UPDATE_UI, it->second, aID );
386}
387
388
389void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
390 ACTION_CONDITIONS aCond )
391{
392 bool checkRes = false;
393 bool enableRes = true;
394 bool showRes = true;
395 bool isCut = aEvent.GetId() == ACTIONS::cut.GetUIId();
396 bool isCopy = aEvent.GetId() == ACTIONS::copy.GetUIId();
397 bool isPaste = aEvent.GetId() == ACTIONS::paste.GetUIId();
398 SELECTION& selection = aFrame->GetCurrentSelection();
399
400 try
401 {
402 checkRes = aCond.checkCondition( selection );
403 enableRes = aCond.enableCondition( selection );
404 showRes = aCond.showCondition( selection );
405 }
406 catch( std::exception& )
407 {
408 // Something broke with the conditions, just skip the event.
409 aEvent.Skip();
410 return;
411 }
412
413 if( showRes && aEvent.GetId() == ACTIONS::undo.GetUIId() )
414 {
415 wxString msg = _( "Undo" );
416
417 if( enableRes )
418 msg += wxS( " " ) + aFrame->GetUndoActionDescription();
419
420 aEvent.SetText( msg );
421 }
422 else if( showRes && aEvent.GetId() == ACTIONS::redo.GetUIId() )
423 {
424 wxString msg = _( "Redo" );
425
426 if( enableRes )
427 msg += wxS( " " ) + aFrame->GetRedoActionDescription();
428
429 aEvent.SetText( msg );
430 }
431
432 if( isCut || isCopy || isPaste )
433 {
434 wxWindow* focus = wxWindow::FindFocus();
435 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( focus );
436
437 if( textEntry && isCut && textEntry->CanCut() )
438 enableRes = true;
439 else if( textEntry && isCopy && textEntry->CanCopy() )
440 enableRes = true;
441 else if( textEntry && isPaste && textEntry->CanPaste() )
442 enableRes = true;
443 else if( dynamic_cast<WX_GRID*>( focus ) )
444 enableRes = false; // Must disable menu in order to get command as CharHook event
445 }
446
447 aEvent.Enable( enableRes );
448 aEvent.Show( showRes );
449
450 if( aEvent.IsCheckable() )
451 aEvent.Check( checkRes );
452}
453
454
456{
457 // Setup the conditions to check a language menu item
458 auto isCurrentLang =
459 [] ( const SELECTION& aSel, int aLangIdentifier )
460 {
461 return Pgm().GetSelectedLanguageIdentifier() == aLangIdentifier;
462 };
463
464 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
465 {
467 cond.Check( std::bind( isCurrentLang, std::placeholders::_1,
468 LanguagesList[ii].m_WX_Lang_Identifier ) );
469
470 RegisterUIUpdateHandler( LanguagesList[ii].m_KI_Lang_Identifier, cond );
471 }
472}
473
474
476{
484 CallAfter( [=]()
485 {
487 } );
488}
489
490
491void EDA_BASE_FRAME::SetMenuBar( wxMenuBar* menu_bar )
492{
493 wxFrame::SetMenuBar( menu_bar );
494
495 // Move Help menu back to end of menubar
496
497 int pos = GetMenuBar()->FindMenu( _( "&Help" ) + wxS( " " ) );
498
499 if( pos != wxNOT_FOUND )
500 {
501 wxMenu* helpMenu = GetMenuBar()->Remove( pos );
502 GetMenuBar()->Append( helpMenu, _( "&Help" ) + wxS( " " ) );
503 }
504}
505
506
507void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
508{
510 ACTION_MENU* helpMenu = new ACTION_MENU( false, commonControl );
511
512 helpMenu->Add( ACTIONS::help );
513 helpMenu->Add( ACTIONS::gettingStarted );
514 helpMenu->Add( ACTIONS::listHotKeys );
515 helpMenu->Add( ACTIONS::getInvolved );
516 helpMenu->Add( ACTIONS::donate );
517 helpMenu->Add( ACTIONS::reportBug );
518
519 helpMenu->AppendSeparator();
520 helpMenu->Add( ACTIONS::about );
521
522 // Trailing space keeps OSX from hijacking our menu (and disabling everything in it).
523 aMenuBar->Append( helpMenu, _( "&Help" ) + wxS( " " ) );
524 helpMenu->wxMenu::SetTitle( _( "&Help" ) + wxS( " " ) );
525}
526
527
529{
531
532 if( GetMenuBar() )
533 {
535 GetMenuBar()->Refresh();
536 }
537}
538
539
540void EDA_BASE_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
541{
542 TOOLS_HOLDER::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
543
544 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
545
546 if( m_fileHistory )
547 {
548 int historySize = settings->m_System.file_history_size;
549 m_fileHistory->SetMaxFiles( (unsigned) std::max( 0, historySize ) );
550 }
551
553 ThemeChanged();
554
555 if( GetMenuBar() )
556 {
557 // For icons in menus, icon scaling & hotkeys
559 GetMenuBar()->Refresh();
560 }
561}
562
563
565{
567
568 // Update all the toolbars to have new icons
569 wxAuiPaneInfoArray panes = m_auimgr.GetAllPanes();
570
571 for( size_t i = 0; i < panes.GetCount(); ++i )
572 {
573 if( ACTION_TOOLBAR* toolbar = dynamic_cast<ACTION_TOOLBAR*>( panes[i].window ) )
574 toolbar->RefreshBitmaps();
575 }
576}
577
578
579void EDA_BASE_FRAME::OnSize( wxSizeEvent& aEvent )
580{
581#ifdef __WXMAC__
582 int currentDisplay = wxDisplay::GetFromWindow( this );
583
584 if( m_displayIndex >= 0 && currentDisplay >= 0 && currentDisplay != m_displayIndex )
585 {
586 wxLogTrace( traceDisplayLocation, wxS( "OnSize: current display changed %d to %d" ),
587 m_displayIndex, currentDisplay );
588 m_displayIndex = currentDisplay;
590 }
591#endif
592
593 aEvent.Skip();
594}
595
596
597void EDA_BASE_FRAME::LoadWindowState( const wxString& aFileName )
598{
599 if( !Pgm().GetCommonSettings()->m_Session.remember_open_files )
600 return;
601
602 const PROJECT_FILE_STATE* state = Prj().GetLocalSettings().GetFileState( aFileName );
603
604 if( state != nullptr )
605 {
606 LoadWindowState( state->window );
607 }
608}
609
610
612{
613 bool wasDefault = false;
614
615 m_framePos.x = aState.pos_x;
616 m_framePos.y = aState.pos_y;
617 m_frameSize.x = aState.size_x;
618 m_frameSize.y = aState.size_y;
619
620 wxLogTrace( traceDisplayLocation, wxS( "Config position (%d, %d) with size (%d, %d)" ),
622
623 // Ensure minimum size is set if the stored config was zero-initialized
624 if( m_frameSize.x < minSize( m_ident ).x || m_frameSize.y < minSize( m_ident ).y )
625 {
627 wasDefault = true;
628
629 wxLogTrace( traceDisplayLocation, wxS( "Using minimum size (%d, %d)" ),
631 }
632
633 wxLogTrace( traceDisplayLocation, wxS( "Number of displays: %d" ), wxDisplay::GetCount() );
634
635 if( aState.display >= wxDisplay::GetCount() )
636 {
637 wxLogTrace( traceDisplayLocation, wxS( "Previous display not found" ) );
638
639 // If it isn't attached, use the first display
640 // Warning wxDisplay has 2 ctor variants. the parameter needs a type:
641 const unsigned int index = 0;
642 wxDisplay display( index );
643 wxRect clientSize = display.GetGeometry();
644
645 m_framePos = wxDefaultPosition;
646
647 // Ensure the window fits on the display, since the other one could have been larger
648 if( m_frameSize.x > clientSize.width )
649 m_frameSize.x = clientSize.width;
650
651 if( m_frameSize.y > clientSize.height )
652 m_frameSize.y = clientSize.height;
653 }
654 else
655 {
656 wxPoint upperRight( m_framePos.x + m_frameSize.x, m_framePos.y );
657 wxPoint upperLeft( m_framePos.x, m_framePos.y );
658
659 wxDisplay display( aState.display );
660 wxRect clientSize = display.GetClientArea();
661
662 int yLimTop = clientSize.y;
663 int yLimBottom = clientSize.y + clientSize.height;
664 int xLimLeft = clientSize.x;
665 int xLimRight = clientSize.x + clientSize.width;
666
667 if( upperLeft.x > xLimRight || // Upper left corner too close to right edge of screen
668 upperRight.x < xLimLeft || // Upper right corner too close to left edge of screen
669 upperLeft.y < yLimTop || // Upper corner too close to the bottom of the screen
670 upperLeft.y > yLimBottom )
671 {
672 m_framePos = wxDefaultPosition;
673 wxLogTrace( traceDisplayLocation, wxS( "Resetting to default position" ) );
674 }
675 }
676
677 wxLogTrace( traceDisplayLocation, wxS( "Final window position (%d, %d) with size (%d, %d)" ),
679
680 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
681
682 // Center the window if we reset to default
683 if( m_framePos.x == -1 )
684 {
685 wxLogTrace( traceDisplayLocation, wxS( "Centering window" ) );
686 Center();
687 m_framePos = GetPosition();
688 }
689
690 // Record the frame sizes in an un-maximized state
693
694 // Maximize if we were maximized before
695 if( aState.maximized || ( wasDefault && m_maximizeByDefault ) )
696 {
697 wxLogTrace( traceDisplayLocation, wxS( "Maximizing window" ) );
698 Maximize();
699 }
700
701 m_displayIndex = wxDisplay::GetFromWindow( this );
702}
703
704
706{
707 wxDisplay display( wxDisplay::GetFromWindow( this ) );
708 wxRect clientSize = display.GetClientArea();
709 wxPoint pos = GetPosition();
710 wxSize size = GetWindowSize();
711
712 wxLogTrace( traceDisplayLocation,
713 wxS( "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d" ),
714 clientSize.x, clientSize.y,
715 clientSize.width, clientSize.height );
716
717 if( pos.y < clientSize.y )
718 {
719 wxLogTrace( traceDisplayLocation,
720 wxS( "ensureWindowIsOnScreen: y pos %d below minimum, setting to %d" ), pos.y,
721 clientSize.y );
722 pos.y = clientSize.y;
723 }
724
725 if( pos.x < clientSize.x )
726 {
727 wxLogTrace( traceDisplayLocation,
728 wxS( "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d" ),
729 pos.x, clientSize.x );
730 pos.x = clientSize.x;
731 }
732
733 if( pos.x + size.x - clientSize.x > clientSize.width )
734 {
735 int newWidth = clientSize.width - ( pos.x - clientSize.x );
736 wxLogTrace( traceDisplayLocation,
737 wxS( "ensureWindowIsOnScreen: effective width %d above available %d, setting "
738 "to %d" ), pos.x + size.x, clientSize.width, newWidth );
739 size.x = newWidth;
740 }
741
742 if( pos.y + size.y - clientSize.y > clientSize.height )
743 {
744 int newHeight = clientSize.height - ( pos.y - clientSize.y );
745 wxLogTrace( traceDisplayLocation,
746 wxS( "ensureWindowIsOnScreen: effective height %d above available %d, setting "
747 "to %d" ), pos.y + size.y, clientSize.height, newHeight );
748 size.y = newHeight;
749 }
750
751 wxLogTrace( traceDisplayLocation, wxS( "Updating window position (%d, %d) with size (%d, %d)" ),
752 pos.x, pos.y, size.x, size.y );
753
754 SetSize( pos.x, pos.y, size.x, size.y );
755}
756
757
759{
760 LoadWindowState( aCfg->state );
761
763 m_mruPath = aCfg->mru_path;
764
766}
767
768
770{
771 if( IsIconized() )
772 return;
773
774 // If the window is maximized, we use the saved window size from before it was maximized
775 if( IsMaximized() )
776 {
779 }
780 else
781 {
783 m_framePos = GetPosition();
784 }
785
786 aCfg->state.pos_x = m_framePos.x;
787 aCfg->state.pos_y = m_framePos.y;
788 aCfg->state.size_x = m_frameSize.x;
789 aCfg->state.size_y = m_frameSize.y;
790 aCfg->state.maximized = IsMaximized();
791 aCfg->state.display = wxDisplay::GetFromWindow( this );
792
793 wxLogTrace( traceDisplayLocation, wxS( "Saving window maximized: %s" ),
794 IsMaximized() ? wxS( "true" ) : wxS( "false" ) );
795 wxLogTrace( traceDisplayLocation, wxS( "Saving config position (%d, %d) with size (%d, %d)" ),
797
798 // Once this is fully implemented, wxAuiManager will be used to maintain
799 // the persistence of the main frame and all it's managed windows and
800 // all of the legacy frame persistence position code can be removed.
801 aCfg->perspective = m_auimgr.SavePerspective().ToStdString();
802
803 aCfg->mru_path = m_mruPath;
804}
805
806
808{
810
811 // Get file history size from common settings
812 int fileHistorySize = Pgm().GetCommonSettings()->m_System.file_history_size;
813
814 // Load the recently used files into the history menu
815 m_fileHistory = new FILE_HISTORY( (unsigned) std::max( 0, fileHistorySize ),
817 m_fileHistory->Load( *aCfg );
818}
819
820
822{
823 wxCHECK( config(), /* void */ );
824
826
827 bool fileOpen = m_isClosing && m_isNonUserClose;
828
829 wxString currentlyOpenedFile = GetCurrentFileName();
830
831 if( Pgm().GetCommonSettings()->m_Session.remember_open_files && !currentlyOpenedFile.IsEmpty() )
832 {
833 wxFileName rfn( currentlyOpenedFile );
834 rfn.MakeRelativeTo( Prj().GetProjectPath() );
835 Prj().GetLocalSettings().SaveFileState( rfn.GetFullPath(), &aCfg->m_Window, fileOpen );
836 }
837
838 // Save the recently used files list
839 if( m_fileHistory )
840 {
841 // Save the currently opened file in the file history
842 if( !currentlyOpenedFile.IsEmpty() )
843 UpdateFileHistory( currentlyOpenedFile );
844
845 m_fileHistory->Save( *aCfg );
846 }
847}
848
849
851{
852 return &aCfg->m_Window;
853}
854
855
857{
858 // KICAD_MANAGER_FRAME overrides this
859 return Kiface().KifaceSettings();
860}
861
862
864{
865 return Kiface().KifaceSearch();
866}
867
868
870{
871 return Kiface().GetHelpFileName();
872}
873
874
875void EDA_BASE_FRAME::PrintMsg( const wxString& text )
876{
877 SetStatusText( text );
878}
879
880
882{
883#if defined( __WXOSX_MAC__ )
885#else
886 m_infoBar = new WX_INFOBAR( this, &m_auimgr );
887
888 m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) ).Top().Layer(1) );
889#endif
890}
891
892
894{
895#if defined( __WXOSX_MAC__ )
896 m_auimgr.Update();
897#else
898 // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
899 // hiding it.
900 m_auimgr.Update();
901
902 // We don't want the infobar displayed right away
903 m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
904 m_auimgr.Update();
905#endif
906}
907
908
909void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
911{
913
914 if( aShowCloseButton )
916
917 GetInfoBar()->ShowMessageFor( aErrorMsg, 8000, wxICON_ERROR, aType );
918}
919
920
921void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
922 std::function<void(void)> aCallback )
923{
925
926 if( aShowCloseButton )
928
929 if( aCallback )
930 m_infoBar->SetCallback( aCallback );
931
932 GetInfoBar()->ShowMessageFor( aErrorMsg, 6000, wxICON_ERROR );
933}
934
935
936void EDA_BASE_FRAME::ShowInfoBarWarning( const wxString& aWarningMsg, bool aShowCloseButton )
937{
939
940 if( aShowCloseButton )
942
943 GetInfoBar()->ShowMessageFor( aWarningMsg, 6000, wxICON_WARNING );
944}
945
946
947void EDA_BASE_FRAME::ShowInfoBarMsg( const wxString& aMsg, bool aShowCloseButton )
948{
950
951 if( aShowCloseButton )
953
954 GetInfoBar()->ShowMessageFor( aMsg, 8000, wxICON_INFORMATION );
955}
956
957
958void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory )
959{
960 if( !aFileHistory )
961 aFileHistory = m_fileHistory;
962
963 wxASSERT( aFileHistory );
964
965 aFileHistory->AddFileToHistory( FullFileName );
966
967 // Update the menubar to update the file history menu
968 if( !m_isClosing && GetMenuBar() )
969 {
971 GetMenuBar()->Refresh();
972 }
973}
974
975
976wxString EDA_BASE_FRAME::GetFileFromHistory( int cmdId, const wxString& type,
977 FILE_HISTORY* aFileHistory )
978{
979 if( !aFileHistory )
980 aFileHistory = m_fileHistory;
981
982 wxASSERT( aFileHistory );
983
984 int baseId = aFileHistory->GetBaseId();
985
986 wxASSERT( cmdId >= baseId && cmdId < baseId + (int) aFileHistory->GetCount() );
987
988 unsigned i = cmdId - baseId;
989
990 if( i < aFileHistory->GetCount() )
991 {
992 wxString fn = aFileHistory->GetHistoryFile( i );
993
994 if( wxFileName::FileExists( fn ) )
995 {
996 return fn;
997 }
998 else
999 {
1000 DisplayErrorMessage( this, wxString::Format( _( "File '%s' was not found." ), fn ) );
1001 aFileHistory->RemoveFileFromHistory( i );
1002 }
1003 }
1004
1005 // Update the menubar to update the file history menu
1006 if( GetMenuBar() )
1007 {
1009 GetMenuBar()->Refresh();
1010 }
1011
1012 return wxEmptyString;
1013}
1014
1015
1017{
1018 if( !aFileHistory )
1019 aFileHistory = m_fileHistory;
1020
1021 wxASSERT( aFileHistory );
1022
1023 aFileHistory->ClearFileHistory();
1024
1025 // Update the menubar to update the file history menu
1026 if( GetMenuBar() )
1027 {
1029 GetMenuBar()->Refresh();
1030 }
1031}
1032
1033
1034void EDA_BASE_FRAME::OnKicadAbout( wxCommandEvent& event )
1035{
1036 void ShowAboutDialog( EDA_BASE_FRAME * aParent ); // See AboutDialog_main.cpp
1037 ShowAboutDialog( this );
1038}
1039
1040
1041void EDA_BASE_FRAME::OnPreferences( wxCommandEvent& event )
1042{
1043 ShowPreferences( wxEmptyString, wxEmptyString );
1044}
1045
1046
1047void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParentPage )
1048{
1049 wxBeginBusyCursor( wxHOURGLASS_CURSOR );
1050
1051 PAGED_DIALOG dlg( this, _( "Preferences" ), true, true, wxEmptyString, wxSize( 980, 560 ) );
1052
1053 dlg.SetEvtHandlerEnabled( false );
1054
1055 WX_TREEBOOK* book = dlg.GetTreebook();
1056 PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( this, book, false );
1057 KIFACE* kiface = nullptr;
1058 std::vector<int> expand;
1059
1060 Kiway().GetActions( hotkeysPanel->ActionsList() );
1061
1062 book->AddLazyPage(
1063 []( wxWindow* aParent ) -> wxWindow*
1064 {
1065 return new PANEL_COMMON_SETTINGS( aParent );
1066 },
1067 _( "Common" ) );
1068
1069 book->AddLazyPage(
1070 []( wxWindow* aParent ) -> wxWindow*
1071 {
1072 return new PANEL_MOUSE_SETTINGS( aParent );
1073 }, _( "Mouse and Touchpad" ) );
1074
1075 book->AddPage( hotkeysPanel, _( "Hotkeys" ) );
1076
1077// This currently allows pre-defined repositories that we
1078// don't use, so keep it disabled at the moment
1079if( ADVANCED_CFG::GetCfg().m_EnableGit && false )
1080 book->AddLazyPage(
1081 []( wxWindow* aParent ) -> wxWindow*
1082 {
1083 return new PANEL_GIT_REPOS( aParent );
1084 }, _( "Version Control" ) );
1085
1086#ifdef KICAD_USE_SENTRY
1087 book->AddLazyPage(
1088 []( wxWindow* aParent ) -> wxWindow*
1089 {
1090 return new PANEL_DATA_COLLECTION( aParent );
1091 }, _( "Data Collection" ) );
1092#endif
1093
1094#define LAZY_CTOR( key ) \
1095 [=]( wxWindow* aParent ) \
1096 { \
1097 return kiface->CreateKiWindow( aParent, key, &Kiway() ); \
1098 }
1099
1100 // If a dll is not loaded, the loader will show an error message.
1101
1102 try
1103 {
1105
1106 kiface->GetActions( hotkeysPanel->ActionsList() );
1107
1109 expand.push_back( (int) book->GetPageCount() );
1110
1111 book->AddPage( new wxPanel( book ), _( "Symbol Editor" ) );
1112 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_DISP_OPTIONS ), _( "Display Options" ) );
1113 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_GRIDS ), _( "Grids" ) );
1114 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_OPTIONS ), _( "Editing Options" ) );
1115 book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_COLORS ), _( "Colors" ) );
1116
1117 if( GetFrameType() == FRAME_SCH )
1118 expand.push_back( (int) book->GetPageCount() );
1119
1120 book->AddPage( new wxPanel( book ), _( "Schematic Editor" ) );
1121 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_DISP_OPTIONS ), _( "Display Options" ) );
1122 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_GRIDS ), _( "Grids" ) );
1123 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_EDIT_OPTIONS ), _( "Editing Options" ) );
1124 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_ANNO_OPTIONS ), _( "Annotation Options" ) );
1125 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_COLORS ), _( "Colors" ) );
1126 book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_FIELD_NAME_TEMPLATES ), _( "Field Name Templates" ) );
1127 }
1128 catch( ... )
1129 {
1130 }
1131
1132 try
1133 {
1135
1136 kiface->GetActions( hotkeysPanel->ActionsList() );
1137
1139 expand.push_back( (int) book->GetPageCount() );
1140
1141 book->AddPage( new wxPanel( book ), _( "Footprint Editor" ) );
1142 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DISPLAY_OPTIONS ), _( "Display Options" ) );
1143 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_GRIDS ), _( "Grids" ) );
1144 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_ORIGINS_AXES ), _( "Origins & Axes" ) );
1145 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_EDIT_OPTIONS ), _( "Editing Options" ) );
1146 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_COLORS ), _( "Colors" ) );
1147 book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DEFAULT_VALUES ), _( "Default Values" ) );
1148
1150 expand.push_back( (int) book->GetPageCount() );
1151
1152 book->AddPage( new wxPanel( book ), _( "PCB Editor" ) );
1153 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_DISPLAY_OPTS ), _( "Display Options" ) );
1154 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_GRIDS ), _( "Grids" ) );
1155 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ORIGINS_AXES ), _( "Origins & Axes" ) );
1156 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_EDIT_OPTIONS ), _( "Editing Options" ) );
1157 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_COLORS ), _( "Colors" ) );
1158 book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ACTION_PLUGINS ), _( "Action Plugins" ) );
1159
1161 expand.push_back( (int) book->GetPageCount() );
1162
1163 book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
1164 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_DISPLAY_OPTIONS ), _( "General" ) );
1165 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_OPENGL ), _( "Realtime Renderer" ) );
1166 book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_RAYTRACING ), _( "Raytracing Renderer" ) );
1167 }
1168 catch( ... )
1169 {
1170 }
1171
1172 try
1173 {
1175
1176 kiface->GetActions( hotkeysPanel->ActionsList() );
1177
1178 if( GetFrameType() == FRAME_GERBER )
1179 expand.push_back( (int) book->GetPageCount() );
1180
1181 book->AddPage( new wxPanel( book ), _( "Gerber Viewer" ) );
1182 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
1183 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_COLORS ), _( "Colors" ) );
1184 book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
1185 }
1186 catch( ... )
1187 {
1188 }
1189
1190 try
1191 {
1193 kiface->GetActions( hotkeysPanel->ActionsList() );
1194
1195 if( GetFrameType() == FRAME_PL_EDITOR )
1196 expand.push_back( (int) book->GetPageCount() );
1197
1198 book->AddPage( new wxPanel( book ), _( "Drawing Sheet Editor" ) );
1199 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_DISPLAY_OPTIONS ), _( "Display Options" ) );
1200 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_GRIDS ), _( "Grids" ) );
1201 book->AddLazySubPage( LAZY_CTOR( PANEL_DS_COLORS ), _( "Colors" ) );
1202
1203 book->AddLazyPage(
1204 []( wxWindow* aParent ) -> wxWindow*
1205 {
1206 return new PANEL_PCM_SETTINGS( aParent );
1207 }, _( "Plugin and Content Manager" ) );
1208 }
1209 catch( ... )
1210 {
1211 }
1212
1213 // Update all of the action hotkeys. The process of loading the actions through
1214 // the KiFACE will only get us the default hotkeys
1215 ReadHotKeyConfigIntoActions( wxEmptyString, hotkeysPanel->ActionsList() );
1216
1217 for( size_t i = 0; i < book->GetPageCount(); ++i )
1218 book->GetPage( i )->Layout();
1219
1220 for( int page : expand )
1221 book->ExpandNode( page );
1222
1223 if( !aStartPage.IsEmpty() )
1224 dlg.SetInitialPage( aStartPage, aStartParentPage );
1225
1226 dlg.SetEvtHandlerEnabled( true );
1227 wxEndBusyCursor();
1228
1229 if( dlg.ShowModal() == wxID_OK )
1230 {
1231 // Update our grids that are cached in the tool
1233 Pgm().GetSettingsManager().Save();
1234 dlg.Kiway().CommonSettingsChanged( false, false );
1235 }
1236
1237#undef LAZY_CTOR
1238}
1239
1240
1241void EDA_BASE_FRAME::OnDropFiles( wxDropFilesEvent& aEvent )
1242{
1243 wxString* files = aEvent.GetFiles();
1244
1245 for( int nb = 0; nb < aEvent.GetNumberOfFiles(); nb++ )
1246 {
1247 const wxFileName fn = wxFileName( files[nb] );
1248 wxString ext = fn.GetExt();
1249
1250 // Alias all gerber files as GerberFileExtension
1251 if( IsGerberFileExtension( ext ) )
1252 ext = GerberFileExtension;
1253
1254 if( m_acceptedExts.find( ext.ToStdString() ) != m_acceptedExts.end() )
1255 m_AcceptedFiles.emplace_back( fn );
1256 }
1257
1259 m_AcceptedFiles.clear();
1260}
1261
1262
1264{
1265 for( const wxFileName& file : m_AcceptedFiles )
1266 {
1267 wxString fn = file.GetFullPath();
1268 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( file.GetExt() ), &fn );
1269 }
1270}
1271
1272
1273bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName, bool aVerbose )
1274{
1275 wxString msg;
1276 wxFileName fn = aFileName;
1277
1278 // Check for absence of a file path with a file name. Unfortunately KiCad
1279 // uses paths relative to the current project path without the ./ part which
1280 // confuses wxFileName. Making the file name path absolute may be less than
1281 // elegant but it solves the problem.
1282 if( fn.GetPath().IsEmpty() && fn.HasName() )
1283 fn.MakeAbsolute();
1284
1285 wxCHECK_MSG( fn.IsOk(), false,
1286 wxT( "File name object is invalid. Bad programmer!" ) );
1287 wxCHECK_MSG( !fn.GetPath().IsEmpty(), false,
1288 wxT( "File name object path <" ) + fn.GetFullPath() +
1289 wxT( "> is not set. Bad programmer!" ) );
1290
1291 if( fn.IsDir() && !fn.IsDirWritable() )
1292 {
1293 msg.Printf( _( "Insufficient permissions to folder '%s'." ), fn.GetPath() );
1294 }
1295 else if( !fn.FileExists() && !fn.IsDirWritable() )
1296 {
1297 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fn.GetFullPath() );
1298 }
1299 else if( fn.FileExists() && !fn.IsFileWritable() )
1300 {
1301 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fn.GetFullPath() );
1302 }
1303
1304 if( !msg.IsEmpty() )
1305 {
1306 if( aVerbose )
1307 DisplayErrorMessage( this, msg );
1308
1309 return false;
1310 }
1311
1312 return true;
1313}
1314
1315
1316void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
1317{
1318 if( !Pgm().IsGUI() )
1319 return;
1320
1321 wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
1322
1323 wxFileName autoSaveFileName = aFileName;
1324
1325 // Check for auto save file.
1326 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + aFileName.GetName() );
1327
1328 wxLogTrace( traceAutoSave,
1329 wxT( "Checking for auto save file " ) + autoSaveFileName.GetFullPath() );
1330
1331 if( !autoSaveFileName.FileExists() )
1332 return;
1333
1334 wxString msg = wxString::Format( _( "Well this is potentially embarrassing!\n"
1335 "It appears that the last time you were editing\n"
1336 "%s\n"
1337 "KiCad exited before saving.\n"
1338 "\n"
1339 "Do you wish to open the auto-saved file instead?" ),
1340 aFileName.GetFullName() );
1341
1342 int response = wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
1343 this );
1344
1345 // Make a backup of the current file, delete the file, and rename the auto save file to
1346 // the file name.
1347 if( response == wxYES )
1348 {
1349 // Preserve the permissions of the current file
1350 KIPLATFORM::IO::DuplicatePermissions( aFileName.GetFullPath(), autoSaveFileName.GetFullPath() );
1351
1352 if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
1353 {
1354 wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
1355 Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION, this );
1356 }
1357 }
1358 else
1359 {
1360 DeleteAutoSaveFile( aFileName );
1361 }
1362}
1363
1364
1365void EDA_BASE_FRAME::DeleteAutoSaveFile( const wxFileName& aFileName )
1366{
1367 if( !Pgm().IsGUI() )
1368 return;
1369
1370 wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
1371
1372 wxFileName autoSaveFn = aFileName;
1373 autoSaveFn.SetName( GetAutoSaveFilePrefix() + aFileName.GetName() );
1374
1375 if( autoSaveFn.FileExists() )
1376 {
1377 wxLogTrace( traceAutoSave, wxT( "Removing auto save file " ) + autoSaveFn.GetFullPath() );
1378 wxRemoveFile( autoSaveFn.GetFullPath() );
1379 }
1380}
1381
1382
1384{
1385 // This function should be overridden in child classes
1386 return false;
1387}
1388
1389
1391{
1392 wxAcceleratorEntry entries[1];
1393 entries[0].Set( wxACCEL_CTRL, int( 'Q' ), wxID_EXIT );
1394 wxAcceleratorTable accel( 1, entries );
1395 SetAcceleratorTable( accel );
1396}
1397
1398
1400{
1403}
1404
1405
1407{
1408 m_undoList.PushCommand( aNewitem );
1409
1410 // Delete the extra items, if count max reached
1411 if( m_undoRedoCountMax > 0 )
1412 {
1413 int extraitems = GetUndoCommandCount() - m_undoRedoCountMax;
1414
1415 if( extraitems > 0 )
1416 ClearUndoORRedoList( UNDO_LIST, extraitems );
1417 }
1418}
1419
1420
1422{
1423 m_redoList.PushCommand( aNewitem );
1424
1425 // Delete the extra items, if count max reached
1426 if( m_undoRedoCountMax > 0 )
1427 {
1428 int extraitems = GetRedoCommandCount() - m_undoRedoCountMax;
1429
1430 if( extraitems > 0 )
1431 ClearUndoORRedoList( REDO_LIST, extraitems );
1432 }
1433}
1434
1435
1437{
1438 return m_undoList.PopCommand();
1439}
1440
1441
1443{
1444 return m_redoList.PopCommand();
1445}
1446
1447
1449{
1450 if( GetUndoCommandCount() > 0 )
1451 return m_undoList.m_CommandsList.back()->GetDescription();
1452
1453 return wxEmptyString;
1454}
1455
1456
1458{
1459 if( GetRedoCommandCount() > 0 )
1460 return m_redoList.m_CommandsList.back()->GetDescription();
1461
1462 return wxEmptyString;
1463}
1464
1465
1467{
1468 m_autoSaveRequired = true;
1469}
1470
1471
1473{
1474 SetUserUnits( aUnits );
1476
1477 wxCommandEvent e( EDA_EVT_UNITS_CHANGED );
1478 e.SetInt( static_cast<int>( aUnits ) );
1479 e.SetClientData( this );
1480 ProcessEventLocally( e );
1481}
1482
1483
1484void EDA_BASE_FRAME::OnMaximize( wxMaximizeEvent& aEvent )
1485{
1486 // When we maximize the window, we want to save the old information
1487 // so that we can add it to the settings on next window load.
1488 // Contrary to the documentation, this event seems to be generated
1489 // when the window is also being unmaximized on OSX, so we only
1490 // capture the size information when we maximize the window when on OSX.
1491#ifdef __WXOSX__
1492 if( !IsMaximized() )
1493#endif
1494 {
1496 m_normalFramePos = GetPosition();
1497 wxLogTrace( traceDisplayLocation,
1498 "Maximizing window - Saving position (%d, %d) with size (%d, %d)",
1501 }
1502
1503 // Skip event to actually maximize the window
1504 aEvent.Skip();
1505}
1506
1507
1509{
1510#ifdef __WXGTK__
1511 wxSize winSize = GetSize();
1512
1513 // GTK includes the window decorations in the normal GetSize call,
1514 // so we have to use a GTK-specific sizing call that returns the
1515 // non-decorated window size.
1517 {
1518 int width = 0;
1519 int height = 0;
1520 GTKDoGetSize( &width, &height );
1521
1522 winSize.Set( width, height );
1523 }
1524#else
1525 wxSize winSize = GetSize();
1526#endif
1527
1528 return winSize;
1529}
1530
1531
1533{
1534 // Update the icon theme when the system theme changes and update the toolbars
1536 ThemeChanged();
1537
1538 // This isn't handled by ThemeChanged()
1539 if( GetMenuBar() )
1540 {
1541 // For icons in menus, icon scaling & hotkeys
1543 GetMenuBar()->Refresh();
1544 }
1545}
1546
1547
1548void EDA_BASE_FRAME::onSystemColorChange( wxSysColourChangedEvent& aEvent )
1549{
1550 // Call the handler to update the colors used in the frame
1552
1553 // Skip the change event to ensure the rest of the window controls get it
1554 aEvent.Skip();
1555}
1556
1557
1558void EDA_BASE_FRAME::onIconize( wxIconizeEvent& aEvent )
1559{
1560 // Call the handler
1561 handleIconizeEvent( aEvent );
1562
1563 // Skip the event.
1564 aEvent.Skip();
1565}
1566
1567
1568#ifdef _WIN32
1569WXLRESULT EDA_BASE_FRAME::MSWWindowProc( WXUINT message, WXWPARAM wParam, WXLPARAM lParam )
1570{
1571 // This will help avoid the menu keeping focus when the alt key is released
1572 // You can still trigger accelerators as long as you hold down alt
1573 if( message == WM_SYSCOMMAND )
1574 {
1575 if( wParam == SC_KEYMENU && ( lParam >> 16 ) <= 0 )
1576 return 0;
1577 }
1578
1579 return wxFrame::MSWWindowProc( message, wParam, lParam );
1580}
1581#endif
1582
1583
1592{
1593 ACTION_MENU* langsMenu = new ACTION_MENU( false, aControlTool );
1594 langsMenu->SetTitle( _( "Set Language" ) );
1595 langsMenu->SetIcon( BITMAPS::language );
1596
1597 wxString tooltip;
1598
1599 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
1600 {
1601 wxString label;
1602
1603 if( LanguagesList[ii].m_DoNotTranslate )
1604 label = LanguagesList[ii].m_Lang_Label;
1605 else
1606 label = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
1607
1608 wxMenuItem* item =
1609 new wxMenuItem( langsMenu,
1610 LanguagesList[ii].m_KI_Lang_Identifier, // wxMenuItem wxID
1611 label, tooltip, wxITEM_CHECK );
1612
1613 langsMenu->Append( item );
1614 }
1615
1616 // This must be done after the items are added
1617 aMasterMenu->Add( langsMenu );
1618}
void ShowAboutDialog(EDA_BASE_FRAME *aParent)
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:69
static TOOL_ACTION about
Definition: actions.h:193
static TOOL_ACTION reportBug
Cursor control event types.
Definition: actions.h:197
static TOOL_ACTION copy
Definition: actions.h:68
static TOOL_ACTION donate
Definition: actions.h:195
static TOOL_ACTION listHotKeys
Definition: actions.h:194
static TOOL_ACTION getInvolved
Definition: actions.h:196
static TOOL_ACTION undo
Definition: actions.h:65
static TOOL_ACTION redo
Definition: actions.h:66
static TOOL_ACTION cut
Definition: actions.h:67
static TOOL_ACTION gettingStarted
Definition: actions.h:191
static TOOL_ACTION help
Definition: actions.h:192
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:49
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:91
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:77
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
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.
Definition: app_settings.h:92
WINDOW_SETTINGS m_Window
Definition: app_settings.h:169
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:83
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
Returns 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
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 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()
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...
void OnKicadAbout(wxCommandEvent &event)
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.
wxSize m_normalFrameSize
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)
void ShowPreferences(wxString aStartPage, wxString aStartParentPage)
Displays the preferences and settings of all opened editors paged dialog, starting with a particular ...
void initExitKey()
Sets 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
void FinishAUIInitialization()
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)
Function AddMenuLanguageList creates a menu list for language choice, and add it as submenu to Master...
void SetMenuBar(wxMenuBar *menu_bar) override
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...
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.
void ClearFileHistory(FILE_HISTORY *aFileHistory=nullptr)
Removes all files from the file history.
std::map< int, UIUpdateHandler > m_uiUpdateMap
< Map containing the UI update handlers registered with wx for each action.
UNDO_REDO_CONTAINER m_redoList
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
FILE_HISTORY * m_fileHistory
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.
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)
Checks if aFileName can be written.
wxPoint m_normalFramePos
void OnMaximize(wxMaximizeEvent &aEvent)
virtual void OnDropFiles(wxDropFilesEvent &aEvent)
Handles event fired when a file is dropped to the window.
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associates files 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)
Fetches the file name from the file history list.
static wxString GetAutoSaveFilePrefix()
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.
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 NonUserClose() to indicate that the user did not request the current close.
void AddStandardHelpMenu(wxMenuBar *aMenuBar)
Adds the standard KiCad help menu to the menubar.
wxString m_mruPath
void ReCreateMenuBar()
Recreates 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...
Definition: file_history.h:43
void AddFileToHistory(const wxString &aFile) override
Adds a file to the history.
void ClearFileHistory()
Clear all entries from the file history.
void Save(APP_SETTINGS_BASE &aSettings)
Saves history into a JSON settings object.
void SetMaxFiles(size_t aMaxFiles)
Update the number of files that will be contained inside the file history.
void Load(const APP_SETTINGS_BASE &aSettings)
Loads history from a JSON settings object.
SEARCH_STACK & KifaceSearch()
Only for DSO specific 'non-library' files.
Definition: kiface_base.h:116
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
void GetActions(std::vector< TOOL_ACTION * > &aActions) const override
Append this Kiface's registered actions to the given list.
Definition: kiface_base.h:118
const wxString & GetHelpFileName() const
Return just the basename portion of the current help file.
Definition: kiface_base.h:112
A mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_holder.h:37
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
virtual void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition: kiway.cpp:637
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:202
@ FACE_SCH
eeschema DSO
Definition: kiway.h:286
@ FACE_PL_EDITOR
Definition: kiway.h:290
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:287
@ FACE_GERBVIEW
Definition: kiway.h:289
virtual void GetActions(std::vector< TOOL_ACTION * > &aActions) const
Append all registered actions to the given list.
Definition: kiway.cpp:562
WX_TREEBOOK * GetTreebook()
Definition: paged_dialog.h:39
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:140
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:172
Look for files in a number of paths.
Definition: search_stack.h:42
virtual wxWindow * GetToolCanvas() const =0
Canvas access.
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:165
virtual void ShowChangedLanguage()
TOOL_DISPATCHER * m_toolDispatcher
Definition: tools_holder.h:167
virtual SELECTION & GetCurrentSelection()
Get the current selection from the canvas area.
Definition: tools_holder.h:96
virtual void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged)
Notification event that some of the common (suite-wide) settings have changed.
int GetUIId() const
Definition: tool_action.h:339
@ REDRAW
Full drawing refresh.
Definition: tool_base.h:83
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Reset all tools (i.e.
void PushCommand(PICKED_ITEMS_LIST *aCommand)
PICKED_ITEMS_LIST * PopCommand()
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
void SetUserUnits(EDA_UNITS aUnits)
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:75
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:301
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.
Definition: wx_infobar.cpp:140
MESSAGE_TYPE
Sets the type of message for special handling if needed.
Definition: wx_infobar.h:93
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:187
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: wx_infobar.cpp:291
void SetCallback(std::function< void(void)> aCallback)
Provide a callback to be called when the infobar is dismissed (either by user action or timer).
Definition: wx_infobar.h:157
bool AddLazyPage(std::function< wxWindow *(wxWindow *aParent)> aLazyCtor, const wxString &text, bool bSelect=false, int imageId=NO_IMAGE)
Definition: wx_treebook.cpp:89
bool AddLazySubPage(std::function< wxWindow *(wxWindow *aParent)> aLazyCtor, const wxString &text, bool bSelect=false, int imageId=NO_IMAGE)
Definition: wx_treebook.cpp:96
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:305
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 defaultSize(FRAME_T aFrameType)
#define LAZY_CTOR(key)
wxDEFINE_EVENT(EDA_EVT_UNITS_CHANGED, wxCommandEvent)
wxWindow * findQuasiModalDialog(wxWindow *aParent)
#define DEFAULT_MAX_UNDO_ITEMS
std::function< void(wxUpdateUIEvent &) > UIUpdateHandler
This is the handler functor for the update UI events.
void SocketCleanup()
Definition: eda_dde.cpp:319
DDE server & client.
EDA_UNITS
Definition: eda_units.h:46
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:92
@ 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_SCH_FIELD_NAME_TEMPLATES
Definition: frame_type.h:82
@ PANEL_GBR_DISPLAY_OPTIONS
Definition: frame_type.h:102
@ PANEL_3DV_OPENGL
Definition: frame_type.h:99
@ PANEL_PCB_ORIGINS_AXES
Definition: frame_type.h:96
@ PANEL_PCB_EDIT_OPTIONS
Definition: frame_type.h:93
@ PANEL_SCH_DISP_OPTIONS
Definition: frame_type.h:77
@ PANEL_FP_DISPLAY_OPTIONS
Definition: frame_type.h:84
@ FRAME_SCH
Definition: frame_type.h:34
@ PANEL_DS_COLORS
Definition: frame_type.h:109
@ PANEL_PCB_COLORS
Definition: frame_type.h:94
@ PANEL_3DV_RAYTRACING
Definition: frame_type.h:100
@ PANEL_SYM_EDIT_OPTIONS
Definition: frame_type.h:74
@ PANEL_FP_GRIDS
Definition: frame_type.h:85
@ PANEL_SCH_EDIT_OPTIONS
Definition: frame_type.h:79
@ PANEL_FP_ORIGINS_AXES
Definition: frame_type.h:89
@ PANEL_SYM_DISP_OPTIONS
Definition: frame_type.h:72
@ PANEL_PCB_DISPLAY_OPTS
Definition: frame_type.h:91
@ PANEL_FP_COLORS
Definition: frame_type.h:87
@ PANEL_SYM_COLORS
Definition: frame_type.h:75
@ FRAME_PL_EDITOR
Definition: frame_type.h:59
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
@ FRAME_GERBER
Definition: frame_type.h:57
@ PANEL_DS_GRIDS
Definition: frame_type.h:108
@ FRAME_PCB_DISPLAY3D
Definition: frame_type.h:47
@ PANEL_FP_EDIT_OPTIONS
Definition: frame_type.h:86
@ PANEL_SCH_ANNO_OPTIONS
Definition: frame_type.h:80
@ PANEL_SCH_GRIDS
Definition: frame_type.h:78
@ PANEL_PCB_ACTION_PLUGINS
Definition: frame_type.h:95
@ PANEL_FP_DEFAULT_VALUES
Definition: frame_type.h:88
@ PANEL_3DV_DISPLAY_OPTIONS
Definition: frame_type.h:98
@ PANEL_DS_DISPLAY_OPTIONS
Definition: frame_type.h:107
@ PANEL_SCH_COLORS
Definition: frame_type.h:81
@ PANEL_GBR_COLORS
Definition: frame_type.h:105
@ PANEL_GBR_EXCELLON_OPTIONS
Definition: frame_type.h:104
@ KICAD_MAIN_FRAME_T
Definition: frame_type.h:68
bool m_EnableGit
When true, enable git integration.
bool IsGerberFileExtension(const wxString &ext)
const std::string GerberFileExtension
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)
Reads a hotkey config file into a list of actions.
@ ID_FILE_LIST_CLEAR
Definition: id.h:87
@ ID_FILE1
Definition: id.h:84
@ ID_AUTO_SAVE_TIMER
Definition: id.h:79
void RemoveShutdownBlockReason(wxWindow *aWindow)
Removes any shutdown block reason set.
Definition: gtk/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: gtk/io.cpp:39
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition: pgm_base.cpp:87
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
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:151
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.h:70
wxString m_Lang_Label
Labels used in menus.
Definition: pgm_base.h:73
struct WINDOW_STATE window
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:74
WINDOW_STATE state
Definition: app_settings.h:75
wxString mru_path
Definition: app_settings.h:76
wxString perspective
Definition: app_settings.h:77
Stores the window positioning/state.
Definition: app_settings.h:61
unsigned int display
Definition: app_settings.h:67
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
wxLogTrace helper definitions.