KiCad PCB EDA Suite
Loading...
Searching...
No Matches
kicad_manager_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 CERN (www.cern.ch)
6 * Copyright (C) 2004-2023 KiCad Developers, see change_log.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 "kicad_id.h"
27#include "pcm.h"
28#include "pgm_kicad.h"
29#include "project_tree_pane.h"
31
32#include <advanced_config.h>
34#include <bitmaps.h>
35#include <build_version.h>
38#include <eda_base_frame.h>
39#include <executable_names.h>
40#include <file_history.h>
41#include <policy_keys.h>
42#include <gestfich.h>
43#include <kiplatform/app.h>
44#include <kiplatform/policy.h>
45#include <build_version.h>
46#include <kiway.h>
47#include <kiway_express.h>
48#include <launch_ext.h>
50#include <reporter.h>
52#include <sch_file_versions.h>
54#include <tool/action_manager.h>
55#include <tool/action_toolbar.h>
56#include <tool/common_control.h>
58#include <tool/tool_manager.h>
63#include <widgets/kistatusbar.h>
64#include <wx/ffile.h>
65#include <wx/filedlg.h>
66#include <wx/dnd.h>
67#include <wx/process.h>
68#include <atomic>
69#include <update_manager.h>
70
71
72#include <../pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h> // for SEXPR_BOARD_FILE_VERSION def
73
74
75#ifdef __WXMAC__
76#include <MacTypes.h>
77#include <ApplicationServices/ApplicationServices.h>
78#endif
79
80#include "kicad_manager_frame.h"
82
83
84#define SEP() wxFileName::GetPathSeparator()
85
86
87// Menubar and toolbar event table
88BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
89 // Window events
92
93 // Menu events
94 EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit )
103
104 // Range menu events
106 KICAD_MANAGER_FRAME::language_change )
107
109 EVT_MENU( ID_FILE_LIST_CLEAR, KICAD_MANAGER_FRAME::OnClearFileHistory )
110
111 // Special functions
112 EVT_MENU( ID_INIT_WATCHED_PATHS, KICAD_MANAGER_FRAME::OnChangeWatchedPaths )
113
114 // Drop files event
115 EVT_DROP_FILES( KICAD_MANAGER_FRAME::OnDropFiles )
116
117END_EVENT_TABLE()
118
119
120// See below the purpose of this include
121#include <wx/xml/xml.h>
122
123KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title,
124 const wxPoint& pos, const wxSize& size ) :
127 m_leftWin( nullptr ),
128 m_launcher( nullptr ),
129 m_mainToolBar( nullptr ),
130 m_lastToolbarIconSize( 0 )
131{
132 const int defaultLeftWinWidth = FromDIP( 250 );
133
134 m_active_project = false;
135 m_leftWinWidth = defaultLeftWinWidth; // Default value
136 m_aboutTitle = "KiCad";
137
138 // JPC: A very ugly hack to fix an issue on Linux: if the wxbase315u_xml_gcc_custom.so is
139 // used **only** in PCM, it is not found in some cases at run time.
140 // So just use it in the main module to avoid a not found issue
141 // wxbase315u_xml_gcc_custom shared object when launching Kicad
142 wxXmlDocument dummy;
143
144 // Create the status line (bottom of the frame). Left half is for project name; right half
145 // is for Reporter (currently used by archiver/unarchiver and PCM).
146 // Note: this is a KISTATUSBAR status bar. Therefore the specified number of fields
147 // is the extra number of fields, not the full field count.
148 // We need here 2 fields: the extra fiels to display the project name, and another field
149 // to display a info (specific to Windows) using the FIELD_OFFSET_BGJOB_TEXT id offset (=1)
150 // So the extra field count is 1
151 CreateStatusBar( 1 );
154 GetStatusBar()->SetFont( KIUI::GetStatusFont( this ) );
155
156 // Give an icon
157 wxIcon icon;
158 wxIconBundle icon_bundle;
159
160 if( IsNightlyVersion())
161 {
162 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 48 ) );
163 icon_bundle.AddIcon( icon );
164 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 128 ) );
165 icon_bundle.AddIcon( icon );
166 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 256 ) );
167 icon_bundle.AddIcon( icon );
168 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly_32 ) );
169 icon_bundle.AddIcon( icon );
170 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly_16 ) );
171 icon_bundle.AddIcon( icon );
172 }
173 else
174 {
175 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 48 ) );
176 icon_bundle.AddIcon( icon );
177 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 128 ) );
178 icon_bundle.AddIcon( icon );
179 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 256 ) );
180 icon_bundle.AddIcon( icon );
181 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_32 ) );
182 icon_bundle.AddIcon( icon );
183 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_16 ) );
184 icon_bundle.AddIcon( icon );
185 }
186
187 SetIcons( icon_bundle );
188
189 // Load the settings
190 LoadSettings( config() );
191
192 m_pcmButton = nullptr;
193 m_pcmUpdateCount = 0;
194
195 // Left window: is the box which display tree project
196 m_leftWin = new PROJECT_TREE_PANE( this );
197
198 setupTools();
199 setupUIConditions();
200
201 m_launcher = new PANEL_KICAD_LAUNCHER( this );
202
203 RecreateBaseLeftToolbar();
204 ReCreateMenuBar();
205
206 m_auimgr.SetManagedWindow( this );
207 m_auimgr.SetFlags( wxAUI_MGR_LIVE_RESIZE );
208
209 m_auimgr.AddPane( m_mainToolBar, EDA_PANE().VToolbar().Name( "MainToolbar" ).Left()
210 .Layer( 2 ) );
211
212 // BestSize() does not always set the actual pane size of m_leftWin to the required value.
213 // It happens when m_leftWin is too large (roughly > 1/3 of the kicad manager frame width.
214 // (Well, BestSize() sets the best size... not the window size)
215 // A trick is to use MinSize() to set the required pane width,
216 // and after give a reasonable MinSize value
217 m_auimgr.AddPane( m_leftWin, EDA_PANE().Palette().Name( "ProjectTree" ).Left().Layer( 1 )
218 .Caption( _( "Project Files" ) ).PaneBorder( false )
219 .MinSize( m_leftWinWidth, -1 ).BestSize( m_leftWinWidth, -1 ) );
220
221 m_auimgr.AddPane( m_launcher, EDA_PANE().Canvas().Name( "Launcher" ).Center()
222 .Caption( _( "Editors" ) ).PaneBorder( false )
223 .MinSize( m_launcher->GetBestSize() ) );
224
225 m_auimgr.Update();
226
227 // Now the actual m_leftWin size is set, give it a reasonable min width
228 m_auimgr.GetPane( m_leftWin ).MinSize( defaultLeftWinWidth, -1 );
229
230 wxSizer* mainSizer = GetSizer();
231
232 // Only fit the initial window size the first time KiCad is run.
233 if( mainSizer && config()->m_Window.state.size_x == 0 && config()->m_Window.state.size_y == 0 )
234 mainSizer->Fit( this );
235
236 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
237 SetTitle( wxT( "KiCad" ) );
238 else
239 SetTitle( wxString( "KiCad " ) + GetMajorMinorVersion() );
240
241 // Do not let the messages window have initial focus
242 m_leftWin->SetFocus();
243
244 // Init for dropping files
247
248 // Gerber files
249 // Note that all gerber files are aliased as GerberFileExtension
253
254 DragAcceptFiles( true );
255
256 // Ensure the window is on top
257 Raise();
258}
259
260
262{
264 Unbind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
265
268
269 // Shutdown all running tools
270 if( m_toolManager )
272
273 if( m_pcm )
274 m_pcm->StopBackgroundUpdate();
275
276 delete m_actions;
277 delete m_toolManager;
278 delete m_toolDispatcher;
279
280 m_auimgr.UnInit();
281}
282
283
284wxStatusBar* KICAD_MANAGER_FRAME::OnCreateStatusBar( int number, long style, wxWindowID id,
285 const wxString& name )
286{
287 return new KISTATUSBAR( number, this, id );
288}
289
290
292{
293 // creates the PLUGIN_CONTENT_MANAGER, if not exists
294 if( m_pcm )
295 return;
296
297 m_pcm = std::make_shared<PLUGIN_CONTENT_MANAGER>(
298 [this]( int aUpdateCount )
299 {
300 m_pcmUpdateCount = aUpdateCount;
301
302 if( aUpdateCount > 0 )
303 {
305 wxS( "pcm" ),
306 _( "PCM Updates Available" ),
307 wxString::Format( _( "%d package update(s) avaliable" ), aUpdateCount ),
308 wxT( "" ) );
309 }
310 else
311 {
312 Pgm().GetNotificationsManager().Remove( wxS( "pcm" ) );
313 }
314
315 CallAfter(
316 [this]()
317 {
319 } );
320 });
321
322 m_pcm->SetRepositoryList( kicadSettings()->m_PcmRepositories );
323}
324
325
327{
328 // Create the manager
330 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
332
334
335 // Attach the events to the tool dispatcher
337 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
338
339 // Register tools
343}
344
345
347{
349
351
352 wxASSERT( manager );
353
354 auto activeProject =
355 [this] ( const SELECTION& )
356 {
357 return m_active_project;
358 };
359
360#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
361
362 ACTION_CONDITIONS activeProjectCond;
363 activeProjectCond.Enable( activeProject );
364
365 manager->SetConditions( ACTIONS::saveAs, activeProjectCond );
366 manager->SetConditions( KICAD_MANAGER_ACTIONS::closeProject, activeProjectCond );
367
368 // These are just here for text boxes, search boxes, etc. in places such as the standard
369 // file dialogs.
373
374 // TODO: Switch this to an action
376
377#undef ENABLE
378}
379
380
382{
383 return m_leftWin;
384}
385
386
388{
390 wxASSERT( ret );
391 return ret;
392}
393
394
396{
397 KICAD_SETTINGS* ret = dynamic_cast<KICAD_SETTINGS*>( config() );
398 wxASSERT( ret );
399 return ret;
400}
401
402
404{
406 wxString( wxEmptyString );
407}
408
409
411{
412 wxFileName fn( GetProjectFileName() );
413
415 return fn.GetFullPath();
416}
417
418
420{
421 wxFileName fn( GetProjectFileName() );
422
424 return fn.GetFullPath();
425}
426
427
429{
430 wxFileName fn( GetProjectFileName() );
431
432 fn.SetExt( FILEEXT::PcbFileExtension );
433 return fn.GetFullPath();
434}
435
436
438{
439 wxFileName fn( GetProjectFileName() );
440
442 return fn.GetFullPath();
443}
444
445
447{
449}
450
451
453{
454 return PgmTop().SysSearch();
455}
456
457
459{
460 return PgmTop().GetHelpFileName();
461}
462
463
464void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
465{
466 if( m_auimgr.GetManagedWindow() )
467 m_auimgr.Update();
468
469 PrintPrjInfo();
470
471#if defined( _WIN32 )
472 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
474#endif
475
476 event.Skip();
477}
478
479
481{
482 // All fileNames are now in m_AcceptedFiles vector.
483 // Check if contains a project file name and load project.
484 // If not, open files in dedicated app.
485 for( const wxFileName& fileName : m_AcceptedFiles )
486 {
487 wxString ext = fileName.GetExt();
488
490 {
491 wxString fn = fileName.GetFullPath();
492 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
493
494 return;
495 }
496 }
497
498 // Then stock gerber files in gerberFiles and run action for other files.
499 wxString gerberFiles;
500
501 // Gerbview editor should be able to open Gerber and drill files
502 for( const wxFileName& fileName : m_AcceptedFiles )
503 {
504 wxString ext = fileName.GetExt();
505
508 {
509 gerberFiles += wxT( '\"' );
510 gerberFiles += fileName.GetFullPath() + wxT( '\"' );
511 gerberFiles = gerberFiles.Pad( 1 );
512 }
513 else
514 {
515 wxString fn = fileName.GetFullPath();
516 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
517 }
518 }
519
520 // Execute Gerbviewer
521 if( !gerberFiles.IsEmpty() )
522 {
523 wxString fullEditorName = FindKicadFile( GERBVIEW_EXE );
524
525 if( wxFileExists( fullEditorName ) )
526 {
527 wxString command = fullEditorName + " " + gerberFiles;
529 &command );
530 }
531 }
532}
533
534
535bool KICAD_MANAGER_FRAME::canCloseWindow( wxCloseEvent& aEvent )
536{
537 KICAD_SETTINGS* settings = kicadSettings();
539
540 // CloseProject will recursively ask all the open editors if they need to save changes.
541 // If any of them cancel then we need to cancel closing the KICAD_MANAGER_FRAME.
542 if( CloseProject( true ) )
543 {
544 // Don't propagate event to frames which have already been closed
545 aEvent.StopPropagation();
546
547 return true;
548 }
549 else
550 {
551 if( aEvent.CanVeto() )
552 aEvent.Veto();
553
554 return false;
555 }
556}
557
558
560{
561#ifdef _WINDOWS_
562 // For some obscure reason, on Windows, when killing Kicad from the Windows task manager
563 // if a editor frame (schematic, library, board editor or fp editor) is open and has
564 // some edition to save, OnCloseWindow is run twice *at the same time*, creating race
565 // conditions between OnCloseWindow() code.
566 // Therefore I added (JPC) a ugly hack to discard the second call (unwanted) during
567 // execution of the first call (only one call is right).
568 // Note also if there is no change made in editors, this behavior does not happen.
569 static std::atomic<unsigned int> lock_close_event( 0 );
570
571 if( ++lock_close_event > 1 ) // Skip extra calls
572 {
573 return;
574 }
575#endif
576
577 m_leftWin->Show( false );
578 Pgm().m_Quitting = true;
579
580 Destroy();
581
582#ifdef _WINDOWS_
583 lock_close_event = 0; // Reenable event management
584#endif
585}
586
587
588void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event )
589{
590 Close( true );
591}
592
593
595{
596 if( !Kiway().PlayersClose( false ) )
597 return false;
598
599 // Save the project file for the currently loaded project.
600 if( m_active_project )
601 {
603
605
606 if( aSave )
607 mgr.SaveProject();
608
609 m_active_project = false;
610 mgr.UnloadProject( &Prj() );
611 }
612
613 SetStatusText( "" );
614
616
617 return true;
618}
619
620
621void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
622{
623 // The project file should be valid by the time we get here or something has gone wrong.
624 if( !aProjectFileName.Exists() )
625 return;
626
627 // Any open KIFACE's must be closed if they are not part of the new project.
628 // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.)
629 // User is prompted here to close those KIWAY_PLAYERs:
630 if( !CloseProject( true ) )
631 return;
632
633 m_active_project = true;
634
635 Pgm().GetSettingsManager().LoadProject( aProjectFileName.GetFullPath() );
636
637 LoadWindowState( aProjectFileName.GetFullName() );
638
639 if( aProjectFileName.IsDirWritable() )
640 SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why?
641
642 // Save history & window state to disk now. Don't wait around for a crash.
643 KICAD_SETTINGS* settings = kicadSettings();
644 SaveSettings( settings );
645 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
646
648
649 // Rebuild the list of watched paths.
650 // however this is possible only when the main loop event handler is running,
651 // so we use it to run the rebuild function.
652 wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
653
654 wxPostEvent( this, cmd );
655
656 PrintPrjInfo();
657
658 KIPLATFORM::APP::RegisterApplicationRestart( aProjectFileName.GetFullPath() );
659 m_openSavedWindows = true;
660}
661
662
663void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName,
664 bool aCreateStubFiles )
665{
666 wxCHECK_RET( aProjectFileName.DirExists() && aProjectFileName.IsDirWritable(),
667 "Project folder must exist and be writable to create a new project." );
668
669 // If the project is legacy, convert it
670 if( !aProjectFileName.FileExists() )
671 {
672 wxFileName legacyPro( aProjectFileName );
673 legacyPro.SetExt( FILEEXT::LegacyProjectFileExtension );
674
675 if( legacyPro.FileExists() )
676 {
677 GetSettingsManager()->LoadProject( legacyPro.GetFullPath() );
679
680 wxRemoveFile( legacyPro.GetFullPath() );
681 }
682 else
683 {
684 // Copy template project file from template folder.
685 wxString srcFileName = sys_search().FindValidPath( "kicad.kicad_pro" );
686
687 wxFileName destFileName( aProjectFileName );
688 destFileName.SetExt( FILEEXT::ProjectFileExtension );
689
690 // Create a minimal project file if the template project file could not be copied
691 if( !wxFileName::FileExists( srcFileName )
692 || !wxCopyFile( srcFileName, destFileName.GetFullPath() ) )
693 {
694 wxFFile file( destFileName.GetFullPath(), "wb" );
695
696 if( file.IsOpened() )
697 file.Write( wxT( "{\n}\n") );
698
699 // wxFFile dtor will close the file
700 }
701 }
702 }
703
704 // Create a "stub" for a schematic root sheet and a board if requested.
705 // It will avoid messages from the schematic editor or the board editor to create a new file
706 // And forces the user to create main files under the right name for the project manager
707 if( aCreateStubFiles )
708 {
709 wxFileName fn( aProjectFileName.GetFullPath() );
711
712 // If a <project>.kicad_sch file does not exist, create a "stub" file ( minimal schematic
713 // file ).
714 if( !fn.FileExists() )
715 {
716 wxFFile file( fn.GetFullPath(), "wb" );
717
718 if( file.IsOpened() )
719 file.Write( wxString::Format( "(kicad_sch (version %d) (generator \"eeschema\") (generator_version \"%s\")\n"
720 " (paper \"A4\")\n (lib_symbols)\n"
721 " (symbol_instances)\n)\n",
723
724 // wxFFile dtor will close the file
725 }
726
727 // If a <project>.kicad_pcb or <project>.brd file does not exist,
728 // create a .kicad_pcb "stub" file
730 wxFileName leg_fn( fn );
731 leg_fn.SetExt( FILEEXT::LegacyPcbFileExtension );
732
733 if( !fn.FileExists() && !leg_fn.FileExists() )
734 {
735 wxFFile file( fn.GetFullPath(), "wb" );
736
737 if( file.IsOpened() )
738 // Create a small dummy file as a stub for pcbnew:
739 file.Write( wxString::Format( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n)",
741
742 // wxFFile dtor will close the file
743 }
744 }
745
746 // Save history & window state to disk now. Don't wait around for a crash.
747 KICAD_SETTINGS* settings = kicadSettings();
748 SaveSettings( settings );
749 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
750
751 m_openSavedWindows = true;
752}
753
754
756{
757 // show all files in file dialog (in Kicad all files are editable texts):
758 wxString wildcard = FILEEXT::AllFilesWildcard();
759
760 wxString default_dir = Prj().GetProjectPath();
761
762 wxFileDialog dlg( this, _( "Edit File in Text Editor" ), default_dir, wxEmptyString, wildcard,
763 wxFD_OPEN );
764
765 if( dlg.ShowModal() == wxID_CANCEL )
766 return;
767
768 wxString filename = dlg.GetPath();
769
770 if( !dlg.GetPath().IsEmpty() && !Pgm().GetTextEditor().IsEmpty() )
772}
773
774
776{
777 // open project directory in host OS's file explorer
778 LaunchExternal( Prj().GetProjectPath() );
779}
780
781
783{
785}
786
787
788void KICAD_MANAGER_FRAME::language_change( wxCommandEvent& event )
789{
790 int id = event.GetId();
791 Kiway().SetLanguage( id );
792}
793
794
796{
797 // call my base class
799
800 // tooltips in toolbars
803
804 PrintPrjInfo();
805}
806
807
808void KICAD_MANAGER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
809{
810 EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
811
812 if( m_pcm && aEnvVarsChanged )
813 {
814 m_pcm->ReadEnvVar();
815 }
816
817 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
818
819 if( m_lastToolbarIconSize == 0
821 {
824 }
825}
826
827
829{
830 wxString file = GetProjectFileName();
831 wxString title;
832
833 if( !file.IsEmpty() )
834 {
835 wxFileName fn( file );
836
837 title = fn.GetName();
838
839 if( !fn.IsDirWritable() )
840 title += wxS( " " ) + _( "[Read Only]" );
841 }
842 else
843 {
844 title = _( "[no project loaded]" );
845 }
846
847 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
848 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad" ) );
849 else
850 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad " ) ) + GetMajorMinorVersion();
851
852 SetTitle( title );
853}
854
855
857{
859
860 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
861
862 wxCHECK( settings, /*void*/ );
863
864 m_leftWinWidth = settings->m_LeftWinWidth;
865}
866
867
869{
871
872 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
873
874 wxCHECK( settings, /*void*/);
875
876 settings->m_LeftWinWidth = m_leftWin->GetSize().x;
877
878 if( !m_isClosing )
879 settings->m_OpenProjects = GetSettingsManager()->GetOpenProjects();
880}
881
882
884{
885 // wxStatusBar's wxELLIPSIZE_MIDDLE flag doesn't work (at least on Mac).
886
887 wxString status = wxString::Format( _( "Project: %s" ), Prj().GetProjectFullName() );
888 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
889 statusBar->SetEllipsedTextField( status, 0 );
890}
891
892
894{
895 return m_active_project;
896}
897
898
899void KICAD_MANAGER_FRAME::OnIdle( wxIdleEvent& aEvent )
900{
906 if( !m_openSavedWindows )
907 return;
908
909 m_openSavedWindows = false;
910
911 if( Pgm().GetCommonSettings()->m_Session.remember_open_files )
912 {
913 int previousOpenCount =
914 std::count_if( Prj().GetLocalSettings().m_files.begin(),
915 Prj().GetLocalSettings().m_files.end(),
916 [&]( const PROJECT_FILE_STATE& f )
917 {
918 return !f.fileName.EndsWith( FILEEXT::ProjectFileExtension ) && f.open;
919 } );
920
921 if( previousOpenCount > 0 )
922 {
923 APP_PROGRESS_DIALOG progressReporter( _( "Restoring session" ), wxEmptyString,
924 previousOpenCount, this );
925
926 // We don't currently support opening more than one view per file
927 std::set<wxString> openedFiles;
928
929 int i = 0;
930
931 for( const PROJECT_FILE_STATE& file : Prj().GetLocalSettings().m_files )
932 {
933 if( file.open && !openedFiles.count( file.fileName ) )
934 {
935 progressReporter.Update( i++,
936 wxString::Format( _( "Restoring '%s'" ), file.fileName ) );
937
938 openedFiles.insert( file.fileName );
939 wxFileName fn( file.fileName );
940
942 || fn.GetExt() == FILEEXT::KiCadSchematicFileExtension )
943 {
945 }
946 else if( fn.GetExt() == FILEEXT::LegacyPcbFileExtension
947 || fn.GetExt() == FILEEXT::KiCadPcbFileExtension )
948 {
950 }
951 }
952
953 wxYield();
954 }
955 }
956 }
957
958 // clear file states regardless if we opened windows or not due to setting
960
961 KICAD_SETTINGS* settings = kicadSettings();
962
963 if( !Pgm().GetCommonSettings()->m_DoNotShowAgain.update_check_prompt )
964 {
965 auto prompt = new DIALOG_UPDATE_CHECK_PROMPT( this );
966 prompt->ShowModal();
967
969 }
970
972 && settings->m_PcmUpdateCheck )
973 {
974 if( !m_pcm )
975 CreatePCM();
976
977 m_pcm->RunBackgroundUpdate();
978 }
979
980#ifdef KICAD_UPDATE_CHECK
981 if( !m_updateManager && settings->m_KiCadUpdateCheck )
982 {
983 m_updateManager = std::make_unique<UPDATE_MANAGER>();
984 m_updateManager->CheckForUpdate( this );
985 }
986#endif
987}
988
989
991{
992 m_pcmButton = aButton;
993
995}
996
997
999{
1000 if( m_pcmButton )
1001 {
1002 if( m_pcmUpdateCount > 0 )
1003 {
1004 m_pcmButton->SetShowBadge( true );
1005 m_pcmButton->SetBadgeText( wxString::Format( "%d", m_pcmUpdateCount ) );
1006 }
1007 else
1008 {
1009 m_pcmButton->SetShowBadge( false );
1010 }
1011
1012 m_pcmButton->Refresh();
1013 }
1014}
1015
1016
1018{
1019 // No idea why, but the same mechanism used in EDA_DRAW_FRAME doesn't work here
1020 // the only thing that seems to work is to blow it all up and start from scratch.
1021 m_auimgr.DetachPane( m_mainToolBar );
1022 delete m_mainToolBar;
1023 m_mainToolBar = nullptr;
1025 m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Left()
1026 .Layer( 2 ) );
1027}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:111
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
@ icon_kicad_16
@ icon_kicad_nightly
@ icon_kicad_32
@ icon_kicad_nightly_32
@ icon_kicad_nightly_16
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
bool IsNightlyVersion()
Check if the build is meant to be nightly.
static TOOL_ACTION paste
Definition: actions.h:72
static TOOL_ACTION saveAs
Definition: actions.h:52
static TOOL_ACTION copy
Definition: actions.h:71
static TOOL_ACTION cut
Definition: actions.h:70
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
wxProgressDialog with the option to also update the application progress on the taskbar
virtual bool Update(int aValue, const wxString &aNewMsg=wxEmptyString, bool *aSkip=nullptr) override
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:92
void UnregisterStatusBar(KISTATUSBAR *aStatusBar)
Removes status bar from handling.
void RegisterStatusBar(KISTATUSBAR *aStatusBar)
Add a status bar for handling.
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
Definition: bitmap_button.h:42
void SetBadgeText(const wxString &aText)
void SetShowBadge(bool aShowBadge)
Handle actions that are shared between different applications.
APPEARANCE m_Appearance
DO_NOT_SHOW_AGAIN m_DoNotShowAgain
The base frame for deriving all KiCad main window classes.
void LoadWindowState(const wxString &aFileName)
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
std::vector< wxFileName > m_AcceptedFiles
SETTINGS_MANAGER * GetSettingsManager() const
wxAuiManager m_auimgr
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.
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associates files extensions with action to execute.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
void SetMruPath(const wxString &aPath)
virtual void RegisterUIUpdateHandler(int aID, const ACTION_CONDITIONS &aConditions) override
Register a UI update handler for the control with ID aID.
bool m_isClosing
Set by NonUserClose() to indicate that the user did not request the current close.
Specialization of the wxAuiPaneInfo class for KiCad panels.
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
Calls Store() and then writes the contents of the JSON document to a file.
static TOOL_ACTION viewDroppedGerbers
static TOOL_ACTION editPCB
static TOOL_ACTION loadProject
static TOOL_ACTION editSchematic
static TOOL_ACTION openTextEditor
static TOOL_ACTION closeProject
Handle actions in the kicad manager frame.
The main KiCad project manager frame.
std::shared_ptr< PLUGIN_CONTENT_MANAGER > m_pcm
void language_change(wxCommandEvent &event)
void SetPcmButton(BITMAP_BUTTON *aButton)
void doCloseWindow() override
void CreateNewProject(const wxFileName &aProjectFileName, bool aCreateStubFiles=true)
Creates a new project by setting up and initial project, schematic, and board files.
void OnUnarchiveFiles(wxCommandEvent &event)
const SEARCH_STACK & sys_search() override
Return a SEARCH_STACK pertaining to entire program.
void OnImportEasyEdaProFiles(wxCommandEvent &event)
Open dialog to import EasyEDA Pro schematic and board files.
void ProjectChanged() override
Notification event that the project has changed.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
const wxString SchLegacyFileName()
void RecreateBaseLeftToolbar()
(Re)Create the left vertical toolbar
wxWindow * GetToolCanvas() const override
Canvas access.
void OnImportEasyEdaFiles(wxCommandEvent &event)
Open dialog to import EasyEDA Std schematic and board files.
PROJECT_TREE_PANE * m_leftWin
const wxString GetProjectFileName() const
void OnBrowseInFileExplorer(wxCommandEvent &event)
KICAD_SETTINGS * kicadSettings() const
const wxString SchFileName()
void OnImportEagleFiles(wxCommandEvent &event)
Open dialog to import Eagle schematic and board files.
wxStatusBar * OnCreateStatusBar(int number, long style, wxWindowID id, const wxString &name) override
Create the status line (like a wxStatusBar).
void OnExit(wxCommandEvent &event)
void LoadProject(const wxFileName &aProjectFileName)
bool canCloseWindow(wxCloseEvent &aCloseEvent) override
void OnSize(wxSizeEvent &event) override
virtual void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void DoWithAcceptedFiles() override
Execute action on accepted dropped file.
void OnOpenFileInTextEditor(wxCommandEvent &event)
APP_SETTINGS_BASE * config() const override
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
const wxString PcbLegacyFileName()
KICAD_MANAGER_FRAME(wxWindow *parent, const wxString &title, const wxPoint &pos, const wxSize &size)
bool CloseProject(bool aSave)
Closes the project, and saves it if aSave is true;.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
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.
void OnIdle(wxIdleEvent &event)
void PrintPrjInfo()
Prints the current working directory name and the project name on the text panel.
ACTION_TOOLBAR * m_mainToolBar
void OnArchiveFiles(wxCommandEvent &event)
void OnImportCadstarArchiveFiles(wxCommandEvent &event)
Open dialog to import CADSTAR Schematic and PCB Archive files.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
BITMAP_BUTTON * m_pcmButton
PANEL_KICAD_LAUNCHER * m_launcher
wxString help_name() override
const wxString PcbFileName()
std::unique_ptr< UPDATE_MANAGER > m_updateManager
std::vector< wxString > m_OpenProjects
std::vector< std::pair< wxString, wxString > > m_PcmRepositories
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition: kistatusbar.h:45
void SetEllipsedTextField(const wxString &aText, int aFieldId)
Set the text in a field using wxELLIPSIZE_MIDDLE option to adjust the text size to the field size (un...
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:55
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition: kiway.cpp:543
void RegisterStatusBar(KISTATUSBAR *aStatusBar)
Add a status bar for handling.
void CreateOrUpdate(const wxString &aKey, const wxString &aTitle, const wxString &aDescription, const wxString &aHref=wxEmptyString)
Creates a notification with the given parameters or updates an existing one with the same key.
void Remove(const wxString &aKey)
Remove a notification by key.
void UnregisterStatusBar(KISTATUSBAR *aStatusBar)
Removes status bar from handling.
static REPORTER & GetInstance()
Definition: reporter.cpp:91
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:678
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition: pgm_base.h:146
bool m_Quitting
Definition: pgm_base.h:390
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
Definition: pgm_base.h:148
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
wxString GetHelpFileName()
Definition: pgm_kicad.h:59
SEARCH_STACK & SysSearch()
Definition: pgm_kicad.h:57
APP_SETTINGS_BASE * PgmSettings()
Definition: pgm_kicad.h:55
PROJECT_TREE_PANE Window to display the tree files.
void EmptyTreePrj()
Delete all m_TreeProject entries.
void ReCreateTreePrj()
Create or modify the tree showing project file names.
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:128
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:134
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:189
Look for files in a number of paths.
Definition: search_stack.h:43
static bool ShowNever(const SELECTION &aSelection)
Always returns false.
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Saves a loaded project.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
bool IsProjectOpen() const
Helper for checking if we have a project open TODO: This should be deprecated along with Prj() once w...
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters the given PROJECT.
std::vector< wxString > GetOpenProjects() const
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Calls BackupProject if a new backup is needed according to the current backup policy.
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
TOOL_DISPATCHER * m_toolDispatcher
Definition: tools_holder.h:169
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
ACTIONS * m_actions
Definition: tools_holder.h:168
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
Definition: tool_manager.h:62
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:150
ACTION_MANAGER * GetActionManager() const
Definition: tool_manager.h:302
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
void InitTools()
Initializes all registered tools.
void ShutdownAllTools()
Shutdown all tools with a currently registered event loop in this tool manager by waking them up with...
#define ENABLE(x)
#define _(s)
Base window classes and related definitions.
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define KICAD_MANAGER_FRAME_NAME
KiCad executable names.
const wxString GERBVIEW_EXE
@ KICAD_MAIN_FRAME_T
Definition: frame_type.h:68
wxString FindKicadFile(const wxString &shortname)
Search the executable file shortname in KiCad binary path and return full file name if found or short...
Definition: gestfich.cpp:54
static const std::string LegacySchematicFileExtension
static const std::string GerberJobFileExtension
static const std::string GerberFileExtension
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string LegacyProjectFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string DrillFileExtension
static const std::string KiCadPcbFileExtension
static wxString AllFilesWildcard()
static bool IsGerberFileExtension(const wxString &ext)
@ ID_FILE_LIST_CLEAR
Definition: id.h:87
@ ID_LANGUAGE_CHOICE
Definition: id.h:105
@ ID_FILEMAX
Definition: id.h:85
@ ID_LANGUAGE_CHOICE_END
Definition: id.h:141
@ ID_FILE1
Definition: id.h:84
PGM_KICAD & PgmTop()
Definition: kicad.cpp:80
IDs used in KiCad main frame foe menuitems and tools.
@ ID_IMPORT_EAGLE_PROJECT
Definition: kicad_id.h:72
@ ID_IMPORT_EASYEDAPRO_PROJECT
Definition: kicad_id.h:74
@ ID_READ_ZIP_ARCHIVE
Definition: kicad_id.h:69
@ ID_SAVE_AND_ZIP_FILES
Definition: kicad_id.h:68
@ ID_INIT_WATCHED_PATHS
Definition: kicad_id.h:70
@ ID_IMPORT_CADSTAR_ARCHIVE_PROJECT
Definition: kicad_id.h:71
@ ID_EDIT_LOCAL_FILE_IN_TEXT_EDITOR
Definition: kicad_id.h:66
@ ID_IMPORT_EASYEDA_PROJECT
Definition: kicad_id.h:73
@ ID_BROWSE_IN_FILE_EXPLORER
Definition: kicad_id.h:67
EVT_MENU_RANGE(ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::language_change) KICAD_MANAGER_FRAME
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
Definition: launch_ext.cpp:25
bool RegisterApplicationRestart(const wxString &aCommandLine)
Registers the application for restart with the OS with the given command line string to pass as args.
Definition: unix/app.cpp:65
PBOOL GetPolicyBool(const wxString &aKey)
Definition: unix/policy.cpp:26
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
Definition: ui_common.cpp:130
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
#define POLICY_KEY_PCM
Definition: policy_keys.h:31
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
ACTION_CONDITIONS & Enable(const SELECTION_CONDITION &aCondition)
Definition of file extensions used in Kicad.