KiCad PCB EDA Suite
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 <stambaughw@gmail.com>
6  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <bitmaps.h>
27 #include <bitmap_store.h>
28 #include <dialog_shim.h>
31 #include <eda_dde.h>
32 #include <filehistory.h>
33 #include <id.h>
34 #include <kiface_i.h>
35 #include <menus_helpers.h>
36 #include <panel_hotkeys_editor.h>
37 #include <paths.h>
38 #include <confirm.h>
39 #include <pgm_base.h>
40 #include <settings/app_settings.h>
44 #include <tool/action_manager.h>
45 #include <tool/action_menu.h>
46 #include <tool/action_toolbar.h>
47 #include <tool/actions.h>
48 #include <tool/common_control.h>
49 #include <tool/tool_manager.h>
50 #include <tool/tool_dispatcher.h>
51 #include <trace_helpers.h>
52 #include <widgets/paged_dialog.h>
53 #include <widgets/infobar.h>
55 #include <wx/app.h>
56 #include <wx/config.h>
57 #include <wx/display.h>
58 #include <wx/stdpaths.h>
59 #include <wx/string.h>
60 #include <wx/treebook.h>
61 #include <kiplatform/app.h>
62 #include <kiplatform/ui.h>
63 
64 #include <functional>
65 
66 wxDEFINE_EVENT( UNITS_CHANGED, wxCommandEvent );
67 
68 
69 // Minimum window size
70 static const wxSize minSize( FRAME_T aFrameType )
71 {
72  switch( aFrameType )
73  {
74  case KICAD_MAIN_FRAME_T:
75  return wxSize( 406, 354 );
76 
77  default:
78  return wxSize( 500, 400 );
79  }
80 }
81 
82 
83 static const wxSize defaultSize( FRAME_T aFrameType )
84 {
85  switch( aFrameType )
86  {
87  case KICAD_MAIN_FRAME_T:
88  return wxSize( 850, 540 );
89 
90  default:
91  return wxSize( 1280, 720 );
92  }
93 }
94 
95 
96 BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
97  EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::OnKicadAbout )
98  EVT_MENU( wxID_PREFERENCES, EDA_BASE_FRAME::OnPreferences )
99 
100  EVT_CHAR_HOOK( EDA_BASE_FRAME::OnCharHook )
101  EVT_MENU_OPEN( EDA_BASE_FRAME::OnMenuEvent )
102  EVT_MENU_CLOSE( EDA_BASE_FRAME::OnMenuEvent )
103  EVT_MENU_HIGHLIGHT_ALL( EDA_BASE_FRAME::OnMenuEvent )
104  EVT_MOVE( EDA_BASE_FRAME::OnMove )
105  EVT_SIZE( EDA_BASE_FRAME::OnSize )
106  EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize )
107 
108  EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange )
109 END_EVENT_TABLE()
110 
111 
112 void EDA_BASE_FRAME::commonInit( FRAME_T aFrameType )
113 {
114  m_ident = aFrameType;
115  m_maximizeByDefault = false;
116  m_infoBar = nullptr;
117  m_settingsManager = nullptr;
118  m_fileHistory = nullptr;
119  m_hasAutoSave = false;
120  m_autoSaveState = false;
121  m_autoSaveInterval = -1;
122  m_undoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
123  m_userUnits = EDA_UNITS::MILLIMETRES;
124  m_isClosing = false;
125  m_isNonUserClose = false;
126  m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
127  m_mruPath = PATHS::GetDefaultUserProjectsPath();
128  m_frameSize = defaultSize( aFrameType );
129  m_displayIndex = -1;
130 
131  m_auimgr.SetArtProvider( new WX_AUI_DOCK_ART() );
132 
133  m_settingsManager = &Pgm().GetSettingsManager();
134 
135  // Set a reasonable minimal size for the frame
136  SetSizeHints( minSize( aFrameType ).x, minSize( aFrameType ).y, -1, -1, -1, -1 );
137 
138  // Store dimensions of the user area of the main window.
139  GetClientSize( &m_frameSize.x, &m_frameSize.y );
140 
141  Connect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
142  wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
143 
144  // hook wxEVT_CLOSE_WINDOW so we can call SaveSettings(). This function seems
145  // to be called before any other hook for wxCloseEvent, which is necessary.
146  Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
147 
148  initExitKey();
149 }
150 
151 
153  wxFrame(),
154  TOOLS_HOLDER(),
155  KIWAY_HOLDER( aKiway, KIWAY_HOLDER::FRAME )
156 {
157  commonInit( aFrameType );
158 }
159 
160 
161 EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
162  const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
163  long aStyle, const wxString& aFrameName, KIWAY* aKiway ) :
164  wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ),
165  TOOLS_HOLDER(),
166  KIWAY_HOLDER( aKiway, KIWAY_HOLDER::FRAME )
167 {
168  commonInit( aFrameType );
169 }
170 
171 
173 {
174  for( wxWindow* iter : GetChildren() )
175  {
176  DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( iter );
177 
178  if( dlg && dlg->IsQuasiModal() )
179  return dlg;
180  }
181 
182  // FIXME: CvPcb is currently implemented on top of KIWAY_PLAYER rather than DIALOG_SHIM,
183  // so we have to look for it separately.
184  if( m_ident == FRAME_SCH )
185  {
186  wxWindow* cvpcb = wxWindow::FindWindowByName( "CvpcbFrame" );
187 
188  if( cvpcb )
189  return cvpcb;
190  }
191 
192  return nullptr;
193 }
194 
195 
196 void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
197 {
198  // Don't allow closing when a quasi-modal is open.
199  wxWindow* quasiModal = findQuasiModalDialog();
200 
201  if( quasiModal )
202  {
203  // Raise and notify; don't give the user a warning regarding "quasi-modal dialogs"
204  // when they have no idea what those are.
205  quasiModal->Raise();
206  wxBell();
207 
208  if( event.CanVeto() )
209  event.Veto();
210 
211  return;
212  }
213 
214 
215  if( event.GetId() == wxEVT_QUERY_END_SESSION
216  || event.GetId() == wxEVT_END_SESSION )
217  {
218  // End session means the OS is going to terminate us
219  m_isNonUserClose = true;
220  }
221 
222  if( canCloseWindow( event ) )
223  {
224  m_isClosing = true;
225  APP_SETTINGS_BASE* cfg = config();
226 
227  if( cfg )
228  SaveSettings( cfg ); // virtual, wxFrame specific
229 
230  doCloseWindow();
231 
232  // Destroy (safe delete frame) this frame only in non modal mode.
233  // In modal mode, the caller will call Destroy().
234  if( !IsModal() )
235  Destroy();
236  }
237  else
238  {
239  if( event.CanVeto() )
240  event.Veto();
241  }
242 }
243 
244 
246 {
247  delete m_autoSaveTimer;
248  delete m_fileHistory;
249 
251 
252  SocketCleanup();
253 
255 }
256 
257 
258 bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent )
259 {
260 #ifdef __WXMAC__
261  // Apple in its infinite wisdom will raise a disabled window before even passing
262  // us the event, so we have no way to stop it. Instead, we have to catch an
263  // improperly ordered disabled window and quasi-modal dialog here and reorder
264  // them.
265  if( !IsEnabled() && IsActive() )
266  {
267  wxWindow* dlg = findQuasiModalDialog();
268  if( dlg )
269  dlg->Raise();
270  }
271 #endif
272 
273  if( !wxFrame::ProcessEvent( aEvent ) )
274  return false;
275 
276  if( IsShown() && m_hasAutoSave && IsActive() &&
278  {
279  if( !m_autoSaveState )
280  {
281  wxLogTrace( traceAutoSave, wxT( "Starting auto save timer." ) );
282  m_autoSaveTimer->Start( m_autoSaveInterval * 1000, wxTIMER_ONE_SHOT );
283  m_autoSaveState = true;
284  }
285  else if( m_autoSaveTimer->IsRunning() )
286  {
287  wxLogTrace( traceAutoSave, wxT( "Stopping auto save timer." ) );
288  m_autoSaveTimer->Stop();
289  m_autoSaveState = false;
290  }
291  }
292 
293  return true;
294 }
295 
296 
298 {
299  m_autoSaveInterval = aInterval;
300 
301  if( m_autoSaveTimer->IsRunning() )
302  {
303  if( m_autoSaveInterval > 0 )
304  {
305  m_autoSaveTimer->Start( m_autoSaveInterval * 1000, wxTIMER_ONE_SHOT );
306  }
307  else
308  {
309  m_autoSaveTimer->Stop();
310  m_autoSaveState = false;
311  }
312  }
313 }
314 
315 
316 void EDA_BASE_FRAME::onAutoSaveTimer( wxTimerEvent& aEvent )
317 {
318  if( !doAutoSave() )
319  m_autoSaveTimer->Start( m_autoSaveInterval * 1000, wxTIMER_ONE_SHOT );
320 }
321 
322 
324 {
325  wxCHECK_MSG( false, true, wxT( "Auto save timer function not overridden. Bad programmer!" ) );
326 }
327 
328 
329 void EDA_BASE_FRAME::OnCharHook( wxKeyEvent& aKeyEvent )
330 {
331  wxLogTrace( kicadTraceKeyEvent, "EDA_BASE_FRAME::OnCharHook %s", dump( aKeyEvent ) );
332 
333  // Key events can be filtered here.
334  // Currently no filtering is made.
335  aKeyEvent.Skip();
336 }
337 
338 
339 void EDA_BASE_FRAME::OnMenuEvent( wxMenuEvent& aEvent )
340 {
341  if( !m_toolDispatcher )
342  aEvent.Skip();
343  else
345 }
346 
347 
349 {
351  std::placeholders::_1,
352  this,
353  aConditions );
354 
355  m_uiUpdateMap[aID] = evtFunc;
356 
357  Bind( wxEVT_UPDATE_UI, evtFunc, aID );
358 }
359 
360 
362 {
363  const auto it = m_uiUpdateMap.find( aID );
364 
365  if( it == m_uiUpdateMap.end() )
366  return;
367 
368  Unbind( wxEVT_UPDATE_UI, it->second, aID );
369 }
370 
371 
372 void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
373  ACTION_CONDITIONS aCond )
374 {
375  bool checkRes = false;
376  bool enableRes = true;
377  bool showRes = true;
378  SELECTION& selection = aFrame->GetCurrentSelection();
379 
380  try
381  {
382  checkRes = aCond.checkCondition( selection );
383  enableRes = aCond.enableCondition( selection );
384  showRes = aCond.showCondition( selection );
385  }
386  catch( std::exception& )
387  {
388  // Something broke with the conditions, just skip the event.
389  aEvent.Skip();
390  return;
391  }
392 
393  aEvent.Enable( enableRes );
394  aEvent.Show( showRes );
395 
396  // wxWidgets 3.1.5+ includes a field in the event that says if the event supports being
397  // checked, since wxMenuItems don't want to be checked unless they actually are checkable
398 #if wxCHECK_VERSION( 3, 1, 5 )
399  if( aEvent.IsCheckable() )
400  aEvent.Check( checkRes );
401 #else
402  bool canCheck = true;
403 
404  // wxMenuItems don't want to be checked unless they actually are checkable, so we have to
405  // check to see if they can be and can't just universally apply a check in this event.
406  if( auto menu = dynamic_cast<wxMenu*>( aEvent.GetEventObject() ) )
407  canCheck = menu->FindItem( aEvent.GetId() )->IsCheckable();
408 
409  if( canCheck )
410  aEvent.Check( checkRes );
411 #endif
412 }
413 
414 
416 {
417  // Setup the conditions to check a language menu item
418  auto isCurrentLang =
419  [] ( const SELECTION& aSel, int aLangIdentifier )
420  {
421  return Pgm().GetSelectedLanguageIdentifier() == aLangIdentifier;
422  };
423 
424  for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
425  {
426  ACTION_CONDITIONS cond;
427  cond.Check( std::bind( isCurrentLang, std::placeholders::_1,
428  LanguagesList[ii].m_WX_Lang_Identifier ) );
429 
430  RegisterUIUpdateHandler( LanguagesList[ii].m_KI_Lang_Identifier, cond );
431  }
432 }
433 
434 
436 {
437 }
438 
439 
440 void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
441 {
442  COMMON_CONTROL* commonControl = m_toolManager->GetTool<COMMON_CONTROL>();
443  ACTION_MENU* helpMenu = new ACTION_MENU( false, commonControl );
444 
445  helpMenu->Add( ACTIONS::help );
446  helpMenu->Add( ACTIONS::gettingStarted );
447  helpMenu->Add( ACTIONS::listHotKeys );
448  helpMenu->Add( ACTIONS::getInvolved );
449  helpMenu->Add( ACTIONS::donate );
450  helpMenu->Add( ACTIONS::reportBug );
451 
452  helpMenu->AppendSeparator();
453  helpMenu->Add( _( "&About KiCad" ), "", wxID_ABOUT, BITMAPS::about );
454 
455  aMenuBar->Append( helpMenu, _( "&Help" ) );
456 }
457 
458 
460 {
462 
463  if( GetMenuBar() )
464  {
465  ReCreateMenuBar();
466  GetMenuBar()->Refresh();
467  }
468 }
469 
470 
471 void EDA_BASE_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
472 {
473  TOOLS_HOLDER::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
474 
475  COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
476 
477  if( m_fileHistory )
478  {
479  int historySize = settings->m_System.file_history_size;
480  m_fileHistory->SetMaxFiles( (unsigned) std::max( 0, historySize ) );
481  }
482 
483  if( GetBitmapStore()->ThemeChanged() )
484  {
485  ThemeChanged();
486  }
487 
488  if( GetMenuBar() )
489  {
490  // For icons in menus, icon scaling & hotkeys
491  ReCreateMenuBar();
492  GetMenuBar()->Refresh();
493  }
494 }
495 
496 
498 {
500 
501  // Update all the toolbars to have new icons
502  wxAuiPaneInfoArray panes = m_auimgr.GetAllPanes();
503 
504  for( size_t i = 0; i < panes.GetCount(); ++i )
505  {
506  if( ACTION_TOOLBAR* toolbar = dynamic_cast<ACTION_TOOLBAR*>( panes[i].window ) )
507  toolbar->RefreshBitmaps();
508  }
509 }
510 
511 
512 void EDA_BASE_FRAME::OnSize( wxSizeEvent& aEvent )
513 {
514 #ifdef __WXMAC__
515  int currentDisplay = wxDisplay::GetFromWindow( this );
516 
517  if( m_displayIndex >= 0 && currentDisplay >= 0 && currentDisplay != m_displayIndex )
518  {
519  wxLogTrace( traceDisplayLocation, "OnSize: current display changed %d to %d",
520  m_displayIndex, currentDisplay );
521  m_displayIndex = currentDisplay;
523  }
524 #endif
525 
526  aEvent.Skip();
527 }
528 
529 
530 void EDA_BASE_FRAME::LoadWindowState( const wxString& aFileName )
531 {
532  if( !Pgm().GetCommonSettings()->m_Session.remember_open_files )
533  return;
534 
535  const PROJECT_FILE_STATE* state = Prj().GetLocalSettings().GetFileState( aFileName );
536 
537  if( state != nullptr )
538  {
539  LoadWindowState( state->window );
540  }
541 }
542 
543 
545 {
546  bool wasDefault = false;
547 
548  m_framePos.x = aState.pos_x;
549  m_framePos.y = aState.pos_y;
550  m_frameSize.x = aState.size_x;
551  m_frameSize.y = aState.size_y;
552 
553  wxLogTrace( traceDisplayLocation, "Config position (%d, %d) with size (%d, %d)",
555 
556  // Ensure minimum size is set if the stored config was zero-initialized
557  if( m_frameSize.x < minSize( m_ident ).x || m_frameSize.y < minSize( m_ident ).y )
558  {
560  wasDefault = true;
561 
562  wxLogTrace( traceDisplayLocation, "Using minimum size (%d, %d)",
563  m_frameSize.x, m_frameSize.y );
564  }
565 
566  wxLogTrace( traceDisplayLocation, "Number of displays: %d", wxDisplay::GetCount() );
567 
568  if( aState.display >= wxDisplay::GetCount() )
569  {
570  wxLogTrace( traceDisplayLocation, "Previous display not found" );
571 
572  // If it isn't attached, use the first display
573  // Warning wxDisplay has 2 ctor variants. the parameter needs a type:
574  const unsigned int index = 0;
575  wxDisplay display( index );
576  wxRect clientSize = display.GetGeometry();
577 
578  m_framePos = wxDefaultPosition;
579 
580  // Ensure the window fits on the display, since the other one could have been larger
581  if( m_frameSize.x > clientSize.width )
582  m_frameSize.x = clientSize.width;
583 
584  if( m_frameSize.y > clientSize.height )
585  m_frameSize.y = clientSize.height;
586  }
587  else
588  {
589  wxPoint upperRight( m_framePos.x + m_frameSize.x, m_framePos.y );
590  wxPoint upperLeft( m_framePos.x, m_framePos.y );
591 
592  wxDisplay display( aState.display );
593  wxRect clientSize = display.GetClientArea();
594 
595  int yLimTop = clientSize.y;
596  int yLimBottom = clientSize.y + clientSize.height;
597  int xLimLeft = clientSize.x;
598  int xLimRight = clientSize.x + clientSize.width;
599 
600  if( upperLeft.x > xLimRight || // Upper left corner too close to right edge of screen
601  upperRight.x < xLimLeft || // Upper right corner too close to left edge of screen
602  upperLeft.y < yLimTop || // Upper corner too close to the bottom of the screen
603  upperLeft.y > yLimBottom )
604  {
605  m_framePos = wxDefaultPosition;
606  wxLogTrace( traceDisplayLocation, "Resetting to default position" );
607  }
608  }
609 
610  wxLogTrace( traceDisplayLocation, "Final window position (%d, %d) with size (%d, %d)",
612 
613  SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
614 
615  // Center the window if we reset to default
616  if( m_framePos.x == -1 )
617  {
618  wxLogTrace( traceDisplayLocation, "Centering window" );
619  Center();
620  m_framePos = GetPosition();
621  }
622 
623  // Record the frame sizes in an un-maximized state
626 
627  // Maximize if we were maximized before
628  if( aState.maximized || ( wasDefault && m_maximizeByDefault ) )
629  {
630  wxLogTrace( traceDisplayLocation, "Maximizing window" );
631  Maximize();
632  }
633 
634  m_displayIndex = wxDisplay::GetFromWindow( this );
635 }
636 
637 
639 {
640  wxDisplay display( wxDisplay::GetFromWindow( this ) );
641  wxRect clientSize = display.GetClientArea();
642  wxPoint pos = GetPosition();
643  wxSize size = GetWindowSize();
644 
645  wxLogTrace( traceDisplayLocation,
646  "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d", clientSize.x, clientSize.y,
647  clientSize.width, clientSize.height );
648 
649  if( pos.y < clientSize.y )
650  {
651  wxLogTrace( traceDisplayLocation,
652  "ensureWindowIsOnScreen: y pos %d below minimum, setting to %d", pos.y,
653  clientSize.y );
654  pos.y = clientSize.y;
655  }
656 
657  if( pos.x < clientSize.x )
658  {
659  wxLogTrace( traceDisplayLocation,
660  "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d", pos.x,
661  clientSize.x );
662  pos.x = clientSize.x;
663  }
664 
665  if( pos.x + size.x - clientSize.x > clientSize.width )
666  {
667  int newWidth = clientSize.width - ( pos.x - clientSize.x );
668  wxLogTrace( traceDisplayLocation,
669  "ensureWindowIsOnScreen: effective width %d above available %d, setting to %d",
670  pos.x + size.x, clientSize.width, newWidth );
671  size.x = newWidth;
672  }
673 
674  if( pos.y + size.y - clientSize.y > clientSize.height )
675  {
676  int newHeight = clientSize.height - ( pos.y - clientSize.y );
677  wxLogTrace( traceDisplayLocation,
678  "ensureWindowIsOnScreen: effective height %d above available %d, setting to %d",
679  pos.y + size.y, clientSize.height, newHeight );
680  size.y = newHeight;
681  }
682 
683  wxLogTrace( traceDisplayLocation, "Updating window position (%d, %d) with size (%d, %d)",
684  pos.x, pos.y, size.x, size.y );
685 
686  SetSize( pos.x, pos.y, size.x, size.y );
687 }
688 
689 
691 {
692  LoadWindowState( aCfg->state );
693 
694  if( m_hasAutoSave )
695  m_autoSaveInterval = Pgm().GetCommonSettings()->m_System.autosave_interval;
696 
697  m_perspective = aCfg->perspective;
698  m_mruPath = aCfg->mru_path;
699 
700  TOOLS_HOLDER::CommonSettingsChanged( false, false );
701 }
702 
703 
705 {
706  wxString text;
707 
708  if( IsIconized() )
709  return;
710 
711  wxString baseCfgName = ConfigBaseName();
712 
713  // If the window is maximized, we use the saved window size from before it was maximized
714  if( IsMaximized() )
715  {
718  }
719  else
720  {
722  m_framePos = GetPosition();
723  }
724 
725  aCfg->state.pos_x = m_framePos.x;
726  aCfg->state.pos_y = m_framePos.y;
727  aCfg->state.size_x = m_frameSize.x;
728  aCfg->state.size_y = m_frameSize.y;
729  aCfg->state.maximized = IsMaximized();
730  aCfg->state.display = wxDisplay::GetFromWindow( this );
731 
732  wxLogTrace( traceDisplayLocation, "Saving window maximized: %s",
733  IsMaximized() ? "true" : "false" );
734  wxLogTrace( traceDisplayLocation, "Saving config position (%d, %d) with size (%d, %d)",
736 
737  // TODO(JE) should auto-save in common settings be overwritten by every app?
738  if( m_hasAutoSave )
739  Pgm().GetCommonSettings()->m_System.autosave_interval = m_autoSaveInterval;
740 
741  // Once this is fully implemented, wxAuiManager will be used to maintain
742  // the persistence of the main frame and all it's managed windows and
743  // all of the legacy frame persistence position code can be removed.
744  aCfg->perspective = m_auimgr.SavePerspective().ToStdString();
745 
746  aCfg->mru_path = m_mruPath;
747 }
748 
749 
751 {
753 
754  // Get file history size from common settings
755  int fileHistorySize = Pgm().GetCommonSettings()->m_System.file_history_size;
756 
757  // Load the recently used files into the history menu
758  m_fileHistory = new FILE_HISTORY( (unsigned) std::max( 0, fileHistorySize ),
760  m_fileHistory->Load( *aCfg );
761 }
762 
763 
765 {
767 
768  bool fileOpen = m_isClosing && m_isNonUserClose;
769 
770  wxString currentlyOpenedFile = GetCurrentFileName();
771 
772  if( Pgm().GetCommonSettings()->m_Session.remember_open_files && !currentlyOpenedFile.IsEmpty() )
773  {
774  wxFileName rfn( currentlyOpenedFile );
775  rfn.MakeRelativeTo( Prj().GetProjectPath() );
776  Prj().GetLocalSettings().SaveFileState( rfn.GetFullPath(), &aCfg->m_Window, fileOpen );
777  }
778 
779  // Save the recently used files list
780  if( m_fileHistory )
781  {
782  // Save the currently opened file in the file history
783  if( !currentlyOpenedFile.IsEmpty() )
784  UpdateFileHistory( currentlyOpenedFile );
785 
786  m_fileHistory->Save( *aCfg );
787  }
788 }
789 
790 
792 {
793  return &aCfg->m_Window;
794 }
795 
796 
798 {
799  // KICAD_MANAGER_FRAME overrides this
800  return Kiface().KifaceSettings();
801 }
802 
803 
805 {
806  return Kiface().KifaceSearch();
807 }
808 
809 
811 {
812  return Kiface().GetHelpFileName();
813 }
814 
815 
816 void EDA_BASE_FRAME::PrintMsg( const wxString& text )
817 {
818  SetStatusText( text );
819 }
820 
821 
823 {
824 #if defined( __WXOSX_MAC__ )
826 #else
827  m_infoBar = new WX_INFOBAR( this, &m_auimgr );
828 
829  m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( "InfoBar" ).Top().Layer(1) );
830 #endif
831 }
832 
833 
835 {
836 #if defined( __WXOSX_MAC__ )
837  m_auimgr.Update();
838 #else
839  // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
840  // hiding it.
841  m_auimgr.Update();
842 
843  // We don't want the infobar displayed right away
844  m_auimgr.GetPane( "InfoBar" ).Hide();
845  m_auimgr.Update();
846 #endif
847 }
848 
849 
850 void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton )
851 {
853 
854  if( aShowCloseButton )
856 
857  GetInfoBar()->ShowMessageFor( aErrorMsg, 8000, wxICON_ERROR );
858 }
859 
860 
861 void EDA_BASE_FRAME::ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
862  std::function<void(void)> aCallback )
863 {
865 
866  if( aShowCloseButton )
868 
869  if( aCallback )
870  m_infoBar->SetCallback( aCallback );
871 
872  GetInfoBar()->ShowMessageFor( aErrorMsg, 6000, wxICON_ERROR );
873 }
874 
875 
876 void EDA_BASE_FRAME::ShowInfoBarWarning( const wxString& aWarningMsg, bool aShowCloseButton )
877 {
879 
880  if( aShowCloseButton )
882 
883  GetInfoBar()->ShowMessageFor( aWarningMsg, 6000, wxICON_WARNING );
884 }
885 
886 
887 void EDA_BASE_FRAME::ShowInfoBarMsg( const wxString& aMsg, bool aShowCloseButton )
888 {
890 
891  if( aShowCloseButton )
893 
894  GetInfoBar()->ShowMessageFor( aMsg, 8000, wxICON_INFORMATION );
895 }
896 
897 
898 void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory )
899 {
900  if( !aFileHistory )
901  aFileHistory = m_fileHistory;
902 
903  wxASSERT( aFileHistory );
904 
905  aFileHistory->AddFileToHistory( FullFileName );
906 
907  // Update the menubar to update the file history menu
908  if( !m_isClosing && GetMenuBar() )
909  {
910  ReCreateMenuBar();
911  GetMenuBar()->Refresh();
912  }
913 }
914 
915 
916 wxString EDA_BASE_FRAME::GetFileFromHistory( int cmdId, const wxString& type,
917  FILE_HISTORY* aFileHistory )
918 {
919  if( !aFileHistory )
920  aFileHistory = m_fileHistory;
921 
922  wxASSERT( aFileHistory );
923 
924  int baseId = aFileHistory->GetBaseId();
925 
926  wxASSERT( cmdId >= baseId && cmdId < baseId + (int) aFileHistory->GetCount() );
927 
928  unsigned i = cmdId - baseId;
929 
930  if( i < aFileHistory->GetCount() )
931  {
932  wxString fn = aFileHistory->GetHistoryFile( i );
933 
934  if( wxFileName::FileExists( fn ) )
935  {
936  return fn;
937  }
938  else
939  {
940  DisplayErrorMessage( this, wxString::Format( _( "File '%s' was not found." ), fn ) );
941  aFileHistory->RemoveFileFromHistory( i );
942  }
943  }
944 
945  // Update the menubar to update the file history menu
946  if( GetMenuBar() )
947  {
948  ReCreateMenuBar();
949  GetMenuBar()->Refresh();
950  }
951 
952  return wxEmptyString;
953 }
954 
955 
957 {
958  if( !aFileHistory )
959  aFileHistory = m_fileHistory;
960 
961  wxASSERT( aFileHistory );
962 
963  aFileHistory->ClearFileHistory();
964 
965  // Update the menubar to update the file history menu
966  if( GetMenuBar() )
967  {
968  ReCreateMenuBar();
969  GetMenuBar()->Refresh();
970  }
971 }
972 
973 
974 void EDA_BASE_FRAME::OnKicadAbout( wxCommandEvent& event )
975 {
976  void ShowAboutDialog( EDA_BASE_FRAME * aParent ); // See AboutDialog_main.cpp
977  ShowAboutDialog( this );
978 }
979 
980 
981 void EDA_BASE_FRAME::OnPreferences( wxCommandEvent& event )
982 {
983  PAGED_DIALOG dlg( this, _( "Preferences" ), true );
984  wxTreebook* book = dlg.GetTreebook();
985 
986  book->AddPage( new PANEL_COMMON_SETTINGS( &dlg, book ), _( "Common" ) );
987 
988  book->AddPage( new PANEL_MOUSE_SETTINGS( &dlg, book ), _( "Mouse and Touchpad" ) );
989 
990  PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( this, book, false );
991  book->AddPage( hotkeysPanel, _( "Hotkeys" ) );
992 
993  wxWindow* viewer3D = nullptr;
994 
995  for( unsigned i = 0; i < KIWAY_PLAYER_COUNT; ++i )
996  {
997  KIWAY_PLAYER* frame = dlg.Kiway().Player( (FRAME_T) i, false );
998 
999  if( frame )
1000  {
1001  frame->InstallPreferences( &dlg, hotkeysPanel );
1002 
1003  if( !viewer3D )
1004  viewer3D = wxFindWindowByName( QUALIFIED_VIEWER3D_FRAMENAME( frame ) );
1005  }
1006  }
1007 
1008  if( viewer3D )
1009  static_cast<EDA_BASE_FRAME*>( viewer3D )->InstallPreferences( &dlg, hotkeysPanel );
1010 
1011  // The Kicad manager frame is not a player so we have to add it by hand
1012  wxWindow* manager = wxFindWindowByName( KICAD_MANAGER_FRAME_NAME );
1013 
1014  if( manager )
1015  static_cast<EDA_BASE_FRAME*>( manager )->InstallPreferences( &dlg, hotkeysPanel );
1016 
1017  for( size_t i = 0; i < book->GetPageCount(); ++i )
1018  book->GetPage( i )->Layout();
1019 
1020  if( dlg.ShowModal() == wxID_OK )
1021  dlg.Kiway().CommonSettingsChanged( false, false );
1022 }
1023 
1024 
1025 bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName )
1026 {
1027  wxString msg;
1028  wxFileName fn = aFileName;
1029 
1030  // Check for absence of a file path with a file name. Unfortunately KiCad
1031  // uses paths relative to the current project path without the ./ part which
1032  // confuses wxFileName. Making the file name path absolute may be less than
1033  // elegant but it solves the problem.
1034  if( fn.GetPath().IsEmpty() && fn.HasName() )
1035  fn.MakeAbsolute();
1036 
1037  wxCHECK_MSG( fn.IsOk(), false,
1038  wxT( "File name object is invalid. Bad programmer!" ) );
1039  wxCHECK_MSG( !fn.GetPath().IsEmpty(), false,
1040  wxT( "File name object path <" ) + fn.GetFullPath() +
1041  wxT( "> is not set. Bad programmer!" ) );
1042 
1043  if( fn.IsDir() && !fn.IsDirWritable() )
1044  {
1045  msg.Printf( _( "Insufficient permissions to folder '%s'." ),
1046  fn.GetPath() );
1047  }
1048  else if( !fn.FileExists() && !fn.IsDirWritable() )
1049  {
1050  msg.Printf( _( "Insufficient permissions to save file '%s'." ),
1051  fn.GetFullName(), fn.GetPath() );
1052  }
1053  else if( fn.FileExists() && !fn.IsFileWritable() )
1054  {
1055  msg.Printf( _( "Insufficient permissions to save file '%s'." ),
1056  fn.GetFullPath() );
1057  }
1058 
1059  if( !msg.IsEmpty() )
1060  {
1061  wxMessageBox( msg );
1062  return false;
1063  }
1064 
1065  return true;
1066 }
1067 
1068 
1069 void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
1070 {
1071  wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
1072 
1073  wxFileName autoSaveFileName = aFileName;
1074 
1075  // Check for auto save file.
1076  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + aFileName.GetName() );
1077 
1078  wxLogTrace( traceAutoSave,
1079  wxT( "Checking for auto save file " ) + autoSaveFileName.GetFullPath() );
1080 
1081  if( !autoSaveFileName.FileExists() )
1082  return;
1083 
1084  wxString msg = wxString::Format( _(
1085  "Well this is potentially embarrassing!\n"
1086  "It appears that the last time you were editing the file\n"
1087  "\"%s\"\n"
1088  "it was not saved properly. Do you wish to restore the last saved edits you made?" ),
1089  aFileName.GetFullName()
1090  );
1091 
1092  int response = wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
1093  this );
1094 
1095  // Make a backup of the current file, delete the file, and rename the auto save file to
1096  // the file name.
1097  if( response == wxYES )
1098  {
1099  if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
1100  {
1101  wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
1102  Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION, this );
1103  }
1104  }
1105  else
1106  {
1107  wxLogTrace( traceAutoSave,
1108  wxT( "Removing auto save file " ) + autoSaveFileName.GetFullPath() );
1109 
1110  // Remove the auto save file when using the previous file as is.
1111  wxRemoveFile( autoSaveFileName.GetFullPath() );
1112  }
1113 }
1114 
1115 
1117 {
1118  // This function should be overridden in child classes
1119  return false;
1120 }
1121 
1122 
1124 {
1125  wxAcceleratorEntry entries[1];
1126  entries[0].Set( wxACCEL_CTRL, int( 'Q' ), wxID_EXIT );
1127  wxAcceleratorTable accel( 1, entries );
1128  SetAcceleratorTable( accel );
1129 }
1130 
1131 
1133 {
1136 }
1137 
1138 
1140 {
1141  m_undoList.PushCommand( aNewitem );
1142 
1143  // Delete the extra items, if count max reached
1144  if( m_undoRedoCountMax > 0 )
1145  {
1146  int extraitems = GetUndoCommandCount() - m_undoRedoCountMax;
1147 
1148  if( extraitems > 0 )
1149  ClearUndoORRedoList( UNDO_LIST, extraitems );
1150  }
1151 }
1152 
1153 
1155 {
1156  m_redoList.PushCommand( aNewitem );
1157 
1158  // Delete the extra items, if count max reached
1159  if( m_undoRedoCountMax > 0 )
1160  {
1161  int extraitems = GetRedoCommandCount() - m_undoRedoCountMax;
1162 
1163  if( extraitems > 0 )
1164  ClearUndoORRedoList( REDO_LIST, extraitems );
1165  }
1166 }
1167 
1168 
1170 {
1171  return m_undoList.PopCommand();
1172 }
1173 
1174 
1176 {
1177  return m_redoList.PopCommand();
1178 }
1179 
1180 
1182 {
1183  SetUserUnits( aUnits );
1185 
1186  wxCommandEvent e( UNITS_CHANGED );
1187  ProcessEventLocally( e );
1188 }
1189 
1190 
1191 void EDA_BASE_FRAME::OnMaximize( wxMaximizeEvent& aEvent )
1192 {
1193  // When we maximize the window, we want to save the old information
1194  // so that we can add it to the settings on next window load.
1195  // Contrary to the documentation, this event seems to be generated
1196  // when the window is also being unmaximized on OSX, so we only
1197  // capture the size information when we maximize the window when on OSX.
1198 #ifdef __WXOSX__
1199  if( !IsMaximized() )
1200 #endif
1201  {
1203  m_normalFramePos = GetPosition();
1204  wxLogTrace( traceDisplayLocation,
1205  "Maximizing window - Saving position (%d, %d) with size (%d, %d)",
1208  }
1209 
1210  // Skip event to actually maximize the window
1211  aEvent.Skip();
1212 }
1213 
1214 
1216 {
1217 #ifdef __WXGTK__
1218  // GTK includes the window decorations in the normal GetSize call,
1219  // so we have to use a GTK-specific sizing call that returns the
1220  // non-decorated window size.
1221  int width = 0;
1222  int height = 0;
1223  GTKDoGetSize( &width, &height );
1224 
1225  wxSize winSize( width, height );
1226 #else
1227  wxSize winSize = GetSize();
1228 #endif
1229 
1230  return winSize;
1231 }
1232 
1233 
1235 {
1236  // Update the icon theme when the system theme changes and update the toolbars
1237  if( GetBitmapStore()->ThemeChanged() )
1238  ThemeChanged();
1239 
1240  // This isn't handled by ThemeChanged()
1241  if( GetMenuBar() )
1242  {
1243  // For icons in menus, icon scaling & hotkeys
1244  ReCreateMenuBar();
1245  GetMenuBar()->Refresh();
1246  }
1247 }
1248 
1249 
1250 void EDA_BASE_FRAME::onSystemColorChange( wxSysColourChangedEvent& aEvent )
1251 {
1252  // Call the handler to update the colors used in the frame
1254 
1255  // Skip the change event to ensure the rest of the window controls get it
1256  aEvent.Skip();
1257 }
SELECTION_CONDITION showCondition
Returns true if the UI control should be shown.
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION)
Show the infobar with the provided message and icon for a specific period of time.
Definition: infobar.cpp:123
wxString mru_path
Definition: app_settings.h:84
virtual void HandleSystemColorChange()
Update the UI in response to a change in the system colors.
static TOOL_ACTION listHotKeys
Definition: actions.h:178
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition: pgm_base.cpp:70
void PrintMsg(const wxString &text)
A mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_holder.h:36
Define the structure of a toolbar with buttons that invoke ACTIONs.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:64
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
DDE server & client.
void SaveFileState(const wxString &aFileName, const WINDOW_SETTINGS *aWindowCfg, bool aOpen)
wxString m_mruPath
virtual void OnCharHook(wxKeyEvent &aKeyEvent)
Capture the key event before it is sent to the GUI.
virtual bool doAutoSave()
This should be overridden by the derived class to handle the auto save feature.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:265
bool m_isClosing
Set by NonUserClose() to indicate that the user did not request the current close.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
virtual APP_SETTINGS_BASE * config() const
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:48
This file is part of the common library.
void SaveWindowSettings(WINDOW_SETTINGS *aCfg)
Save window settings to the given settings object.
UNDO_REDO_CONTAINER m_undoList
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
void onSystemColorChange(wxSysColourChangedEvent &aEvent)
SELECTION_CONDITION enableCondition
Returns true if the UI control should be enabled.
void windowClosing(wxCloseEvent &event)
(with its unexpected name so it does not collide with the real OnWindowClose() function provided in d...
virtual void PushCommandToRedoList(PICKED_ITEMS_LIST *aItem)
Add a command to redo in the redo list.
SELECTION_CONDITION checkCondition
Returns true if the UI control should be checked.
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...
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.h:65
virtual bool isAutoSaveRequired() const
Return the auto save status of the application.
void Save(APP_SETTINGS_BASE &aSettings)
Saves history into a JSON settings object.
Definition: filehistory.cpp:67
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
void onAutoSaveTimer(wxTimerEvent &aEvent)
Handle the auto save timer event.
static TOOL_ACTION reportBug
Cursor control event types.
Definition: actions.h:181
virtual void doCloseWindow()
bool IsQuasiModal() const
Definition: dialog_shim.h:106
virtual void RegisterUIUpdateHandler(int aID, const ACTION_CONDITIONS &aConditions) override
Register a UI update handler for the control with ID aID.
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_i.h:92
const wxChar *const traceDisplayLocation
Flag to enable debug output of display positioning logic.
virtual void PushCommandToUndoList(PICKED_ITEMS_LIST *aItem)
Add a command to undo in the undo list.
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 ClearScaledBitmapCache()
Wipes out the scaled bitmap cache so that the icon theme can be changed.
Definition: bitmap.cpp:170
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:382
void Load(const APP_SETTINGS_BASE &aSettings)
Loads history from a JSON settings object.
Definition: filehistory.cpp:45
virtual void ShowChangedLanguage()
virtual int GetRedoCommandCount() const
wxPoint m_normalFramePos
void ChangeUserUnits(EDA_UNITS aUnits)
Look for files in a number of paths.
Definition: search_stack.h:41
virtual PICKED_ITEMS_LIST * PopCommandFromRedoList()
Return the last command to undo and remove it from list, nothing is deleted.
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:82
static TOOL_ACTION donate
Definition: actions.h:179
wxAuiManager m_auimgr
bool IsWritable(const wxFileName &aFileName)
Checks if aFileName can be written.
This class implements a file history object to store a list of files, that can then be added to a men...
Definition: filehistory.h:42
#define DEFAULT_MAX_UNDO_ITEMS
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
wxTimer * m_autoSaveTimer
void LoadWindowState(const wxString &aFileName)
PICKED_ITEMS_LIST * PopCommand()
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 ...
void ClearFileHistory()
Clear all entries from the file history.
std::function< void(wxUpdateUIEvent &) > UIUpdateHandler
This is the handler functor for the update UI events.
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...
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
wxString m_perspective
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:151
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetches the file name from the file history list.
void PushCommand(PICKED_ITEMS_LIST *aCommand)
void initExitKey()
Sets the common key-pair for exiting the application (Ctrl-Q) and ties it to the wxID_EXIT event id.
wxTreebook * GetTreebook()
Definition: paged_dialog.h:37
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...
void AddFileToHistory(const wxString &aFile) override
Adds a file to the history.
Definition: filehistory.cpp:96
SEARCH_STACK & KifaceSearch()
Only for DSO specific 'non-library' files.
Definition: kiface_i.h:113
wxWindow * findQuasiModalDialog()
void SocketCleanup()
Definition: eda_dde.cpp:313
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:81
const wxString & GetHelpFileName() const
Return just the basename portion of the current help file.
Definition: kiface_i.h:109
void ShowAboutDialog(EDA_BASE_FRAME *aParent)
wxString perspective
Definition: app_settings.h:85
void ensureWindowIsOnScreen()
wxSize m_normalFrameSize
void CheckForAutoSaveFile(const wxFileName &aFileName)
Check if an auto save file exists for aFileName and takes the appropriate action depending on the use...
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:99
virtual int GetUndoCommandCount() const
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
virtual wxWindow * GetToolCanvas() const =0
Canvas access.
static const wxSize defaultSize(FRAME_T aFrameType)
virtual void unitsChangeRefresh()
Called when when the units setting has changed to allow for any derived classes to handle refreshing ...
virtual void OnSize(wxSizeEvent &aEvent)
std::map< int, UIUpdateHandler > m_uiUpdateMap
Set by the close window event handler after frames are asked if they can close.
virtual void UnregisterUIUpdateHandler(int aID) override
Unregister a UI handler for a given ID that was registered using RegisterUIUpdateHandler.
EDA_BASE_FRAME(wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, KIWAY *aKiway)
void FinishAUIInitialization()
virtual const SEARCH_STACK & sys_search()
Return a SEARCH_STACK pertaining to entire program.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
struct WINDOW_STATE window
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
void AddStandardHelpMenu(wxMenuBar *aMenuBar)
Adds the standard KiCad help menu to the menubar.
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: infobar.h:152
virtual WINDOW_SETTINGS * GetWindowSettings(APP_SETTINGS_BASE *aCfg)
Return a pointer to the window settings for this frame.
virtual PICKED_ITEMS_LIST * PopCommandFromUndoList()
Return the last command to undo and remove it from list, nothing is deleted.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:260
#define _(s)
wxLogTrace helper definitions.
void OnKicadAbout(wxCommandEvent &event)
A holder to handle information on schematic or board items.
Handle actions that are shared between different applications.
Specialization of the wxAuiPaneInfo class for KiCad panels.
Stores the window positioning/state.
Definition: app_settings.h:68
UNDO_REDO_CONTAINER m_redoList
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:287
virtual bool canCloseWindow(wxCloseEvent &aCloseEvent)
wxDEFINE_EVENT(UNITS_CHANGED, wxCommandEvent)
TOOL_DISPATCHER * m_toolDispatcher
Definition: tools_holder.h:160
void ClearFileHistory(FILE_HISTORY *aFileHistory=nullptr)
Removes all files from the file history.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
virtual bool IsContentModified() const
Get if the contents of the frame have been modified since the last save.
const PROJECT_FILE_STATE * GetFileState(const wxString &aFileName)
virtual void OnMove(wxMoveEvent &aEvent)
EDA_UNITS
Definition: eda_units.h:38
static wxString GetAutoSaveFilePrefix()
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:130
A modified version of the wxInfoBar class that allows us to:
Definition: infobar.h:73
WINDOW_SETTINGS m_Window
Definition: app_settings.h:181
void SetMaxFiles(size_t aMaxFiles)
Update the number of files that will be contained inside the file history.
Definition: filehistory.cpp:85
void OnMaximize(wxMaximizeEvent &aEvent)
void SetAutoSaveInterval(int aInterval)
virtual void ThemeChanged()
Process light/dark theme change.
virtual SELECTION & GetCurrentSelection()
Get the current selection from the canvas area.
Definition: tools_holder.h:101
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:158
wxSize GetWindowSize()
Get the undecorated window size that can be used for restoring the window size.
see class PGM_BASE
wxString ConfigBaseName() override
Get the configuration base name.
WX_INFOBAR * m_infoBar
#define KICAD_MANAGER_FRAME_NAME
WINDOW_STATE state
Definition: app_settings.h:83
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
The base frame for deriving all KiCad main window classes.
void LoadWindowSettings(const WINDOW_SETTINGS *aCfg)
Load window settings from the given settings object.
void commonInit(FRAME_T aFrameType)
Collect common initialization functions used in all CTORs.
static TOOL_ACTION help
Definition: actions.h:177
const wxChar *const kicadTraceKeyEvent
Flag to enable wxKeyEvent debug tracing.
virtual wxString help_name()
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
virtual void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged)
Notification event that some of the common (suite-wide) settings have changed.
void OnPreferences(wxCommandEvent &event)
Displays the preferences and settings of all opened editors paged dialog.
virtual void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition: kiway.cpp:553
static const wxSize minSize(FRAME_T aFrameType)
WX_INFOBAR * GetInfoBar()
ACTION_CONDITIONS & Check(const SELECTION_CONDITION &aCondition)
void SetUserUnits(EDA_UNITS aUnits)
Definition: id.h:86
#define QUALIFIED_VIEWER3D_FRAMENAME(parent)
virtual void InstallPreferences(PAGED_DIALOG *, PANEL_HOTKEYS_EDITOR *)
Allow a frame to load its preference panels (if any) into the preferences dialog.
unsigned int display
Definition: app_settings.h:75
static TOOL_ACTION getInvolved
Definition: actions.h:180
static TOOL_ACTION gettingStarted
Definition: actions.h:176
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
virtual wxString GetCurrentFileName() const
Get the full filename + path of the currently opened file in the frame.
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
void RemoveShutdownBlockReason(wxWindow *aWindow)
Removes any shutdown block reason set.
Definition: gtk/app.cpp:78
FILE_HISTORY * m_fileHistory
void OnMenuEvent(wxMenuEvent &event)
The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu events aren't ...
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: infobar.cpp:277
virtual void ReCreateMenuBar()
Recreates the menu bar.
BITMAP_STORE * GetBitmapStore()
Definition: bitmap.cpp:93