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 The 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 "kicad_id.h"
27#include "pcm.h"
28#include "pgm_kicad.h"
29#include "project_tree_pane.h"
30#include "local_history_pane.h"
32
33#include <advanced_config.h>
35#include <bitmaps.h>
36#include <build_version.h>
37#include <confirm.h>
41#include <local_history.h>
42#include <wx/msgdlg.h>
43#include <eda_base_frame.h>
44#include <executable_names.h>
45#include <file_history.h>
46#include <local_history.h>
47#include <policy_keys.h>
48#include <gestfich.h>
49#include <kiplatform/app.h>
51#include <kiplatform/policy.h>
52#include <build_version.h>
53#include <kiway.h>
54#include <kiway_express.h>
55#include <launch_ext.h>
56#include <lockfile.h>
58#include <reporter.h>
60#include <sch_file_versions.h>
62#include <tool/action_manager.h>
63#include <tool/action_toolbar.h>
64#include <tool/common_control.h>
66#include <tool/tool_manager.h>
72#include <widgets/kistatusbar.h>
73#include <wx/ffile.h>
74#include <wx/filedlg.h>
75#include <wx/dnd.h>
76#include <wx/process.h>
77#include <wx/snglinst.h>
78#include <atomic>
79#include <update_manager.h>
80#include <jobs/jobset.h>
81
82#include <../pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h> // for SEXPR_BOARD_FILE_VERSION def
83
84
85#ifdef __WXMAC__
86#include <MacTypes.h>
87#include <ApplicationServices/ApplicationServices.h>
88#endif
89
90#include "kicad_manager_frame.h"
92
94
95
96#define EDITORS_CAPTION _( "Editors" )
97#define PROJECT_FILES_CAPTION _( "Project Files" )
98
99#define ID_INIT_WATCHED_PATHS 52913
100
101#define SEP() wxFileName::GetPathSeparator()
102
103
104// Menubar and toolbar event table
105BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
106 // Window events
109
110 // Menu events
111 EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit )
119
120 // Range menu events
122 KICAD_MANAGER_FRAME::language_change )
123
125 EVT_MENU( ID_FILE_LIST_CLEAR, KICAD_MANAGER_FRAME::OnClearFileHistory )
126
127 // Special functions
128 EVT_MENU( ID_INIT_WATCHED_PATHS, KICAD_MANAGER_FRAME::OnChangeWatchedPaths )
129
130 // Drop files event
131 EVT_DROP_FILES( KICAD_MANAGER_FRAME::OnDropFiles )
132
133END_EVENT_TABLE()
134
135// See below the purpose of this include
136#include <wx/xml/xml.h>
138
139KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title,
140 const wxPoint& pos, const wxSize& size ) :
143 m_openSavedWindows( false ),
144 m_restoredFromHistory( false ),
145 m_active_project( false ),
146 m_showHistoryPanel( false ),
147 m_leftWin( nullptr ),
148 m_historyPane( nullptr ),
149 m_launcher( nullptr ),
150 m_lastToolbarIconSize( 0 ),
151 m_pcmButton( nullptr ),
152 m_pcmUpdateCount( 0 )
153{
154 const int defaultLeftWinWidth = FromDIP( 250 );
155
156 m_leftWinWidth = defaultLeftWinWidth; // Default value
157 m_aboutTitle = "KiCad";
158
159 // JPC: A very ugly hack to fix an issue on Linux: if the wxbase315u_xml_gcc_custom.so is
160 // used **only** in PCM, it is not found in some cases at run time.
161 // So just use it in the main module to avoid a not found issue
162 // wxbase315u_xml_gcc_custom shared object when launching Kicad
163 wxXmlDocument dummy;
164
165 // Create the status line (bottom of the frame). Left half is for project name; right half
166 // is for Reporter (currently used by archiver/unarchiver and PCM).
167 // Note: this is a KISTATUSBAR status bar. Therefore the specified number of fields
168 // is the extra number of fields, not the full field count.
169 // We need here 2 fields: the extra fiels to display the project name, and another field
170 // to display a info (specific to Windows) using the FIELD_OFFSET_BGJOB_TEXT id offset (=1)
171 // So the extra field count is 1
172 CreateStatusBar( 2 );
175 Pgm().RegisterLibraryLoadStatusBar( (KISTATUSBAR*) GetStatusBar() );
176 GetStatusBar()->SetFont( KIUI::GetStatusFont( this ) );
177
178 // Give an icon
179 wxIcon icon;
180 wxIconBundle icon_bundle;
181
182 if( IsNightlyVersion())
183 {
184 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 48 ) );
185 icon_bundle.AddIcon( icon );
186 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 128 ) );
187 icon_bundle.AddIcon( icon );
188 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 256 ) );
189 icon_bundle.AddIcon( icon );
190 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly_32 ) );
191 icon_bundle.AddIcon( icon );
192 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly_16 ) );
193 icon_bundle.AddIcon( icon );
194 }
195 else
196 {
197 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 48 ) );
198 icon_bundle.AddIcon( icon );
199 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 128 ) );
200 icon_bundle.AddIcon( icon );
201 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 256 ) );
202 icon_bundle.AddIcon( icon );
203 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_32 ) );
204 icon_bundle.AddIcon( icon );
205 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_16 ) );
206 icon_bundle.AddIcon( icon );
207 }
208
209 SetIcons( icon_bundle );
210
211 // Load the settings
212 LoadSettings( config() );
213
214 // Left window: is the box which display tree project
215 m_leftWin = new PROJECT_TREE_PANE( this );
216
217 setupTools();
218 setupUIConditions();
219
220 m_toolbarSettings = GetToolbarSettings<KICAD_MANAGER_TOOLBAR_SETTINGS>( "kicad-toolbars" );
221 configureToolbars();
222 RecreateToolbars();
223 ReCreateMenuBar();
224
225 m_auimgr.SetManagedWindow( this );
226 m_auimgr.SetFlags( wxAUI_MGR_LIVE_RESIZE );
227
228 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( "TopMainToolbar" ).Left().Layer( 2 ) );
229
230 // BestSize() does not always set the actual pane size of m_leftWin to the required value.
231 // It happens when m_leftWin is too large (roughly > 1/3 of the kicad manager frame width.
232 // (Well, BestSize() sets the best size... not the window size)
233 // A trick is to use MinSize() to set the required pane width,
234 // and after give a reasonable MinSize value
235 m_auimgr.AddPane( m_leftWin, EDA_PANE().Palette().Name( "ProjectTree" ).Left().Layer( 1 )
236 .Caption( PROJECT_FILES_CAPTION ).PaneBorder( false )
237 .MinSize( m_leftWinWidth, -1 ).BestSize( m_leftWinWidth, -1 ) );
238
239 m_historyPane = new LOCAL_HISTORY_PANE( this );
240 m_auimgr.AddPane( m_historyPane,
241 EDA_PANE().Palette().Name( "LocalHistory" ).Left().Layer( 1 ).Position( 1 )
242 .Caption( _( "Local History" ) ).PaneBorder( false )
243 .Floatable( false ).Movable( false ).CloseButton( true ).Hide() );
244
245 if( m_showHistoryPanel )
246 m_auimgr.GetPane( m_historyPane ).Show();
247
248 wxSize client_size = GetClientSize();
249 m_notebook = new wxAuiNotebook( this, wxID_ANY, wxPoint( client_size.x, client_size.y ),
250 FromDIP( wxSize( 700, 590 ) ),
251 wxAUI_NB_TOP | wxAUI_NB_CLOSE_ON_ALL_TABS | wxAUI_NB_TAB_MOVE
252 | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER );
253
254 m_notebook->SetArtProvider( new WX_AUI_TAB_ART() );
255
256 m_notebook->Bind( wxEVT_AUINOTEBOOK_PAGE_CLOSE, &KICAD_MANAGER_FRAME::onNotebookPageCloseRequest, this );
257 m_notebook->Bind( wxEVT_AUINOTEBOOK_PAGE_CLOSED, &KICAD_MANAGER_FRAME::onNotebookPageCountChanged, this );
258 m_launcher = new PANEL_KICAD_LAUNCHER( m_notebook );
259
260 m_notebook->Freeze();
261 m_launcher->SetClosable( false );
262 m_notebook->AddPage( m_launcher, EDITORS_CAPTION, false );
263 m_notebook->SetTabCtrlHeight( 0 );
264 m_notebook->Thaw();
265
266 m_auimgr.AddPane( m_notebook, EDA_PANE().Canvas().Name( "Editors" ).Center().Caption( EDITORS_CAPTION )
267 .PaneBorder( false ).MinSize( m_notebook->GetBestSize() ) );
268
269 m_auimgr.Update();
270
271 // Now the actual m_leftWin size is set, give it a reasonable min width
272 m_auimgr.GetPane( m_leftWin ).MinSize( defaultLeftWinWidth, -1 );
273
274
275 wxSizer* mainSizer = GetSizer();
276
277 // Only fit the initial window size the first time KiCad is run.
278 if( mainSizer && config()->m_Window.state.size_x == 0 && config()->m_Window.state.size_y == 0 )
279 {
280 Layout();
281 mainSizer->Fit( this );
282 Center();
283 }
284
285 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
286 SetTitle( wxT( "KiCad" ) );
287 else
288 SetTitle( wxString( "KiCad " ) + GetMajorMinorVersion() );
289
290 // Do not let the messages window have initial focus
291 m_leftWin->SetFocus();
292
293 // Init for dropping files
296
297 // Gerber files
298 // Note that all gerber files are aliased as GerberFileExtension
302
303 DragAcceptFiles( true );
304
305 // Ensure the window is on top
306 Raise();
307}
308
309
311{
313 Unbind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
314
315 m_notebook->Unbind( wxEVT_AUINOTEBOOK_PAGE_CLOSE, &KICAD_MANAGER_FRAME::onNotebookPageCloseRequest, this );
316 m_notebook->Unbind( wxEVT_AUINOTEBOOK_PAGE_CLOSED, &KICAD_MANAGER_FRAME::onNotebookPageCountChanged, this );
317
320 Pgm().UnregisterLibraryLoadStatusBar( (KISTATUSBAR*) GetStatusBar() );
321
322 // Shutdown all running tools
323 if( m_toolManager )
324 m_toolManager->ShutdownAllTools();
325
326 if( m_pcm )
327 m_pcm->StopBackgroundUpdate();
328
329 delete m_actions;
330 delete m_toolManager;
331 delete m_toolDispatcher;
332
333 m_auimgr.UnInit();
334}
335
337{
338 if( m_notebook->GetPageCount() == 1 )
339 m_notebook->SetTabCtrlHeight( 0 );
340 else
341 m_notebook->SetTabCtrlHeight( -1 );
342}
343
344
346{
348}
349
350
352{
353 wxAuiNotebook* notebook = (wxAuiNotebook*) evt.GetEventObject();
354 wxWindow* page = notebook->GetPage( evt.GetSelection() );
355
356 if( PANEL_NOTEBOOK_BASE* panel = dynamic_cast<PANEL_NOTEBOOK_BASE*>( page ) )
357 {
358 if( panel->GetClosable() )
359 {
360 if( !panel->GetCanClose() )
361 evt.Veto();
362
363 CallAfter(
364 [this]()
365 {
367 } );
368 }
369 else
370 {
371 evt.Veto();
372 }
373 }
374}
375
376
377wxStatusBar* KICAD_MANAGER_FRAME::OnCreateStatusBar( int number, long style, wxWindowID id,
378 const wxString& name )
379{
380 return new KISTATUSBAR( number, this, id,
381 static_cast<KISTATUSBAR::STYLE_FLAGS>(
384}
385
386
388{
389 // creates the PLUGIN_CONTENT_MANAGER, if not exists
390 if( m_pcm )
391 return;
392
393 m_pcm = std::make_shared<PLUGIN_CONTENT_MANAGER>(
394 [this]( int aUpdateCount )
395 {
396 m_pcmUpdateCount = aUpdateCount;
397
398 if( aUpdateCount > 0 )
399 {
401 wxS( "pcm" ),
402 _( "PCM Updates Available" ),
403 wxString::Format( _( "%d package update(s) available" ), aUpdateCount ),
404 wxT( "" ) );
405 }
406 else
407 {
408 Pgm().GetNotificationsManager().Remove( wxS( "pcm" ) );
409 }
410
411 CallAfter(
412 [this]()
413 {
415 } );
416 });
417
418 m_pcm->SetRepositoryList( kicadSettings()->m_PcmRepositories );
419}
420
421
423{
424 // Create the manager
426 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
428
430
431 // Attach the events to the tool dispatcher
433 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
434
435 // Register tools
436 m_toolManager->RegisterTool( new COMMON_CONTROL );
437 m_toolManager->RegisterTool( new KICAD_MANAGER_CONTROL );
438 m_toolManager->InitTools();
439}
440
441
443{
445
446 ACTION_MANAGER* manager = m_toolManager->GetActionManager();
447
448 wxASSERT( manager );
449
450 auto activeProject =
451 [this] ( const SELECTION& )
452 {
453 return m_active_project;
454 };
455
456#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
457
458 ACTION_CONDITIONS activeProjectCond;
459 activeProjectCond.Enable( activeProject );
460
461 manager->SetConditions( ACTIONS::saveAs, activeProjectCond );
462 manager->SetConditions( KICAD_MANAGER_ACTIONS::closeProject, activeProjectCond );
463 manager->SetConditions( KICAD_MANAGER_ACTIONS::archiveProject, activeProjectCond );
464 manager->SetConditions( KICAD_MANAGER_ACTIONS::newJobsetFile, activeProjectCond );
465 manager->SetConditions( KICAD_MANAGER_ACTIONS::openJobsetFile, activeProjectCond );
466
467 auto historyCond =
468 [this]( const SELECTION& )
469 {
470 return HistoryPanelShown();
471 };
472
474 ACTION_CONDITIONS().Check( historyCond ) );
475
476 // These are just here for text boxes, search boxes, etc. in places such as the standard
477 // file dialogs.
481
482#undef ENABLE
483}
484
485
487{
488 return m_leftWin;
489}
490
491
493{
495 wxASSERT( ret );
496 return ret;
497}
498
499
501{
502 KICAD_SETTINGS* ret = dynamic_cast<KICAD_SETTINGS*>( config() );
503 wxASSERT( ret );
504 return ret;
505}
506
507
509{
511 : wxString( wxEmptyString );
512}
513
514
516{
517 wxFileName fn( GetProjectFileName() );
518
520 return fn.GetFullPath();
521}
522
523
525{
526 wxFileName fn( GetProjectFileName() );
527
529 return fn.GetFullPath();
530}
531
532
534{
535 wxFileName fn( GetProjectFileName() );
536
537 fn.SetExt( FILEEXT::PcbFileExtension );
538 return fn.GetFullPath();
539}
540
541
543{
544 wxFileName fn( GetProjectFileName() );
545
547 return fn.GetFullPath();
548}
549
550
552{
553 m_leftWin->ReCreateTreePrj();
554}
555
556
561
562
564{
565 return PgmTop().GetHelpFileName();
566}
567
568
569void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
570{
571 if( m_auimgr.GetManagedWindow() )
572 m_auimgr.Update();
573
574 PrintPrjInfo();
575
576#if defined( _WIN32 )
577 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
579#endif
580
581 event.Skip();
582}
583
584
586{
587 // All fileNames are now in m_AcceptedFiles vector.
588 // Check if contains a project file name and load project.
589 // If not, open files in dedicated app.
590 for( const wxFileName& fileName : m_AcceptedFiles )
591 {
592 wxString ext = fileName.GetExt();
593
595 {
596 wxString fn = fileName.GetFullPath();
597 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
598
599 return;
600 }
601 }
602
603 // Then stock gerber files in gerberFiles and run action for other files.
604 wxString gerberFiles;
605
606 // Gerbview editor should be able to open Gerber and drill files
607 for( const wxFileName& fileName : m_AcceptedFiles )
608 {
609 wxString ext = fileName.GetExt();
610
613 {
614 gerberFiles += wxT( '\"' );
615 gerberFiles += fileName.GetFullPath() + wxT( '\"' );
616 gerberFiles = gerberFiles.Pad( 1 );
617 }
618 else
619 {
620 wxString fn = fileName.GetFullPath();
621 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
622 }
623 }
624
625 // Execute Gerbviewer
626 if( !gerberFiles.IsEmpty() )
627 {
628 wxString fullEditorName = FindKicadFile( GERBVIEW_EXE );
629
630 if( wxFileExists( fullEditorName ) )
631 {
632 wxString command = fullEditorName + " " + gerberFiles;
633 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( FILEEXT::GerberFileExtension ), &command );
634 }
635 }
636}
637
638
639bool KICAD_MANAGER_FRAME::canCloseWindow( wxCloseEvent& aEvent )
640{
641 KICAD_SETTINGS* settings = kicadSettings();
643
644 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
645 {
646 wxWindow* page = m_notebook->GetPage( i );
647
648 if( PANEL_NOTEBOOK_BASE* panel = dynamic_cast<PANEL_NOTEBOOK_BASE*>( page ) )
649 {
650 if( !panel->GetCanClose() )
651 return false;
652 }
653 }
654
655 // CloseProject will recursively ask all the open editors if they need to save changes.
656 // If any of them cancel then we need to cancel closing the KICAD_MANAGER_FRAME.
657 if( CloseProject( true ) )
658 {
659 // Don't propagate event to frames which have already been closed
660 aEvent.StopPropagation();
661
662 return true;
663 }
664 else
665 {
666 if( aEvent.CanVeto() )
667 aEvent.Veto();
668
669 return false;
670 }
671}
672
673
675{
676#ifdef _WINDOWS_
677 // For some obscure reason, on Windows, when killing Kicad from the Windows task manager
678 // if a editor frame (schematic, library, board editor or fp editor) is open and has
679 // some edition to save, OnCloseWindow is run twice *at the same time*, creating race
680 // conditions between OnCloseWindow() code.
681 // Therefore I added (JPC) a ugly hack to discard the second call (unwanted) during
682 // execution of the first call (only one call is right).
683 // Note also if there is no change made in editors, this behavior does not happen.
684 static std::atomic<unsigned int> lock_close_event( 0 );
685
686 if( ++lock_close_event > 1 ) // Skip extra calls
687 {
688 return;
689 }
690#endif
691
692 m_leftWin->Show( false );
693 Pgm().m_Quitting = true;
694
695 Destroy();
696
697#ifdef _WINDOWS_
698 lock_close_event = 0; // Reenable event management
699#endif
700}
701
702
704{
706
707 if( !aIsExplicitUserSave && !cfg.ShouldAutoSave() )
708 return;
709
710 cfg.m_OpenJobSets.clear();
711
712 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
713 {
714 if( PANEL_JOBSET* jobset = dynamic_cast<PANEL_JOBSET*>( m_notebook->GetPage( i ) ) )
715 {
716 wxFileName jobsetFn( jobset->GetFilePath() );
717 jobsetFn.MakeRelativeTo( Prj().GetProjectPath() );
718 cfg.m_OpenJobSets.emplace_back( jobsetFn.GetFullPath() );
719 }
720 }
721
722 cfg.SaveToFile( Prj().GetProjectPath() );
723}
724
725
726void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event )
727{
728 Close( true );
729}
730
731
733{
734 if( !Kiway().PlayersClose( false ) )
735 return false;
736
737 // Abort any in-progress background load, since the threads depend on the project not changing
738 KIFACE *schface = Kiway().KiFACE( KIWAY::FACE_SCH );
739 schface->CancelPreload();
740
741 KIFACE *pcbface = Kiway().KiFACE( KIWAY::FACE_PCB );
742 pcbface->CancelPreload();
743
744 // Save the project file for the currently loaded project.
745 if( m_active_project )
746 {
748
749 if( Prj().GetLocalSettings().ShouldAutoSave() && Prj().GetProjectFile().ShouldAutoSave() )
750 {
752
753 if( aSave )
754 mgr.SaveProject();
755 }
756
757 // Ensure the Last_Save tag is at HEAD before closing. This handles the case where
758 // autosave commits were made after the last explicit save - without this, the next
759 // project load would offer to restore the autosave state, which is incorrect after
760 // a clean close.
761 wxString projPath = Prj().GetProjectPath();
762
763 if( !projPath.IsEmpty() && Kiway().LocalHistory().HistoryExists( projPath ) )
764 {
765 if( Kiway().LocalHistory().HeadNewerThanLastSave( projPath ) )
766 {
767 // Commit the current on-disk state and tag it so Last_Save matches HEAD
768 if( Kiway().LocalHistory().CommitFullProjectSnapshot( projPath, wxS( "Close" ) ) )
769 {
770 Kiway().LocalHistory().TagSave( projPath, wxS( "project" ) );
771 }
772 }
773 }
774
775 m_active_project = false;
776 // Enforce local history size limit (if enabled) once all pending saves/backups are done.
777 if( Pgm().GetCommonSettings() && Pgm().GetCommonSettings()->m_Backup.enabled )
778 {
780
781 if( limit > 0 )
782 Kiway().LocalHistory().EnforceSizeLimit( Prj().GetProjectPath(), (size_t) limit );
783 }
784
785 // Unregister the project saver before unloading the project to prevent
786 // dangling references
788
789 mgr.UnloadProject( &Prj() );
790 }
791
792 SetStatusText( "" );
793
794 // Traverse pages in reverse order so deleting them doesn't mess up our iterator.
795 for( int i = (int) m_notebook->GetPageCount() - 1; i >= 0; i-- )
796 {
797 wxWindow* page = m_notebook->GetPage( i );
798
799 if( PANEL_NOTEBOOK_BASE* panel = dynamic_cast<PANEL_NOTEBOOK_BASE*>( page ) )
800 {
801 if( panel->GetProjectTied() )
802 m_notebook->DeletePage( i );
803 }
804 }
805
806 m_leftWin->EmptyTreePrj();
808
809 return true;
810}
811
812
813void KICAD_MANAGER_FRAME::OpenJobsFile( const wxFileName& aFileName, bool aCreate,
814 bool aResaveProjectPreferences )
815{
816 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
817 {
818 if( PANEL_JOBSET* panel = dynamic_cast<PANEL_JOBSET*>( m_notebook->GetPage( i ) ) )
819 {
820 if( aFileName.GetFullPath() == panel->GetFilePath() )
821 {
822 m_notebook->SetSelection( i );
823 return;
824 }
825 }
826 }
827
828 try
829 {
830 std::unique_ptr<JOBSET> jobsFile = std::make_unique<JOBSET>( aFileName.GetFullPath().ToStdString() );
831
832 jobsFile->LoadFromFile();
833
834 if( aCreate && !aFileName.FileExists() )
835 {
836 JOBSET_DESTINATION* dest = jobsFile->AddNewDestination( JOBSET_DESTINATION_T::FOLDER );
837 dest->m_outputHandler->SetOutputPath( aFileName.GetName() );
838 jobsFile->SaveToFile( wxEmptyString, true );
839 }
840
841 PANEL_JOBSET* jobPanel = new PANEL_JOBSET( m_notebook, this, std::move( jobsFile ) );
842 jobPanel->SetProjectTied( true );
843 jobPanel->SetClosable( true );
844 m_notebook->AddPage( jobPanel, aFileName.GetFullName(), true );
846
847 if( aResaveProjectPreferences )
849 }
850 catch( ... )
851 {
852 DisplayErrorMessage( this, _( "Error opening jobs file" ) );
853 }
854}
855
856
857void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
858{
859 // The project file should be valid by the time we get here or something has gone wrong.
860 if( !aProjectFileName.Exists() )
861 return;
862
863 wxString fullPath = aProjectFileName.GetFullPath();
864
865 // Check project lock BEFORE loading so Cancel can actually abort
866 LOCKFILE lockFile( fullPath );
867 bool lockOverrideGranted = false;
868
869 if( !lockFile.Valid() && lockFile.IsLockedByMe() )
870 {
871 // If we cannot acquire the lock but we appear to be the one who locked it, check to
872 // see if there is another KiCad instance running. If not, then we can override the
873 // lock. This could happen if KiCad crashed or was interrupted.
874 if( !Pgm().SingleInstance()->IsAnotherRunning() )
875 lockFile.OverrideLock();
876 }
877
878 if( !lockFile.Valid() )
879 {
880 wxString msg;
881 msg.Printf( _( "Project '%s' is already open by '%s' at '%s'." ),
882 fullPath, lockFile.GetUsername(), lockFile.GetHostname() );
883
884 if( !AskOverrideLock( this, msg ) )
885 return; // User clicked Cancel - abort project loading entirely
886
887 lockFile.OverrideLock();
888 lockOverrideGranted = true;
889 }
890
891 // Any open KIFACE's must be closed if they are not part of the new project.
892 // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.)
893 // User is prompted here to close those KIWAY_PLAYERs:
894 if( !CloseProject( true ) )
895 return;
896
897 m_active_project = true;
898
899 // NB: when loading a legacy project SETTINGS_MANAGER::LoadProject() will convert it to
900 // current extension. Be very careful with aProjectFileName vs. Prj().GetProjectPath()
901 // from here on out.
902
903 Pgm().GetSettingsManager().LoadProject( fullPath );
904
905 // Propagate lock override decision to the loaded project
906 if( lockOverrideGranted )
907 Prj().SetLockOverrideGranted( true );
908
909 LoadWindowState( aProjectFileName.GetFullName() );
910
911 if( aProjectFileName.IsDirWritable() )
912 SetMruPath( Prj().GetProjectPath() );
913
914 Kiway().LocalHistory().Init( Prj().GetProjectPath() );
915
916 if( Kiway().LocalHistory().HeadNewerThanLastSave( Prj().GetProjectPath() ) )
917 {
918 wxString head = Kiway().LocalHistory().GetHeadHash( Prj().GetProjectPath() );
919 if( wxMessageBox( _( "A newer local history snapshot is available. Restore it?" ),
920 _( "Restore" ), wxYES_NO | wxICON_QUESTION, this ) == wxYES )
921 {
922 Kiway().LocalHistory().RestoreCommit( Prj().GetProjectPath(), head, this );
923 }
924 else
925 {
926 // User declined to restore - commit the current on-disk state and tag it
927 // so we don't prompt again on next load
928 if( Kiway().LocalHistory().CommitFullProjectSnapshot( Prj().GetProjectPath(),
929 wxS( "Declined restore" ) ) )
930 {
931 Kiway().LocalHistory().TagSave( Prj().GetProjectPath(), wxS( "project" ) );
932 }
933 }
934 }
935
936 // Save history & window state to disk now. Don't wait around for a crash.
937 KICAD_SETTINGS* settings = kicadSettings();
938 SaveSettings( settings );
939 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
940
941 m_leftWin->ReCreateTreePrj();
942 m_historyPane->RefreshHistory( Prj().GetProjectPath() );
943
944 for( const wxString& jobset : Prj().GetLocalSettings().m_OpenJobSets )
945 {
946 wxFileName jobsetFn( jobset );
947 jobsetFn.MakeAbsolute( Prj().GetProjectPath() );
948
949 if( jobsetFn.Exists() )
950 OpenJobsFile( jobsetFn.GetFullPath(), false, false );
951 }
952
953 // Always start with the apps page
954 m_notebook->SetSelection( 0 );
955
956 // Rebuild the list of watched paths.
957 // however this is possible only when the main loop event handler is running,
958 // so we use it to run the rebuild function.
959 wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
960
961 wxPostEvent( this, cmd );
962
963 PrintPrjInfo();
964
965 KIPLATFORM::APP::RegisterApplicationRestart( aProjectFileName.GetFullPath() );
966 m_openSavedWindows = true;
967
968 KIPLATFORM::ENV::AddToRecentDocs( aProjectFileName.GetFullPath() );
969
970 // Now that we have a new project, trigger a library preload, which will load in any
971 // project-specific symbol and footprint libraries into the manager
972 CallAfter( [&]()
973 {
974 KIFACE *schface = Kiway().KiFACE( KIWAY::FACE_SCH );
975 schface->PreloadLibraries( &Kiway() );
976
977 KIFACE *pcbface = Kiway().KiFACE( KIWAY::FACE_PCB );
978 pcbface->PreloadLibraries( &Kiway() );
979
981 } );
982}
983
984
985void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName, bool aCreateStubFiles )
986{
987 wxCHECK_RET( aProjectFileName.DirExists() && aProjectFileName.IsDirWritable(),
988 "Project folder must exist and be writable to create a new project." );
989
990 // If the project is legacy, convert it
991 if( !aProjectFileName.FileExists() )
992 {
993 wxFileName legacyPro( aProjectFileName );
994 legacyPro.SetExt( FILEEXT::LegacyProjectFileExtension );
995
996 if( legacyPro.FileExists() )
997 {
998 GetSettingsManager()->LoadProject( legacyPro.GetFullPath() );
1000
1001 wxRemoveFile( legacyPro.GetFullPath() );
1002 }
1003 else
1004 {
1005 // Copy template project file from template folder.
1006 wxString srcFileName = sys_search().FindValidPath( "kicad.kicad_pro" );
1007
1008 wxFileName destFileName( aProjectFileName );
1009 destFileName.SetExt( FILEEXT::ProjectFileExtension );
1010
1011 // Create a minimal project file if the template project file could not be copied
1012 if( !wxFileName::FileExists( srcFileName )
1013 || !wxCopyFile( srcFileName, destFileName.GetFullPath() ) )
1014 {
1015 wxFFile file( destFileName.GetFullPath(), "wb" );
1016
1017 if( file.IsOpened() )
1018 file.Write( wxT( "{\n}\n") );
1019
1020 // wxFFile dtor will close the file
1021 }
1022 }
1023 }
1024
1025 // Create a "stub" for a schematic root sheet and a board if requested.
1026 // It will avoid messages from the schematic editor or the board editor to create a new file
1027 // And forces the user to create main files under the right name for the project manager
1028 if( aCreateStubFiles )
1029 {
1030 wxFileName fn( aProjectFileName.GetFullPath() );
1032
1033 // If a <project>.kicad_sch file does not exist, create a "stub" file ( minimal schematic
1034 // file ).
1035 if( !fn.FileExists() )
1036 {
1037 wxFFile file( fn.GetFullPath(), "wb" );
1038
1039 if( file.IsOpened() )
1040 {
1041 file.Write( wxString::Format( "(kicad_sch\n"
1042 "\t(version %d)\n"
1043 "\t(generator \"eeschema\")\n"
1044 "\t(generator_version \"%s\")\n"
1045 "\t(uuid %s)\n"
1046 "\t(paper \"A4\")\n"
1047 "\t(lib_symbols)\n"
1048 "\t(sheet_instances\n"
1049 "\t\t(path \"/\"\n"
1050 "\t\t\t(page \"1\")\n"
1051 "\t\t)\n"
1052 "\t)\n"
1053 "\t(embedded_fonts no)\n"
1054 ")",
1056 KIID().AsString() ) );
1057 }
1058
1059 // wxFFile dtor will close the file
1060 }
1061
1062 // If a <project>.kicad_pcb or <project>.brd file does not exist,
1063 // create a .kicad_pcb "stub" file
1064 fn.SetExt( FILEEXT::KiCadPcbFileExtension );
1065 wxFileName leg_fn( fn );
1066 leg_fn.SetExt( FILEEXT::LegacyPcbFileExtension );
1067
1068 if( !fn.FileExists() && !leg_fn.FileExists() )
1069 {
1070 wxFFile file( fn.GetFullPath(), "wb" );
1071
1072 if( file.IsOpened() )
1073 {
1074 // Create a small dummy file as a stub for pcbnew:
1075 file.Write( wxString::Format( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n)",
1077 }
1078
1079 // wxFFile dtor will close the file
1080 }
1081 }
1082
1083 // Save history & window state to disk now. Don't wait around for a crash.
1084 KICAD_SETTINGS* settings = kicadSettings();
1085 SaveSettings( settings );
1086 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
1087
1088 m_openSavedWindows = true;
1089}
1090
1091
1093{
1094 // show all files in file dialog (in Kicad all files are editable texts):
1095 wxString wildcard = FILEEXT::AllFilesWildcard();
1096
1097 wxString default_dir = Prj().GetProjectPath();
1098
1099 wxFileDialog dlg( this, _( "Edit File in Text Editor" ), default_dir, wxEmptyString, wildcard,
1100 wxFD_OPEN );
1101
1102 if( dlg.ShowModal() == wxID_CANCEL )
1103 return;
1104
1105 wxString filename = dlg.GetPath();
1106
1107 if( !dlg.GetPath().IsEmpty() && !Pgm().GetTextEditor().IsEmpty() )
1108 m_toolManager->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::openTextEditor, &filename );
1109}
1110
1111
1112void KICAD_MANAGER_FRAME::OnEditAdvancedCfg( wxCommandEvent& WXUNUSED( event ) )
1113{
1114 DIALOG_EDIT_CFG dlg( this );
1115 dlg.ShowModal();
1116}
1117
1118
1120{
1121 m_leftWin->ReCreateTreePrj();
1122}
1123
1124
1125void KICAD_MANAGER_FRAME::language_change( wxCommandEvent& event )
1126{
1127 int id = event.GetId();
1128 Kiway().SetLanguage( id );
1129}
1130
1131
1133{
1134 // call my base class
1136
1137 // tooltips in toolbars
1139 m_launcher->CreateLaunchers();
1140
1141 // update captions
1142 int pageId = m_notebook->FindPage( m_launcher );
1143
1144 if( pageId != wxNOT_FOUND )
1145 m_notebook->SetPageText( pageId, EDITORS_CAPTION );
1146
1147 m_auimgr.GetPane( m_leftWin ).Caption( PROJECT_FILES_CAPTION );
1148 m_auimgr.Update();
1149
1150 m_leftWin->FileWatcherReset();
1151
1152 PrintPrjInfo();
1153}
1154
1155
1157{
1159
1160 if( m_pcm && ( aFlags & ENVVARS_CHANGED ) )
1161 m_pcm->ReadEnvVar();
1162
1163 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
1164
1165 if( m_lastToolbarIconSize == 0
1167 {
1170 }
1171
1172 m_leftWin->ReCreateTreePrj();
1173}
1174
1175
1177{
1178 wxString file = GetProjectFileName();
1179
1180 // empty file string means no project loaded
1181 if( !Prj().IsNullProject() &&
1182 Prj().GetProjectLock() == nullptr )
1183 {
1184 LOCKFILE lockFile( file );
1185
1186 if( !lockFile.Valid() && lockFile.IsLockedByMe() )
1187 {
1188 // If we cannot acquire the lock but we appear to be the one who
1189 // locked it, check to see if there is another KiCad instance running.
1190 // If there is not, then we can override the lock. This could happen if
1191 // KiCad crashed or was interrupted
1192 if( !Pgm().SingleInstance()->IsAnotherRunning() )
1193 {
1194 lockFile.OverrideLock();
1195 }
1196 }
1197
1198 if( !lockFile.Valid() )
1199 {
1200 wxString msg;
1201 msg.Printf( _( "Project '%s' is already open by '%s' at '%s'." ), file, lockFile.GetUsername(),
1202 lockFile.GetHostname() );
1203
1204 if( AskOverrideLock( this, msg ) )
1205 {
1206 lockFile.OverrideLock();
1207 }
1208 }
1209
1210 Prj().SetReadOnly( !lockFile.Valid() || Prj().GetProjectFile().IsReadOnly() );
1211 Prj().SetProjectLock( new LOCKFILE( std::move( lockFile ) ) );
1212 }
1213
1214 wxString title;
1215
1216 if( !file.IsEmpty() )
1217 {
1218 wxFileName fn( file );
1219
1220 title = fn.GetName();
1221
1222 if( Prj().IsReadOnly() )
1223 title += wxS( " " ) + _( "[Read Only]" );
1224 }
1225 else
1226 {
1227 title = _( "[no project loaded]" );
1228 }
1229
1230 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
1231 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad" ) );
1232 else
1233 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad " ) ) + GetMajorMinorVersion();
1234
1235 SetTitle( title );
1236
1237 // Register project file saver. Ensures project file participates in
1238 // autosave history commits without affecting dirty state.
1240 [this]( const wxString& aProjectPath, std::vector<wxString>& aFiles )
1241 {
1242 Prj().SaveToHistory( aProjectPath, aFiles );
1243 } );
1244}
1245
1246
1248{
1250
1251 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
1252
1253 wxCHECK( settings, /*void*/ );
1254
1255 m_leftWinWidth = settings->m_LeftWinWidth;
1256 m_showHistoryPanel = settings->m_ShowHistoryPanel;
1257}
1258
1259
1261{
1263
1264 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
1265
1266 wxCHECK( settings, /*void*/);
1267
1268 settings->m_LeftWinWidth = m_leftWin->GetSize().x;
1269 settings->m_ShowHistoryPanel = m_historyPane &&
1270 m_auimgr.GetPane( m_historyPane ).IsShown();
1271
1272 if( !m_isClosing )
1273 settings->m_OpenProjects = GetSettingsManager()->GetOpenProjects();
1274}
1275
1276
1278{
1279 // wxStatusBar's wxELLIPSIZE_MIDDLE flag doesn't work (at least on Mac).
1280
1281 wxString status = wxString::Format( _( "Project: %s" ), Prj().GetProjectFullName() );
1282 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
1283 statusBar->SetEllipsedTextField( status, 0 );
1284}
1285
1286
1291
1292
1293void KICAD_MANAGER_FRAME::OnIdle( wxIdleEvent& aEvent )
1294{
1300 if( !m_openSavedWindows )
1301 return;
1302
1303 m_openSavedWindows = false;
1304
1305 if( Pgm().GetCommonSettings()->m_Session.remember_open_files )
1306 {
1307 int previousOpenCount =
1308 std::count_if( Prj().GetLocalSettings().m_files.begin(),
1309 Prj().GetLocalSettings().m_files.end(),
1310 [&]( const PROJECT_FILE_STATE& f )
1311 {
1312 return !f.fileName.EndsWith( FILEEXT::ProjectFileExtension ) && f.open;
1313 } );
1314
1315 if( previousOpenCount > 0 )
1316 {
1317 APP_PROGRESS_DIALOG progressReporter( _( "Restoring session" ), wxEmptyString,
1318 previousOpenCount, this );
1319
1320 // We don't currently support opening more than one view per file
1321 std::set<wxString> openedFiles;
1322
1323 int i = 0;
1324
1325 for( const PROJECT_FILE_STATE& file : Prj().GetLocalSettings().m_files )
1326 {
1327 if( file.open && !openedFiles.count( file.fileName ) )
1328 {
1329 progressReporter.Update( i++, wxString::Format( _( "Restoring '%s'" ), file.fileName ) );
1330
1331 openedFiles.insert( file.fileName );
1332 wxFileName fn( file.fileName );
1333
1334 if( fn.GetExt() == FILEEXT::LegacySchematicFileExtension
1335 || fn.GetExt() == FILEEXT::KiCadSchematicFileExtension )
1336 {
1338 }
1339 else if( fn.GetExt() == FILEEXT::LegacyPcbFileExtension
1340 || fn.GetExt() == FILEEXT::KiCadPcbFileExtension )
1341 {
1343 }
1344 }
1345
1346 wxYield();
1347 }
1348 }
1349 }
1350
1351 // clear file states regardless if we opened windows or not due to setting
1353
1354 // After restore from history, mark open editors as dirty so user is prompted to save
1356 {
1357 m_restoredFromHistory = false;
1358
1359 // Mark schematic editor as dirty if open
1360 if( KIWAY_PLAYER* schFrame = Kiway().Player( FRAME_SCH, false ) )
1361 schFrame->OnModify();
1362
1363 // Mark PCB editor as dirty if open
1364 if( KIWAY_PLAYER* pcbFrame = Kiway().Player( FRAME_PCB_EDITOR, false ) )
1365 pcbFrame->OnModify();
1366 }
1367
1368 KICAD_SETTINGS* settings = kicadSettings();
1369
1371 && settings->m_PcmUpdateCheck )
1372 {
1373 if( !m_pcm )
1374 CreatePCM();
1375
1376 m_pcm->RunBackgroundUpdate();
1377 }
1378
1379#ifdef KICAD_UPDATE_CHECK
1380 if( !m_updateManager && settings->m_KiCadUpdateCheck )
1381 {
1382 m_updateManager = std::make_unique<UPDATE_MANAGER>();
1383 m_updateManager->CheckForUpdate( this );
1384 }
1385#endif
1386
1387 // This little diddy is needed to get the window put into the Mac dock icon's context menu.
1388 Raise();
1389}
1390
1391
1393{
1394 m_pcmButton = aButton;
1395
1397}
1398
1399
1401{
1402 if( m_pcmButton )
1403 {
1404 if( m_pcmUpdateCount > 0 )
1405 {
1406 m_pcmButton->SetShowBadge( true );
1407 m_pcmButton->SetBadgeText( wxString::Format( "%d", m_pcmUpdateCount ) );
1408 }
1409 else
1410 {
1411 m_pcmButton->SetShowBadge( false );
1412 }
1413
1414 m_pcmButton->Refresh();
1415 }
1416}
1417
1418
1420{
1421 // No idea why, but the same mechanism used in EDA_DRAW_FRAME doesn't work here
1422 // the only thing that seems to work is to blow it all up and start from scratch.
1423 m_auimgr.DetachPane( m_tbLeft );
1424 delete m_tbLeft;
1425 m_tbLeft = nullptr;
1427 m_auimgr.AddPane( m_tbLeft, EDA_PANE().HToolbar().Name( "TopMainToolbar" ).Left()
1428 .Layer( 2 ) );
1429
1430 m_auimgr.Update();
1431}
1432
1433
1435{
1436 wxAuiPaneInfo& pane = m_auimgr.GetPane( m_historyPane );
1437 bool show = !pane.IsShown();
1438 pane.Show( show );
1439
1440 if( show )
1441 m_historyPane->RefreshHistory( Prj().GetProjectPath() );
1442
1443 m_auimgr.Update();
1444}
1445
1446
1448{
1449 if( !Kiway().PlayersClose( true ) )
1450 return;
1451
1452 if( Kiway().LocalHistory().RestoreCommit( Prj().GetProjectPath(), aHash, this ) )
1453 {
1454 m_restoredFromHistory = true; // Mark editors dirty when they reopen
1455 }
1456
1457 m_leftWin->ReCreateTreePrj();
1458 m_openSavedWindows = true;
1459 m_historyPane->RefreshHistory( Prj().GetProjectPath() );
1460}
1461
1462
1464{
1465 return m_historyPane && m_auimgr.GetPane( m_historyPane ).IsShown();
1466}
const char * name
constexpr EDA_IU_SCALE unityScale
Definition base_units.h:115
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_nightly
@ 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:80
static TOOL_ACTION saveAs
Definition actions.h:59
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION cut
Definition actions.h:77
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.
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.
Handle actions that are shared between different applications.
APPEARANCE m_Appearance
AUTO_BACKUP m_Backup
The base frame for deriving all KiCad main window classes.
void LoadWindowState(const wxString &aFileName)
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
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 RecreateToolbars()
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
ACTION_TOOLBAR * m_tbLeft
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associate file 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)
bool m_isClosing
Set by the close window event handler after frames are asked if they can close.
Specialization of the wxAuiPaneInfo class for KiCad panels.
void SetOutputPath(const wxString &aPath)
Definition jobs_output.h:56
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 loadProject
static TOOL_ACTION showLocalHistory
static TOOL_ACTION editSchematic
static TOOL_ACTION openTextEditor
static TOOL_ACTION archiveProject
static TOOL_ACTION closeProject
static TOOL_ACTION openJobsetFile
static TOOL_ACTION newJobsetFile
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 CreateNewProject(const wxFileName &aProjectFileName, bool aCreateStubFiles=true)
Creates a new project by setting up and initial project, schematic, and board files.
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
void OnImportAltiumProjectFiles(wxCommandEvent &event)
Open dialog to import Altium project files.
const wxString GetProjectFileName() const
KICAD_SETTINGS * kicadSettings() const
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 OpenJobsFile(const wxFileName &aFileName, bool aCreate=false, bool aResaveProjectPreferences=true)
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 RestoreCommitFromHistory(const wxString &aHash)
void DoWithAcceptedFiles() override
Execute action on accepted dropped file.
void OnOpenFileInTextEditor(wxCommandEvent &event)
APP_SETTINGS_BASE * config() const override
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
const wxString PcbLegacyFileName()
void OnEditAdvancedCfg(wxCommandEvent &event)
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 onNotebookPageCloseRequest(wxAuiNotebookEvent &evt)
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void OnIdle(wxIdleEvent &event)
void PrintPrjInfo()
Prints the current working directory name and the project name on the text panel.
void SaveOpenJobSetsToLocalSettings(bool aIsExplicitUserSave=false)
bool m_restoredFromHistory
Set after restore to mark editors dirty.
void onNotebookPageCountChanged(wxAuiNotebookEvent &evt)
LOCAL_HISTORY_PANE * m_historyPane
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
void HideTabsIfNeeded()
Hides the tabs for Editor notebook if there is only 1 page.
wxString help_name() override
std::unique_ptr< UPDATE_MANAGER > m_updateManager
std::vector< wxString > m_OpenProjects
Definition kiid.h:49
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.
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.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition kiway.cpp:526
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition kiway.cpp:206
@ FACE_SCH
eeschema DSO
Definition kiway.h:301
@ FACE_PCB
pcbnew DSO
Definition kiway.h:302
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:406
bool TagSave(const wxString &aProjectPath, const wxString &aFileType)
Tag a manual save in the local history repository.
wxString GetHeadHash(const wxString &aProjectPath)
Return the current head commit hash.
bool RestoreCommit(const wxString &aProjectPath, const wxString &aHash, wxWindow *aParent=nullptr)
Restore the project files to the state recorded by the given commit hash.
bool EnforceSizeLimit(const wxString &aProjectPath, size_t aMaxBytes)
Enforce total size limit by rebuilding trimmed history keeping newest commits whose cumulative unique...
bool Init(const wxString &aProjectPath)
Initialize the local history repository for the given project path.
void UnregisterSaver(const void *aSaverObject)
Unregister a previously registered saver callback.
void RegisterSaver(const void *aSaverObject, const std::function< void(const wxString &, std::vector< wxString > &)> &aSaver)
Register a saver callback invoked during autosave history commits.
bool OverrideLock(bool aRemoveOnRelease=true)
Force the lock, overwriting the data that existed already.
Definition lockfile.h:174
bool Valid() const
Definition lockfile.h:254
wxString GetUsername()
Definition lockfile.h:236
wxString GetHostname()
Definition lockfile.h:242
bool IsLockedByMe()
Definition lockfile.h:227
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)
Create 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)
Remove status bar from handling.
static REPORTER & GetInstance()
Definition reporter.cpp:97
void SetClosable(bool aYes)
void SetProjectTied(bool aYes)
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:535
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
Definition pgm_base.cpp:881
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:138
void UnregisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Unregister a status bar from receiving library load warning messages.
Definition pgm_base.cpp:973
bool m_Quitting
Definition pgm_base.h:395
void RegisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Register a status bar to receive library load warning messages.
Definition pgm_base.cpp:953
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
Definition pgm_base.h:143
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:132
wxString GetHelpFileName()
Definition pgm_kicad.h:63
SEARCH_STACK & SysSearch()
Definition pgm_kicad.h:61
APP_SETTINGS_BASE * PgmSettings()
Definition pgm_kicad.h:59
The project local settings are things that are attached to a particular project, but also might be pa...
bool SaveToFile(const wxString &aDirectory="", bool aForce=false) override
Calls Store() and then writes the contents of the JSON document to a file.
std::vector< wxString > m_OpenJobSets
PROJECT_TREE_PANE Window to display the tree files.
void SetProjectLock(LOCKFILE *aLockFile)
Definition project.cpp:446
virtual void SetReadOnly(bool aReadOnly=true)
Definition project.h:163
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition project.cpp:162
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:168
void SaveToHistory(const wxString &aProjectPath, std::vector< wxString > &aFiles)
Save project files (.kicad_pro and .kicad_prl) to the .history directory.
Definition project.cpp:452
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:209
virtual void SetLockOverrideGranted(bool aGranted=true)
Definition project.h:167
Look for files in a number of paths.
static bool ShowNever(const SELECTION &aSelection)
Always returns false.
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
bool IsProjectOpen() const
Helper for checking if we have a project open.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Save, unload and unregister the given PROJECT.
std::vector< wxString > GetOpenProjects() const
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Call BackupProject() if a new backup is needed according to the current backup policy.
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
ACTIONS * m_actions
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
bool AskOverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
Definition confirm.cpp:42
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
This file is part of the common library.
#define ENABLE(x)
#define _(s)
Base window classes and related definitions.
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define KICAD_MANAGER_FRAME_NAME
EVT_MENU_RANGE(ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILEMAX, GERBVIEW_FRAME::OnDrlFileHistory) EVT_MENU_RANGE(ID_GERBVIEW_ZIP_FILE1
KiCad executable names.
const wxString GERBVIEW_EXE
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_SCH
Definition frame_type.h:34
@ 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:61
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:62
@ ID_LANGUAGE_CHOICE
Definition id.h:66
@ ID_FILEMAX
Definition id.h:60
@ ID_LANGUAGE_CHOICE_END
Definition id.h:110
@ ID_FILE1
Definition id.h:59
PGM_KICAD & PgmTop()
Definition kicad.cpp:87
@ ID_EDIT_ADVANCED_CFG
Definition kicad_id.h:38
@ ID_IMPORT_EAGLE_PROJECT
Definition kicad_id.h:40
@ ID_IMPORT_EASYEDAPRO_PROJECT
Definition kicad_id.h:42
@ ID_IMPORT_CADSTAR_ARCHIVE_PROJECT
Definition kicad_id.h:39
@ ID_EDIT_LOCAL_FILE_IN_TEXT_EDITOR
Definition kicad_id.h:37
@ ID_IMPORT_EASYEDA_PROJECT
Definition kicad_id.h:41
@ ID_IMPORT_ALTIUM_PROJECT
Definition kicad_id.h:43
#define EDITORS_CAPTION
#define ID_INIT_WATCHED_PATHS
#define PROJECT_FILES_CAPTION
File locking utilities.
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
void AddToRecentDocs(const wxString &aPath)
PBOOL GetPolicyBool(const wxString &aKey)
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
#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.
#define POLICY_KEY_PCM
Definition policy_keys.h:31
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
T * GetToolbarSettings(const wxString &aFilename)
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)
unsigned long long limit_total_size
Maximum total size of backups (bytes), 0 for unlimited.
std::shared_ptr< JOBS_OUTPUT_HANDLER > m_outputHandler
Definition jobset.h:136
Implement a participant in the KIWAY alchemy.
Definition kiway.h:155
virtual void PreloadLibraries(KIWAY *aKiway)
Definition kiway.h:258
virtual void CancelPreload(bool aBlock=true)
Definition kiway.h:260
#define ENVVARS_CHANGED
Definition of file extensions used in Kicad.