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 );
152 Pgm().GetBackgroundJobMonitor().RegisterStatusBar( (KISTATUSBAR*) GetStatusBar() );
153 Pgm().GetNotificationsManager().RegisterStatusBar( (KISTATUSBAR*) GetStatusBar() );
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 RecreateBaseHToolbar();
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().HToolbar().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{
263 Pgm().GetBackgroundJobMonitor().UnregisterStatusBar( (KISTATUSBAR*) GetStatusBar() );
264 Pgm().GetNotificationsManager().UnregisterStatusBar( (KISTATUSBAR*) GetStatusBar() );
265
266 // Shutdown all running tools
267 if( m_toolManager )
269
270 if( m_pcm )
271 m_pcm->StopBackgroundUpdate();
272
273 delete m_actions;
274 delete m_toolManager;
275 delete m_toolDispatcher;
276
277 m_auimgr.UnInit();
278}
279
280
281wxStatusBar* KICAD_MANAGER_FRAME::OnCreateStatusBar( int number, long style, wxWindowID id,
282 const wxString& name )
283{
284 return new KISTATUSBAR( number, this, id );
285}
286
287
289{
290 // creates the PLUGIN_CONTENT_MANAGER, if not exists
291 if( m_pcm )
292 return;
293
294 m_pcm = std::make_shared<PLUGIN_CONTENT_MANAGER>(
295 [this]( int aUpdateCount )
296 {
297 m_pcmUpdateCount = aUpdateCount;
298
299 if( aUpdateCount > 0 )
300 {
301 Pgm().GetNotificationsManager().CreateOrUpdate(
302 wxS( "pcm" ),
303 _( "PCM Updates Available" ),
304 wxString::Format( _( "%d package update(s) avaliable" ), aUpdateCount ),
305 wxT( "" ) );
306 }
307 else
308 {
309 Pgm().GetNotificationsManager().Remove( wxS( "pcm" ) );
310 }
311
312 CallAfter(
313 [this]()
314 {
316 } );
317 });
318
319 m_pcm->SetRepositoryList( kicadSettings()->m_PcmRepositories );
320}
321
322
324{
325 // Create the manager
327 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
329
331
332 // Attach the events to the tool dispatcher
334 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
335
336 // Register tools
340}
341
342
344{
346
348
349 wxASSERT( manager );
350
351 auto activeProject =
352 [this] ( const SELECTION& )
353 {
354 return m_active_project;
355 };
356
357#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
358
359 ACTION_CONDITIONS activeProjectCond;
360 activeProjectCond.Enable( activeProject );
361
362 manager->SetConditions( ACTIONS::saveAs, activeProjectCond );
363 manager->SetConditions( KICAD_MANAGER_ACTIONS::closeProject, activeProjectCond );
364
365 // These are just here for text boxes, search boxes, etc. in places such as the standard
366 // file dialogs.
370
371 // TODO: Switch this to an action
373
374#undef ENABLE
375}
376
377
379{
380 return m_leftWin;
381}
382
383
385{
387 wxASSERT( ret );
388 return ret;
389}
390
391
393{
394 KICAD_SETTINGS* ret = dynamic_cast<KICAD_SETTINGS*>( config() );
395 wxASSERT( ret );
396 return ret;
397}
398
399
401{
402 return Pgm().GetSettingsManager().IsProjectOpen() ? Prj().GetProjectFullName() :
403 wxString( wxEmptyString );
404}
405
406
408{
409 wxFileName fn( GetProjectFileName() );
410
412 return fn.GetFullPath();
413}
414
415
417{
418 wxFileName fn( GetProjectFileName() );
419
421 return fn.GetFullPath();
422}
423
424
426{
427 wxFileName fn( GetProjectFileName() );
428
429 fn.SetExt( FILEEXT::PcbFileExtension );
430 return fn.GetFullPath();
431}
432
433
435{
436 wxFileName fn( GetProjectFileName() );
437
439 return fn.GetFullPath();
440}
441
442
444{
446}
447
448
450{
451 return PgmTop().SysSearch();
452}
453
454
456{
457 return PgmTop().GetHelpFileName();
458}
459
460
461void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
462{
463 if( m_auimgr.GetManagedWindow() )
464 m_auimgr.Update();
465
466 PrintPrjInfo();
467
468#if defined( _WIN32 )
469 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
471#endif
472
473 event.Skip();
474}
475
476
478{
479 // All fileNames are now in m_AcceptedFiles vector.
480 // Check if contains a project file name and load project.
481 // If not, open files in dedicated app.
482 for( const wxFileName& fileName : m_AcceptedFiles )
483 {
484 wxString ext = fileName.GetExt();
485
487 {
488 wxString fn = fileName.GetFullPath();
489 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
490
491 return;
492 }
493 }
494
495 // Then stock gerber files in gerberFiles and run action for other files.
496 wxString gerberFiles;
497
498 // Gerbview editor should be able to open Gerber and drill files
499 for( const wxFileName& fileName : m_AcceptedFiles )
500 {
501 wxString ext = fileName.GetExt();
502
505 {
506 gerberFiles += wxT( '\"' );
507 gerberFiles += fileName.GetFullPath() + wxT( '\"' );
508 gerberFiles = gerberFiles.Pad( 1 );
509 }
510 else
511 {
512 wxString fn = fileName.GetFullPath();
513 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
514 }
515 }
516
517 // Execute Gerbviewer
518 if( !gerberFiles.IsEmpty() )
519 {
520 wxString fullEditorName = FindKicadFile( GERBVIEW_EXE );
521
522 if( wxFileExists( fullEditorName ) )
523 {
524 wxString command = fullEditorName + " " + gerberFiles;
526 &command );
527 }
528 }
529}
530
531
532bool KICAD_MANAGER_FRAME::canCloseWindow( wxCloseEvent& aEvent )
533{
534 KICAD_SETTINGS* settings = kicadSettings();
536
537 // CloseProject will recursively ask all the open editors if they need to save changes.
538 // If any of them cancel then we need to cancel closing the KICAD_MANAGER_FRAME.
539 if( CloseProject( true ) )
540 {
541 // Don't propagate event to frames which have already been closed
542 aEvent.StopPropagation();
543
544 return true;
545 }
546 else
547 {
548 if( aEvent.CanVeto() )
549 aEvent.Veto();
550
551 return false;
552 }
553}
554
555
557{
558#ifdef _WINDOWS_
559 // For some obscure reason, on Windows, when killing Kicad from the Windows task manager
560 // if a editor frame (schematic, library, board editor or fp editor) is open and has
561 // some edition to save, OnCloseWindow is run twice *at the same time*, creating race
562 // conditions between OnCloseWindow() code.
563 // Therefore I added (JPC) a ugly hack to discard the second call (unwanted) during
564 // execution of the first call (only one call is right).
565 // Note also if there is no change made in editors, this behavior does not happen.
566 static std::atomic<unsigned int> lock_close_event( 0 );
567
568 if( ++lock_close_event > 1 ) // Skip extra calls
569 {
570 return;
571 }
572#endif
573
574 m_leftWin->Show( false );
575 Pgm().m_Quitting = true;
576
577 Destroy();
578
579#ifdef _WINDOWS_
580 lock_close_event = 0; // Reenable event management
581#endif
582}
583
584
585void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event )
586{
587 Close( true );
588}
589
590
592{
593 if( !Kiway().PlayersClose( false ) )
594 return false;
595
596 // Save the project file for the currently loaded project.
597 if( m_active_project )
598 {
599 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
600
602
603 if( aSave )
604 mgr.SaveProject();
605
606 m_active_project = false;
607 mgr.UnloadProject( &Prj() );
608 }
609
610 SetStatusText( "" );
611
613
614 return true;
615}
616
617
618void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
619{
620 // The project file should be valid by the time we get here or something has gone wrong.
621 if( !aProjectFileName.Exists() )
622 return;
623
624 // Any open KIFACE's must be closed if they are not part of the new project.
625 // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.)
626 // User is prompted here to close those KIWAY_PLAYERs:
627 if( !CloseProject( true ) )
628 return;
629
630 m_active_project = true;
631
632 Pgm().GetSettingsManager().LoadProject( aProjectFileName.GetFullPath() );
633
634 LoadWindowState( aProjectFileName.GetFullName() );
635
636 if( aProjectFileName.IsDirWritable() )
637 SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why?
638
639 // Save history & window state to disk now. Don't wait around for a crash.
640 KICAD_SETTINGS* settings = kicadSettings();
641 SaveSettings( settings );
642 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
643
645
646 // Rebuild the list of watched paths.
647 // however this is possible only when the main loop event handler is running,
648 // so we use it to run the rebuild function.
649 wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
650
651 wxPostEvent( this, cmd );
652
653 PrintPrjInfo();
654
655 KIPLATFORM::APP::RegisterApplicationRestart( aProjectFileName.GetFullPath() );
656 m_openSavedWindows = true;
657}
658
659
660void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName,
661 bool aCreateStubFiles )
662{
663 wxCHECK_RET( aProjectFileName.DirExists() && aProjectFileName.IsDirWritable(),
664 "Project folder must exist and be writable to create a new project." );
665
666 // If the project is legacy, convert it
667 if( !aProjectFileName.FileExists() )
668 {
669 wxFileName legacyPro( aProjectFileName );
670 legacyPro.SetExt( FILEEXT::LegacyProjectFileExtension );
671
672 if( legacyPro.FileExists() )
673 {
674 GetSettingsManager()->LoadProject( legacyPro.GetFullPath() );
676
677 wxRemoveFile( legacyPro.GetFullPath() );
678 }
679 else
680 {
681 // Copy template project file from template folder.
682 wxString srcFileName = sys_search().FindValidPath( "kicad.kicad_pro" );
683
684 wxFileName destFileName( aProjectFileName );
685 destFileName.SetExt( FILEEXT::ProjectFileExtension );
686
687 // Create a minimal project file if the template project file could not be copied
688 if( !wxFileName::FileExists( srcFileName )
689 || !wxCopyFile( srcFileName, destFileName.GetFullPath() ) )
690 {
691 wxFFile file( destFileName.GetFullPath(), "wb" );
692
693 if( file.IsOpened() )
694 file.Write( wxT( "{\n}\n") );
695
696 // wxFFile dtor will close the file
697 }
698 }
699 }
700
701 // Create a "stub" for a schematic root sheet and a board if requested.
702 // It will avoid messages from the schematic editor or the board editor to create a new file
703 // And forces the user to create main files under the right name for the project manager
704 if( aCreateStubFiles )
705 {
706 wxFileName fn( aProjectFileName.GetFullPath() );
708
709 // If a <project>.kicad_sch file does not exist, create a "stub" file ( minimal schematic
710 // file ).
711 if( !fn.FileExists() )
712 {
713 wxFFile file( fn.GetFullPath(), "wb" );
714
715 if( file.IsOpened() )
716 file.Write( wxString::Format( "(kicad_sch (version %d) (generator \"eeschema\") (generator_version \"%s\")\n"
717 " (paper \"A4\")\n (lib_symbols)\n"
718 " (symbol_instances)\n)\n",
720
721 // wxFFile dtor will close the file
722 }
723
724 // If a <project>.kicad_pcb or <project>.brd file does not exist,
725 // create a .kicad_pcb "stub" file
727 wxFileName leg_fn( fn );
728 leg_fn.SetExt( FILEEXT::LegacyPcbFileExtension );
729
730 if( !fn.FileExists() && !leg_fn.FileExists() )
731 {
732 wxFFile file( fn.GetFullPath(), "wb" );
733
734 if( file.IsOpened() )
735 // Create a small dummy file as a stub for pcbnew:
736 file.Write( wxString::Format( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n)",
738
739 // wxFFile dtor will close the file
740 }
741 }
742
743 // Save history & window state to disk now. Don't wait around for a crash.
744 KICAD_SETTINGS* settings = kicadSettings();
745 SaveSettings( settings );
746 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
747
748 m_openSavedWindows = true;
749}
750
751
753{
754 // show all files in file dialog (in Kicad all files are editable texts):
755 wxString wildcard = FILEEXT::AllFilesWildcard();
756
757 wxString default_dir = Prj().GetProjectPath();
758
759 wxFileDialog dlg( this, _( "Edit File in Text Editor" ), default_dir, wxEmptyString, wildcard,
760 wxFD_OPEN );
761
762 if( dlg.ShowModal() == wxID_CANCEL )
763 return;
764
765 wxString filename = dlg.GetPath();
766
767 if( !dlg.GetPath().IsEmpty() && !Pgm().GetTextEditor().IsEmpty() )
769}
770
771
773{
774 // open project directory in host OS's file explorer
775 LaunchExternal( Prj().GetProjectPath() );
776}
777
778
780{
782}
783
784
785void KICAD_MANAGER_FRAME::language_change( wxCommandEvent& event )
786{
787 int id = event.GetId();
788 Kiway().SetLanguage( id );
789}
790
791
793{
794 // call my base class
796
797 // tooltips in toolbars
800
801 PrintPrjInfo();
802}
803
804
805void KICAD_MANAGER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
806{
807 EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
808
809 if( m_pcm && aEnvVarsChanged )
810 {
811 m_pcm->ReadEnvVar();
812 }
813
814 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
815
816 if( m_lastToolbarIconSize == 0
818 {
821 }
822}
823
824
826{
827 wxString file = GetProjectFileName();
828 wxString title;
829
830 if( !file.IsEmpty() )
831 {
832 wxFileName fn( file );
833
834 title = fn.GetName();
835
836 if( !fn.IsDirWritable() )
837 title += wxS( " " ) + _( "[Read Only]" );
838 }
839 else
840 {
841 title = _( "[no project loaded]" );
842 }
843
844 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
845 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad" ) );
846 else
847 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad " ) ) + GetMajorMinorVersion();
848
849 SetTitle( title );
850}
851
852
854{
856
857 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
858
859 wxCHECK( settings, /*void*/ );
860
861 m_leftWinWidth = settings->m_LeftWinWidth;
862}
863
864
866{
868
869 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
870
871 wxCHECK( settings, /*void*/);
872
873 settings->m_LeftWinWidth = m_leftWin->GetSize().x;
874
875 if( !m_isClosing )
876 settings->m_OpenProjects = GetSettingsManager()->GetOpenProjects();
877}
878
879
881{
882 // wxStatusBar's wxELLIPSIZE_MIDDLE flag doesn't work (at least on Mac).
883
884 wxString status = wxString::Format( _( "Project: %s" ), Prj().GetProjectFullName() );
885 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
886 statusBar->SetEllipsedTextField( status, 0 );
887}
888
889
891{
892 return m_active_project;
893}
894
895
896void KICAD_MANAGER_FRAME::OnIdle( wxIdleEvent& aEvent )
897{
903 if( !m_openSavedWindows )
904 return;
905
906 m_openSavedWindows = false;
907
908 if( Pgm().GetCommonSettings()->m_Session.remember_open_files )
909 {
910 int previousOpenCount =
911 std::count_if( Prj().GetLocalSettings().m_files.begin(),
912 Prj().GetLocalSettings().m_files.end(),
913 [&]( const PROJECT_FILE_STATE& f )
914 {
915 return !f.fileName.EndsWith( FILEEXT::ProjectFileExtension ) && f.open;
916 } );
917
918 if( previousOpenCount > 0 )
919 {
920 APP_PROGRESS_DIALOG progressReporter( _( "Restoring session" ), wxEmptyString,
921 previousOpenCount, this );
922
923 // We don't currently support opening more than one view per file
924 std::set<wxString> openedFiles;
925
926 int i = 0;
927
928 for( const PROJECT_FILE_STATE& file : Prj().GetLocalSettings().m_files )
929 {
930 if( file.open && !openedFiles.count( file.fileName ) )
931 {
932 progressReporter.Update( i++,
933 wxString::Format( _( "Restoring '%s'" ), file.fileName ) );
934
935 openedFiles.insert( file.fileName );
936 wxFileName fn( file.fileName );
937
939 || fn.GetExt() == FILEEXT::KiCadSchematicFileExtension )
940 {
942 }
943 else if( fn.GetExt() == FILEEXT::LegacyPcbFileExtension
944 || fn.GetExt() == FILEEXT::KiCadPcbFileExtension )
945 {
947 }
948 }
949
950 wxYield();
951 }
952 }
953 }
954
955 // clear file states regardless if we opened windows or not due to setting
957
958 KICAD_SETTINGS* settings = kicadSettings();
959
960 if( !Pgm().GetCommonSettings()->m_DoNotShowAgain.update_check_prompt )
961 {
962 auto prompt = new DIALOG_UPDATE_CHECK_PROMPT( this );
963 prompt->ShowModal();
964
965 Pgm().GetCommonSettings()->m_DoNotShowAgain.update_check_prompt = true;
966 }
967
969 && settings->m_PcmUpdateCheck )
970 {
971 if( !m_pcm )
972 CreatePCM();
973
974 m_pcm->RunBackgroundUpdate();
975 }
976
977#ifdef KICAD_UPDATE_CHECK
978 if( !m_updateManager && settings->m_KiCadUpdateCheck )
979 {
980 m_updateManager = std::make_unique<UPDATE_MANAGER>();
981 m_updateManager->CheckForUpdate( this );
982 }
983#endif
984}
985
986
988{
989 m_pcmButton = aButton;
990
992}
993
994
996{
997 if( m_pcmButton )
998 {
999 if( m_pcmUpdateCount > 0 )
1000 {
1001 m_pcmButton->SetShowBadge( true );
1002 m_pcmButton->SetBadgeText( wxString::Format( "%d", m_pcmUpdateCount ) );
1003 }
1004 else
1005 {
1006 m_pcmButton->SetShowBadge( false );
1007 }
1008
1009 m_pcmButton->Refresh();
1010 }
1011}
1012
1013
1015{
1016 // No idea why, but the same mechanism used in EDA_DRAW_FRAME doesn't work here
1017 // the only thing that seems to work is to blow it all up and start from scratch.
1018 m_auimgr.DetachPane( m_mainToolBar );
1019 delete m_mainToolBar;
1020 m_mainToolBar = nullptr;
1022 m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Left()
1023 .Layer( 2 ) );
1024}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:112
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:70
static TOOL_ACTION saveAs
Definition: actions.h:52
static TOOL_ACTION copy
Definition: actions.h:69
static TOOL_ACTION cut
Definition: actions.h:68
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
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
Definition: bitmap_button.h:41
void SetBadgeText(const wxString &aText)
void SetShowBadge(bool aShowBadge)
Handle actions that are shared between different applications.
APPEARANCE m_Appearance
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()
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 RecreateBaseHToolbar()
(Re)Create the horizontal toolbar
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:43
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:53
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition: kiway.cpp:569
static REPORTER & GetInstance()
Definition: reporter.cpp:119
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:129
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:135
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:172
Look for files in a number of paths.
Definition: search_stack.h:42
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 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:57
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
ACTION_MANAGER * GetActionManager() const
Definition: tool_manager.h:289
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:90
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
KIWAY Kiway
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: gtk/app.cpp:65
PBOOL GetPolicyBool(const wxString &aKey)
Definition: gtk/policy.cpp:26
wxFont GetStatusFont(wxWindow *aWindow)
Definition: ui_common.cpp:127
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
#define POLICY_KEY_PCM
Definition: policy_keys.h:31
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
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.