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/ui.h>
52#include <kiplatform/policy.h>
53#include <build_version.h>
54#include <kiway.h>
55#include <kiway_mail.h>
56#include <launch_ext.h>
57#include <lockfile.h>
59#include <reporter.h>
61#include <sch_file_versions.h>
64#include <tool/action_manager.h>
65#include <tool/action_toolbar.h>
66#include <tool/common_control.h>
68#include <tool/tool_manager.h>
74#include <widgets/kistatusbar.h>
75#include <wx/ffile.h>
76#include <wx/filedlg.h>
77#include <wx/dnd.h>
78#include <wx/process.h>
79#include <wx/snglinst.h>
80#include <atomic>
81#include <update_manager.h>
82#include <jobs/jobset.h>
84
85#include <../pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h> // for SEXPR_BOARD_FILE_VERSION def
86
87
88#ifdef __WXMAC__
89#include <MacTypes.h>
90#include <ApplicationServices/ApplicationServices.h>
91#endif
92
93#include "kicad_manager_frame.h"
95
97
98
99#define EDITORS_CAPTION _( "Editors" )
100#define PROJECT_FILES_CAPTION _( "Project Files" )
101
102#define ID_INIT_WATCHED_PATHS 52913
103
104#define SEP() wxFileName::GetPathSeparator()
105
106
107// Menubar and toolbar event table
108BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
109 // Window events
112
113 // Menu events
114 EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit )
124
125 // Range menu events
128
129 // Special functions
131
132 // Drop files event
133 EVT_DROP_FILES( KICAD_MANAGER_FRAME::OnDropFiles )
134
135END_EVENT_TABLE()
136
137// See below the purpose of this include
138#include <wx/xml/xml.h>
139
140KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title,
141 const wxPoint& pos, const wxSize& size ) :
144 m_openSavedWindows( false ),
145 m_restoredFromHistory( false ),
146 m_active_project( false ),
147 m_showHistoryPanel( false ),
148 m_projectTreePane( nullptr ),
149 m_historyPane( nullptr ),
150 m_launcher( nullptr ),
152 m_pcmButton( nullptr ),
154{
155 const int defaultLeftWinWidth = FromDIP( 250 );
156
157 m_leftWinWidth = defaultLeftWinWidth; // Default value
158 m_aboutTitle = "KiCad";
159
160 // JPC: A very ugly hack to fix an issue on Linux: if the wxbase315u_xml_gcc_custom.so is
161 // used **only** in PCM, it is not found in some cases at run time.
162 // So just use it in the main module to avoid a not found issue
163 // wxbase315u_xml_gcc_custom shared object when launching Kicad
164 wxXmlDocument dummy;
165
166 // Create the status line (bottom of the frame). Left half is for project name; right half
167 // is for Reporter (currently used by archiver/unarchiver and PCM).
168 // Note: this is a KISTATUSBAR status bar. Therefore the specified number of fields
169 // is the extra number of fields, not the full field count.
170 // We need here 2 fields: the extra fiels to display the project name, and another field
171 // to display a info (specific to Windows) using the FIELD_OFFSET_BGJOB_TEXT id offset (=1)
172 // So the extra field count is 1
173 CreateStatusBar( 2 );
176 Pgm().RegisterLibraryLoadStatusBar( (KISTATUSBAR*) GetStatusBar() );
177 GetStatusBar()->SetFont( KIUI::GetStatusFont( this ) );
178
179 // Give an icon
180 wxIcon icon;
181 wxIconBundle icon_bundle;
182
183 if( IsNightlyVersion())
184 {
185 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 48 ) );
186 icon_bundle.AddIcon( icon );
187 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 128 ) );
188 icon_bundle.AddIcon( icon );
189 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly, 256 ) );
190 icon_bundle.AddIcon( icon );
191 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly_32 ) );
192 icon_bundle.AddIcon( icon );
193 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_nightly_16 ) );
194 icon_bundle.AddIcon( icon );
195 }
196 else
197 {
198 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 48 ) );
199 icon_bundle.AddIcon( icon );
200 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 128 ) );
201 icon_bundle.AddIcon( icon );
202 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad, 256 ) );
203 icon_bundle.AddIcon( icon );
204 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_32 ) );
205 icon_bundle.AddIcon( icon );
206 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_kicad_16 ) );
207 icon_bundle.AddIcon( icon );
208 }
209
210 SetIcons( icon_bundle );
211
212 // Load the settings
213 LoadSettings( config() );
214
215 // Left window: is the box which display tree project
217
218 setupTools();
220
225
226 m_auimgr.SetManagedWindow( this );
227 m_auimgr.SetFlags( wxAUI_MGR_LIVE_RESIZE );
228
229 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( "TopMainToolbar" ).Left().Layer( 2 ) );
230
231 // There is no wxAUIPaneInfo::SetSize(), but a trick is to use MinSize() to set the required pane width,
232 // and after give a reasonable MinSize value.
234 EDA_PANE().Palette().Name( "ProjectTree" ).Left().Layer( 1 )
235 .Caption( PROJECT_FILES_CAPTION ).PaneBorder( false )
236 .MinSize( m_leftWinWidth, -1 ).Floatable( false ).Movable( false ) );
237
238 m_historyPane = new LOCAL_HISTORY_PANE( this );
239 m_auimgr.AddPane( m_historyPane,
240 EDA_PANE().Palette().Name( "LocalHistory" ).Left().Layer( 1 ).Position( 1 )
241 .Caption( _( "Local History" ) ).PaneBorder( false )
242 .Floatable( false ).Movable( false ).CloseButton( true ).Hide() );
243
245 m_auimgr.GetPane( m_historyPane ).Show();
246
247 wxSize client_size = GetClientSize();
248 m_notebook = new wxAuiNotebook( this, wxID_ANY, wxPoint( client_size.x, client_size.y ),
249 FromDIP( wxSize( 700, 590 ) ),
250 wxAUI_NB_TOP | wxAUI_NB_CLOSE_ON_ALL_TABS | wxAUI_NB_TAB_MOVE
251 | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER );
252
253 m_notebook->SetArtProvider( new WX_AUI_TAB_ART() );
254
255 m_notebook->Bind( wxEVT_AUINOTEBOOK_PAGE_CLOSE, &KICAD_MANAGER_FRAME::onNotebookPageCloseRequest, this );
256 m_notebook->Bind( wxEVT_AUINOTEBOOK_PAGE_CLOSED, &KICAD_MANAGER_FRAME::onNotebookPageCountChanged, this );
258
259 m_notebook->Freeze();
260 m_launcher->SetClosable( false );
261 m_notebook->AddPage( m_launcher, EDITORS_CAPTION, false );
262 m_notebook->SetTabCtrlHeight( 0 );
263 m_notebook->Thaw();
264
265 m_auimgr.AddPane( m_notebook, EDA_PANE().Canvas().Name( "Editors" ).Center().Caption( EDITORS_CAPTION )
266 .PaneBorder( false ).MinSize( m_notebook->GetBestSize() ) );
267
268 m_auimgr.Update();
269
270 // Now the actual m_projectTreePane size is set, give it a reasonable min width
271 m_auimgr.GetPane( m_projectTreePane ).MinSize( defaultLeftWinWidth, FromDIP( 80 ) );
272
273
274 wxSizer* mainSizer = GetSizer();
275
276 // Only fit the initial window size the first time KiCad is run.
277 if( mainSizer && config()->m_Window.state.size_x == 0 && config()->m_Window.state.size_y == 0 )
278 {
279 Layout();
280 mainSizer->Fit( this );
281 Center();
282 }
283
284 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
285 SetTitle( wxT( "KiCad" ) );
286 else
287 SetTitle( wxString( "KiCad " ) + GetMajorMinorVersion() );
288
289 // Do not let the messages window have initial focus
290 m_projectTreePane->SetFocus();
291
292 // Init for dropping files
295
296 // Gerber files
297 // Note that all gerber files are aliased as GerberFileExtension
301
302 DragAcceptFiles( true );
303
304 // Ensure the window is on top
305 Raise();
306}
307
308
310{
312 Unbind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
313
314 m_notebook->Unbind( wxEVT_AUINOTEBOOK_PAGE_CLOSE, &KICAD_MANAGER_FRAME::onNotebookPageCloseRequest, this );
315 m_notebook->Unbind( wxEVT_AUINOTEBOOK_PAGE_CLOSED, &KICAD_MANAGER_FRAME::onNotebookPageCountChanged, this );
316
319 Pgm().UnregisterLibraryLoadStatusBar( (KISTATUSBAR*) GetStatusBar() );
320
321 // Shutdown all running tools
322 if( m_toolManager )
323 m_toolManager->ShutdownAllTools();
324
325 if( m_pcm )
326 m_pcm->StopBackgroundUpdate();
327
328 // Stop update manager before tearing down the AUI framework. The update
329 // task runs on the thread pool and may call CallAfter on this frame, so it
330 // must complete before we uninitialize AUI or destroy child windows.
331 m_updateManager.reset();
332
333 delete m_actions;
334 delete m_toolManager;
335 delete m_toolDispatcher;
336
337 m_auimgr.UnInit();
338}
339
341{
342 if( m_notebook->GetPageCount() == 1 )
343 m_notebook->SetTabCtrlHeight( 0 );
344 else
345 m_notebook->SetTabCtrlHeight( -1 );
346}
347
348
350{
352}
353
354
356{
357 wxAuiNotebook* notebook = (wxAuiNotebook*) evt.GetEventObject();
358 wxWindow* page = notebook->GetPage( evt.GetSelection() );
359
360 if( PANEL_NOTEBOOK_BASE* panel = dynamic_cast<PANEL_NOTEBOOK_BASE*>( page ) )
361 {
362 if( panel->GetClosable() )
363 {
364 if( !panel->GetCanClose() )
365 evt.Veto();
366
367 CallAfter(
368 [this]()
369 {
371 } );
372 }
373 else
374 {
375 evt.Veto();
376 }
377 }
378}
379
380
381wxStatusBar* KICAD_MANAGER_FRAME::OnCreateStatusBar( int number, long style, wxWindowID id,
382 const wxString& name )
383{
384 return new KISTATUSBAR( number, this, id,
388}
389
390
392{
393 // creates the PLUGIN_CONTENT_MANAGER, if not exists
394 if( m_pcm )
395 return;
396
397 m_pcm = std::make_shared<PLUGIN_CONTENT_MANAGER>(
398 [this]( int aUpdateCount )
399 {
400 if( Pgm().m_Quitting )
401 return;
402
403 m_pcmUpdateCount = aUpdateCount;
404
405 if( aUpdateCount > 0 )
406 {
408 wxS( "pcm" ),
409 _( "PCM Updates Available" ),
410 wxString::Format( _( "%d package update(s) available" ), aUpdateCount ),
411 wxT( "" ) );
412 }
413 else
414 {
415 Pgm().GetNotificationsManager().Remove( wxS( "pcm" ) );
416 }
417
418 CallAfter(
419 [this]()
420 {
422 } );
423 });
424
425 m_pcm->SetRepositoryList( kicadSettings()->m_PcmRepositories );
426}
427
428
430{
431 // Create the manager
433 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
435
437
438 // Attach the events to the tool dispatcher
440 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
441
442 // Register tools
443 m_toolManager->RegisterTool( new COMMON_CONTROL );
444 m_toolManager->RegisterTool( new KICAD_MANAGER_CONTROL );
445 m_toolManager->InitTools();
446}
447
448
450{
452
453 ACTION_MANAGER* manager = m_toolManager->GetActionManager();
454
455 wxASSERT( manager );
456
457 auto activeProject =
458 [this] ( const SELECTION& )
459 {
460 return m_active_project;
461 };
462
463#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
464
465 ACTION_CONDITIONS activeProjectCond;
466 activeProjectCond.Enable( activeProject );
467
468 manager->SetConditions( ACTIONS::saveAs, activeProjectCond );
469 manager->SetConditions( KICAD_MANAGER_ACTIONS::closeProject, activeProjectCond );
470 manager->SetConditions( KICAD_MANAGER_ACTIONS::archiveProject, activeProjectCond );
471 manager->SetConditions( KICAD_MANAGER_ACTIONS::newJobsetFile, activeProjectCond );
472 manager->SetConditions( KICAD_MANAGER_ACTIONS::openJobsetFile, activeProjectCond );
473
474 auto historyCond =
475 [this]( const SELECTION& )
476 {
477 return HistoryPanelShown();
478 };
479
481
482 // These are just here for text boxes, search boxes, etc. in places such as the standard
483 // file dialogs.
487
488#undef ENABLE
489}
490
491
493{
494 return m_projectTreePane;
495}
496
497
499{
501 wxASSERT( ret );
502 return ret;
503}
504
505
507{
508 KICAD_SETTINGS* ret = dynamic_cast<KICAD_SETTINGS*>( config() );
509 wxASSERT( ret );
510 return ret;
511}
512
513
515{
516 CallAfter(
517 [&]()
518 {
519 KIFACE *schface = Kiway().KiFACE( KIWAY::FACE_SCH );
520 schface->PreloadLibraries( &Kiway() );
521
522 KIFACE *pcbface = Kiway().KiFACE( KIWAY::FACE_PCB );
523 pcbface->PreloadLibraries( &Kiway() );
524
526 } );
527}
528
529
531{
532 return GetProjectFileName();
533}
534
535
537{
539 : wxString( wxEmptyString );
540}
541
542
544{
545 wxFileName fn( GetProjectFileName() );
546
548 return fn.GetFullPath();
549}
550
551
553{
554 wxFileName fn( GetProjectFileName() );
555
557 return fn.GetFullPath();
558}
559
560
562{
563 wxFileName fn( GetProjectFileName() );
564
565 fn.SetExt( FILEEXT::PcbFileExtension );
566 return fn.GetFullPath();
567}
568
569
571{
572 wxFileName fn( GetProjectFileName() );
573
575 return fn.GetFullPath();
576}
577
578
580{
581 m_projectTreePane->ReCreateTreePrj();
582}
583
584
589
590
592{
593 return PgmTop().GetHelpFileName();
594}
595
596
597void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
598{
599 if( m_auimgr.GetManagedWindow() )
600 m_auimgr.Update();
601
602 PrintPrjInfo();
603
604#if defined( _WIN32 )
605 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
607#endif
608
609 event.Skip();
610}
611
612
614{
615 // All fileNames are now in m_AcceptedFiles vector.
616 // Check if contains a project file name and load project.
617 // If not, open files in dedicated app.
618 for( const wxFileName& fileName : m_AcceptedFiles )
619 {
620 wxString ext = fileName.GetExt();
621
623 {
624 wxString fn = fileName.GetFullPath();
625 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
626
627 return;
628 }
629 }
630
631 // Then stock gerber files in gerberFiles and run action for other files.
632 wxString gerberFiles;
633
634 // Gerbview editor should be able to open Gerber and drill files
635 for( const wxFileName& fileName : m_AcceptedFiles )
636 {
637 wxString ext = fileName.GetExt();
638
642 {
643 gerberFiles += wxT( '\"' );
644 gerberFiles += fileName.GetFullPath() + wxT( '\"' );
645 gerberFiles = gerberFiles.Pad( 1 );
646 }
647 else
648 {
649 wxString fn = fileName.GetFullPath();
650 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( fileName.GetExt() ), &fn );
651 }
652 }
653
654 // Execute Gerbviewer
655 if( !gerberFiles.IsEmpty() )
656 {
657 wxString fullEditorName = FindKicadFile( GERBVIEW_EXE );
658
659 if( wxFileExists( fullEditorName ) )
660 {
661 wxString command = fullEditorName + " " + gerberFiles;
662 m_toolManager->RunAction<wxString*>( *m_acceptedExts.at( FILEEXT::GerberFileExtension ), &command );
663 }
664 }
665}
666
667
668bool KICAD_MANAGER_FRAME::canCloseWindow( wxCloseEvent& aEvent )
669{
670 KICAD_SETTINGS* settings = kicadSettings();
672
673 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
674 {
675 wxWindow* page = m_notebook->GetPage( i );
676
677 if( PANEL_NOTEBOOK_BASE* panel = dynamic_cast<PANEL_NOTEBOOK_BASE*>( page ) )
678 {
679 if( !panel->GetCanClose() )
680 return false;
681 }
682 }
683
684 // CloseProject will recursively ask all the open editors if they need to save changes.
685 // If any of them cancel then we need to cancel closing the KICAD_MANAGER_FRAME.
686 if( CloseProject( true ) )
687 {
688 // Don't propagate event to frames which have already been closed
689 aEvent.StopPropagation();
690
691 return true;
692 }
693 else
694 {
695 if( aEvent.CanVeto() )
696 aEvent.Veto();
697
698 return false;
699 }
700}
701
702
704{
705#ifdef _WINDOWS_
706 // For some obscure reason, on Windows, when killing Kicad from the Windows task manager
707 // if a editor frame (schematic, library, board editor or fp editor) is open and has
708 // some edition to save, OnCloseWindow is run twice *at the same time*, creating race
709 // conditions between OnCloseWindow() code.
710 // Therefore I added (JPC) a ugly hack to discard the second call (unwanted) during
711 // execution of the first call (only one call is right).
712 // Note also if there is no change made in editors, this behavior does not happen.
713 static std::atomic<unsigned int> lock_close_event( 0 );
714
715 if( ++lock_close_event > 1 ) // Skip extra calls
716 {
717 return;
718 }
719#endif
720
721 m_projectTreePane->Show( false );
722 Pgm().m_Quitting = true;
723
724 Destroy();
725
726#ifdef _WINDOWS_
727 lock_close_event = 0; // Reenable event management
728#endif
729}
730
731
733{
735
736 if( !aIsExplicitUserSave && !cfg.ShouldAutoSave() )
737 return;
738
739 cfg.m_OpenJobSets.clear();
740
741 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
742 {
743 if( PANEL_JOBSET* jobset = dynamic_cast<PANEL_JOBSET*>( m_notebook->GetPage( i ) ) )
744 {
745 wxFileName jobsetFn( jobset->GetFilePath() );
746 jobsetFn.MakeRelativeTo( Prj().GetProjectPath() );
747 cfg.m_OpenJobSets.emplace_back( jobsetFn.GetFullPath() );
748 }
749 }
750
751 cfg.SaveToFile( Prj().GetProjectPath() );
752}
753
754
755void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event )
756{
757 Close( true );
758}
759
760
762{
763 if( !Kiway().PlayersClose( false ) )
764 return false;
765
766 // Abort any in-progress background load, since the threads depend on the project not changing
767 KIFACE *schface = Kiway().KiFACE( KIWAY::FACE_SCH );
768 schface->CancelPreload();
769
770 KIFACE *pcbface = Kiway().KiFACE( KIWAY::FACE_PCB );
771 pcbface->CancelPreload();
772
773 // Save the project file for the currently loaded project.
774 if( m_active_project )
775 {
777
778 if( Prj().GetLocalSettings().ShouldAutoSave() && Prj().GetProjectFile().ShouldAutoSave() )
779 {
781
782 if( aSave )
783 mgr.SaveProject();
784 }
785
786 // Ensure the Last_Save tag is at HEAD before closing. This handles the case where
787 // autosave commits were made after the last explicit save - without this, the next
788 // project load would offer to restore the autosave state, which is incorrect after
789 // a clean close.
790 wxString projPath = Prj().GetProjectPath();
791
792 if( !projPath.IsEmpty() && Kiway().LocalHistory().HistoryExists( projPath ) )
793 {
794 if( Kiway().LocalHistory().HeadNewerThanLastSave( projPath ) )
795 {
796 // Commit the current on-disk state and tag it so Last_Save matches HEAD
797 if( Kiway().LocalHistory().CommitFullProjectSnapshot( projPath, wxS( "Close" ) ) )
798 {
799 Kiway().LocalHistory().TagSave( projPath, wxS( "project" ) );
800 }
801 }
802 }
803
804 m_active_project = false;
805 // Enforce local history size limit (if enabled) once all pending saves/backups are done.
806 if( Pgm().GetCommonSettings() && Pgm().GetCommonSettings()->m_Backup.enabled )
807 {
808 unsigned long long int limit = Pgm().GetCommonSettings()->m_Backup.limit_total_size;
809
810 if( limit > 0 )
811 Kiway().LocalHistory().EnforceSizeLimit( Prj().GetProjectPath(), (size_t) limit );
812 }
813
814 // Unregister the project saver before unloading the project to prevent
815 // dangling references
817
818 mgr.UnloadProject( &Prj() );
819 }
820
821 SetStatusText( "" );
822
823 // Traverse pages in reverse order so deleting them doesn't mess up our iterator.
824 for( int i = (int) m_notebook->GetPageCount() - 1; i >= 0; i-- )
825 {
826 wxWindow* page = m_notebook->GetPage( i );
827
828 if( PANEL_NOTEBOOK_BASE* panel = dynamic_cast<PANEL_NOTEBOOK_BASE*>( page ) )
829 {
830 if( panel->GetProjectTied() )
831 m_notebook->DeletePage( i );
832 }
833 }
834
835 m_projectTreePane->EmptyTreePrj();
837
838 return true;
839}
840
841
842void KICAD_MANAGER_FRAME::OpenJobsFile( const wxFileName& aFileName, bool aCreate, bool aResaveProjectPreferences )
843{
844 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
845 {
846 if( PANEL_JOBSET* panel = dynamic_cast<PANEL_JOBSET*>( m_notebook->GetPage( i ) ) )
847 {
848 if( aFileName.GetFullPath() == panel->GetFilePath() )
849 {
850 m_notebook->SetSelection( i );
851 return;
852 }
853 }
854 }
855
856 try
857 {
858 std::unique_ptr<JOBSET> jobsFile = std::make_unique<JOBSET>( aFileName.GetFullPath().ToStdString() );
859
860 jobsFile->LoadFromFile();
861
862 if( aCreate && !aFileName.FileExists() )
863 {
864 JOBSET_DESTINATION* dest = jobsFile->AddNewDestination( JOBSET_DESTINATION_T::FOLDER );
865 dest->m_outputHandler->SetOutputPath( aFileName.GetName() );
866 jobsFile->SaveToFile( wxEmptyString, true );
867 }
868
869 PANEL_JOBSET* jobPanel = new PANEL_JOBSET( m_notebook, this, std::move( jobsFile ) );
870 jobPanel->SetProjectTied( true );
871 jobPanel->SetClosable( true );
872 m_notebook->AddPage( jobPanel, aFileName.GetFullName(), true );
874
875 if( aResaveProjectPreferences )
877 }
878 catch( ... )
879 {
880 DisplayErrorMessage( this, _( "Error opening jobs file" ) );
881 }
882}
883
884
885bool KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
886{
887 // The project file should be valid by the time we get here or something has gone wrong.
888 if( !aProjectFileName.Exists() )
889 return false;
890
891 wxString fullPath = aProjectFileName.GetFullPath();
892
893 // Check if a lock file already exists BEFORE we try to acquire it. We only want to warn
894 // the user if the lock file pre-existed, not if we're about to create it ourselves.
895 // The actual lock acquisition happens in SETTINGS_MANAGER::LoadProject().
896 wxFileName lockFn( fullPath );
897 lockFn.SetName( FILEEXT::LockFilePrefix + lockFn.GetName() );
898 lockFn.SetExt( lockFn.GetExt() + wxS( "." ) + FILEEXT::LockFileExtension );
899 bool lockFilePreExisted = lockFn.FileExists();
900
901 bool lockOverrideGranted = false;
902
903 if( lockFilePreExisted )
904 {
905 // A lock file exists. Create a LOCKFILE to read who owns it and decide what to do.
906 LOCKFILE lockFile( fullPath );
907
908 if( !lockFile.Valid() && lockFile.IsLockedByMe() )
909 {
910 // If we cannot acquire the lock but we appear to be the one who locked it, check to
911 // see if there is another KiCad instance running. If not, then we can override the
912 // lock. This could happen if KiCad crashed or was interrupted.
913 if( !Pgm().SingleInstance()->IsAnotherRunning() )
914 lockFile.OverrideLock();
915 }
916
917 if( !lockFile.Valid() )
918 {
919 wxString msg;
920 msg.Printf( _( "Project '%s' is already open by '%s' at '%s'." ),
921 fullPath,
922 lockFile.GetUsername(),
923 lockFile.GetHostname() );
924
925 if( !AskOverrideLock( this, msg ) )
926 return false; // User clicked Cancel - abort project loading entirely
927
928 lockFile.OverrideLock();
929 lockOverrideGranted = true;
930 }
931
932 // The LOCKFILE goes out of scope here and releases/removes the lock file.
933 // SETTINGS_MANAGER::LoadProject() will create the actual persistent lock.
934 }
935
936 // Any open KIFACE's must be closed if they are not part of the new project.
937 // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.)
938 // User is prompted here to close those KIWAY_PLAYERs:
939 if( !CloseProject( true ) )
940 return false;
941
942 m_active_project = true;
943
944 // NB: when loading a legacy project SETTINGS_MANAGER::LoadProject() will convert it to
945 // current extension. Be very careful with aProjectFileName vs. Prj().GetProjectPath()
946 // from here on out.
947
948 Pgm().GetSettingsManager().LoadProject( fullPath );
949
950 // Propagate lock override decision to the loaded project
951 if( lockOverrideGranted )
952 Prj().SetLockOverrideGranted( true );
953
954 LoadWindowState( aProjectFileName.GetFullName() );
955
956 if( aProjectFileName.IsDirWritable() )
957 SetMruPath( Prj().GetProjectPath() );
958
959 Kiway().LocalHistory().Init( Prj().GetProjectPath() );
960
961 if( Kiway().LocalHistory().HeadNewerThanLastSave( Prj().GetProjectPath() ) )
962 {
963 wxString head = Kiway().LocalHistory().GetHeadHash( Prj().GetProjectPath() );
964
965 KICAD_MESSAGE_DIALOG dlg( this, _( "KiCad found unsaved changes from your last session that are newer than "
966 "the saved project files." ),
967 _( "Recover Unsaved Changes" ), wxYES_NO | wxICON_QUESTION );
968
969 dlg.SetExtendedMessage( _( "This can happen if your previous session ended unexpectedly.\n\n"
970 "Choose 'Restore' to recover those changes, or 'Discard' to keep the "
971 "currently saved files." ) );
972
973 dlg.SetYesNoLabels( _( "Restore" ), _( "Discard" ) );
974
975 if( dlg.ShowModal() == wxID_YES )
976 {
977 Kiway().LocalHistory().RestoreCommit( Prj().GetProjectPath(), head, this );
978 }
979 else
980 {
981 // User declined to restore - commit the current on-disk state and tag it
982 // so we don't prompt again on next load
983 if( Kiway().LocalHistory().CommitFullProjectSnapshot( Prj().GetProjectPath(), wxS( "Declined restore" ) ) )
984 Kiway().LocalHistory().TagSave( Prj().GetProjectPath(), wxS( "project" ) );
985 }
986 }
987
988 // Save history & window state to disk now. Don't wait around for a crash.
989 KICAD_SETTINGS* settings = kicadSettings();
990 SaveSettings( settings );
991 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
992
993 m_projectTreePane->ReCreateTreePrj();
994 m_historyPane->RefreshHistory( Prj().GetProjectPath() );
995
996 for( const wxString& jobset : Prj().GetLocalSettings().m_OpenJobSets )
997 {
998 wxFileName jobsetFn( jobset );
999 jobsetFn.MakeAbsolute( Prj().GetProjectPath() );
1000
1001 if( jobsetFn.Exists() )
1002 OpenJobsFile( jobsetFn.GetFullPath(), false, false );
1003 }
1004
1005 // Always start with the apps page
1006 m_notebook->SetSelection( 0 );
1007
1008 // Rebuild the list of watched paths.
1009 // however this is possible only when the main loop event handler is running,
1010 // so we use it to run the rebuild function.
1011 wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
1012
1013 wxPostEvent( this, cmd );
1014
1015 PrintPrjInfo();
1016
1017 KIPLATFORM::APP::RegisterApplicationRestart( aProjectFileName.GetFullPath() );
1018 m_openSavedWindows = true;
1019
1020 KIPLATFORM::ENV::AddToRecentDocs( aProjectFileName.GetFullPath() );
1021
1022 // Now that we have a new project, trigger a library preload, which will load in any
1023 // project-specific symbol and footprint libraries into the manager
1025 return true;
1026}
1027
1028
1029void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName, bool aCreateStubFiles )
1030{
1031 wxCHECK_RET( aProjectFileName.DirExists() && aProjectFileName.IsDirWritable(),
1032 "Project folder must exist and be writable to create a new project." );
1033
1034 // If the project is legacy, convert it
1035 if( !aProjectFileName.FileExists() )
1036 {
1037 wxFileName legacyPro( aProjectFileName );
1038 legacyPro.SetExt( FILEEXT::LegacyProjectFileExtension );
1039
1040 if( legacyPro.FileExists() )
1041 {
1042 GetSettingsManager()->LoadProject( legacyPro.GetFullPath() );
1044
1045 wxRemoveFile( legacyPro.GetFullPath() );
1046 }
1047 else
1048 {
1049 // Copy template project file from template folder.
1050 wxString srcFileName = sys_search().FindValidPath( "kicad.kicad_pro" );
1051
1052 wxFileName destFileName( aProjectFileName );
1053 destFileName.SetExt( FILEEXT::ProjectFileExtension );
1054
1055 // Create a minimal project file if the template project file could not be copied
1056 if( !wxFileName::FileExists( srcFileName )
1057 || !wxCopyFile( srcFileName, destFileName.GetFullPath() ) )
1058 {
1059 wxFFile file( destFileName.GetFullPath(), "wb" );
1060
1061 if( file.IsOpened() )
1062 file.Write( wxT( "{\n}\n") );
1063
1064 // wxFFile dtor will close the file
1065 }
1066 }
1067 }
1068
1069 // Create a "stub" for a schematic root sheet and a board if requested.
1070 // It will avoid messages from the schematic editor or the board editor to create a new file
1071 // And forces the user to create main files under the right name for the project manager
1072 if( aCreateStubFiles )
1073 {
1074 wxFileName fn( aProjectFileName.GetFullPath() );
1076
1077 // If a <project>.kicad_sch file does not exist, create a "stub" file ( minimal schematic
1078 // file ).
1079 if( !fn.FileExists() )
1080 {
1081 wxFFile file( fn.GetFullPath(), "wb" );
1082
1083 if( file.IsOpened() )
1084 {
1085 file.Write( wxString::Format( "(kicad_sch\n"
1086 "\t(version %d)\n"
1087 "\t(generator \"eeschema\")\n"
1088 "\t(generator_version \"%s\")\n"
1089 "\t(uuid %s)\n"
1090 "\t(paper \"A4\")\n"
1091 "\t(lib_symbols)\n"
1092 "\t(sheet_instances\n"
1093 "\t\t(path \"/\"\n"
1094 "\t\t\t(page \"1\")\n"
1095 "\t\t)\n"
1096 "\t)\n"
1097 "\t(embedded_fonts no)\n"
1098 ")",
1101 KIID().AsString() ) );
1102 }
1103
1104 // wxFFile dtor will close the file
1105 }
1106
1107 // If a <project>.kicad_pcb or <project>.brd file does not exist,
1108 // create a .kicad_pcb "stub" file
1109 fn.SetExt( FILEEXT::KiCadPcbFileExtension );
1110 wxFileName leg_fn( fn );
1111 leg_fn.SetExt( FILEEXT::LegacyPcbFileExtension );
1112
1113 if( !fn.FileExists() && !leg_fn.FileExists() )
1114 {
1115 wxFFile file( fn.GetFullPath(), "wb" );
1116
1117 if( file.IsOpened() )
1118 {
1119 // Create a small dummy file as a stub for pcbnew:
1120 file.Write( wxString::Format( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n)",
1122 }
1123
1124 // wxFFile dtor will close the file
1125 }
1126 }
1127
1128 // Save history & window state to disk now. Don't wait around for a crash.
1129 KICAD_SETTINGS* settings = kicadSettings();
1130 SaveSettings( settings );
1131 settings->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( settings ) );
1132
1133 m_openSavedWindows = true;
1134}
1135
1136
1138{
1139 // show all files in file dialog (in Kicad all files are editable texts):
1140 wxString wildcard = FILEEXT::AllFilesWildcard();
1141
1142 wxString default_dir = Prj().GetProjectPath();
1143
1144 wxFileDialog dlg( this, _( "Edit File in Text Editor" ), default_dir, wxEmptyString, wildcard,
1145 wxFD_OPEN );
1146
1148
1149 if( dlg.ShowModal() == wxID_CANCEL )
1150 return;
1151
1152 wxString filename = dlg.GetPath();
1153
1154 if( !dlg.GetPath().IsEmpty() && !Pgm().GetTextEditor().IsEmpty() )
1155 m_toolManager->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::openTextEditor, &filename );
1156}
1157
1158
1159void KICAD_MANAGER_FRAME::OnEditAdvancedCfg( wxCommandEvent& WXUNUSED( event ) )
1160{
1161 DIALOG_EDIT_CFG dlg( this );
1162 dlg.ShowModal();
1163}
1164
1165
1167{
1168 m_projectTreePane->ReCreateTreePrj();
1169}
1170
1171
1173{
1174 // call my base class
1176
1177 // tooltips in toolbars
1179 m_launcher->CreateLaunchers();
1180
1181 // update captions
1182 int pageId = m_notebook->FindPage( m_launcher );
1183
1184 if( pageId != wxNOT_FOUND )
1185 m_notebook->SetPageText( pageId, EDITORS_CAPTION );
1186
1187 m_auimgr.GetPane( m_projectTreePane ).Caption( PROJECT_FILES_CAPTION );
1188 m_auimgr.Update();
1189
1190 m_projectTreePane->FileWatcherReset();
1191
1192 PrintPrjInfo();
1193}
1194
1195
1197{
1199
1200 if( m_pcm && ( aFlags & ENVVARS_CHANGED ) )
1201 m_pcm->ReadEnvVar();
1202
1203 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
1204
1205 if( m_lastToolbarIconSize == 0
1207 {
1210 }
1211
1212 m_projectTreePane->ReCreateTreePrj();
1213}
1214
1215
1217{
1218 wxString file = GetProjectFileName();
1219
1220 // empty file string means no project loaded
1221 if( !Prj().IsNullProject() &&
1222 Prj().GetProjectLock() == nullptr )
1223 {
1224 LOCKFILE lockFile( file );
1225
1226 if( !lockFile.Valid() && lockFile.IsLockedByMe() )
1227 {
1228 // If we cannot acquire the lock but we appear to be the one who
1229 // locked it, check to see if there is another KiCad instance running.
1230 // If there is not, then we can override the lock. This could happen if
1231 // KiCad crashed or was interrupted
1232 if( !Pgm().SingleInstance()->IsAnotherRunning() )
1233 {
1234 lockFile.OverrideLock();
1235 }
1236 }
1237
1238 if( !lockFile.Valid() )
1239 {
1240 wxString msg;
1241 msg.Printf( _( "Project '%s' is already open by '%s' at '%s'." ),
1242 file,
1243 lockFile.GetUsername(),
1244 lockFile.GetHostname() );
1245
1246 if( AskOverrideLock( this, msg ) )
1247 {
1248 lockFile.OverrideLock();
1249 }
1250 }
1251
1252 Prj().SetReadOnly( !lockFile.Valid() || Prj().GetProjectFile().IsReadOnly() );
1253 Prj().SetProjectLock( new LOCKFILE( std::move( lockFile ) ) );
1254 }
1255
1256 wxString title;
1257
1258 if( !file.IsEmpty() )
1259 {
1260 wxFileName fn( file );
1261
1262 title = fn.GetName();
1263
1264 if( Prj().IsReadOnly() )
1265 title += wxS( " " ) + _( "[Read Only]" );
1266 }
1267 else
1268 {
1269 title = _( "[no project loaded]" );
1270 }
1271
1272 if( ADVANCED_CFG::GetCfg().m_HideVersionFromTitle )
1273 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad" ) );
1274 else
1275 title += wxT( " \u2014 " ) + wxString( wxS( "KiCad " ) ) + GetMajorMinorVersion();
1276
1277 SetTitle( title );
1278
1279 // Register project file saver. Ensures project file participates in
1280 // autosave history commits without affecting dirty state.
1282 [this]( const wxString& aProjectPath, std::vector<wxString>& aFiles )
1283 {
1284 Prj().SaveToHistory( aProjectPath, aFiles );
1285 } );
1286}
1287
1288
1290{
1292
1293 auto settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
1294
1295 wxCHECK( settings, /*void*/ );
1296
1297 m_leftWinWidth = settings->m_LeftWinWidth;
1298 m_showHistoryPanel = settings->m_ShowHistoryPanel;
1299}
1300
1301
1303{
1305
1306 KICAD_SETTINGS* settings = dynamic_cast<KICAD_SETTINGS*>( aCfg );
1307
1308 wxCHECK( settings, /*void*/ );
1309
1310 settings->m_LeftWinWidth = m_projectTreePane->GetSize().x;
1311 settings->m_ShowHistoryPanel = m_historyPane && m_auimgr.GetPane( m_historyPane ).IsShown();
1312
1313 if( !m_isClosing )
1315}
1316
1317
1319{
1320 // wxStatusBar's wxELLIPSIZE_MIDDLE flag doesn't work (at least on Mac).
1321
1322 wxString status = wxString::Format( _( "Project: %s" ), Prj().GetProjectFullName() );
1323 KISTATUSBAR* statusBar = static_cast<KISTATUSBAR*>( GetStatusBar() );
1324 statusBar->SetEllipsedTextField( status, 0 );
1325}
1326
1327
1332
1333
1334void KICAD_MANAGER_FRAME::OnIdle( wxIdleEvent& aEvent )
1335{
1341 if( !m_openSavedWindows )
1342 return;
1343
1344 m_openSavedWindows = false;
1345
1346 if( Pgm().GetCommonSettings()->m_Session.remember_open_files )
1347 {
1348 int previousOpenCount = std::count_if( Prj().GetLocalSettings().m_files.begin(),
1349 Prj().GetLocalSettings().m_files.end(),
1350 [&]( const PROJECT_FILE_STATE& f )
1351 {
1352 return !f.fileName.EndsWith( FILEEXT::ProjectFileExtension ) && f.open;
1353 } );
1354
1355 if( previousOpenCount > 0 )
1356 {
1357 APP_PROGRESS_DIALOG progressReporter( _( "Restoring session" ), wxEmptyString, previousOpenCount, this );
1358
1359 // We don't currently support opening more than one view per file
1360 std::set<wxString> openedFiles;
1361
1362 int i = 0;
1363
1364 for( const PROJECT_FILE_STATE& file : Prj().GetLocalSettings().m_files )
1365 {
1366 if( file.open && !openedFiles.count( file.fileName ) )
1367 {
1368 progressReporter.Update( i++, wxString::Format( _( "Restoring '%s'" ), file.fileName ) );
1369
1370 openedFiles.insert( file.fileName );
1371 wxFileName fn( file.fileName );
1372
1373 if( fn.GetExt() == FILEEXT::LegacySchematicFileExtension
1374 || fn.GetExt() == FILEEXT::KiCadSchematicFileExtension )
1375 {
1377 }
1378 else if( fn.GetExt() == FILEEXT::LegacyPcbFileExtension
1379 || fn.GetExt() == FILEEXT::KiCadPcbFileExtension )
1380 {
1382 }
1383 }
1384
1385 wxYield();
1386 }
1387 }
1388 }
1389
1390 // clear file states regardless if we opened windows or not due to setting
1392
1393 // After restore from history, mark open editors as dirty so user is prompted to save
1395 {
1396 m_restoredFromHistory = false;
1397
1398 // Mark schematic editor as dirty if open
1399 if( KIWAY_PLAYER* schFrame = Kiway().Player( FRAME_SCH, false ) )
1400 schFrame->OnModify();
1401
1402 // Mark PCB editor as dirty if open
1403 if( KIWAY_PLAYER* pcbFrame = Kiway().Player( FRAME_PCB_EDITOR, false ) )
1404 pcbFrame->OnModify();
1405 }
1406
1407 KICAD_SETTINGS* settings = kicadSettings();
1408
1410 && settings->m_PcmUpdateCheck )
1411 {
1412 if( !m_pcm )
1413 CreatePCM();
1414
1415 m_pcm->RunBackgroundUpdate();
1416 }
1417
1418#ifdef KICAD_UPDATE_CHECK
1419 if( !m_updateManager && settings->m_KiCadUpdateCheck )
1420 {
1421 m_updateManager = std::make_unique<UPDATE_MANAGER>();
1422 m_updateManager->CheckForUpdate( this );
1423 }
1424#endif
1425
1426 // This little diddy is needed to get the window put into the Mac dock icon's context menu.
1427 Raise();
1428}
1429
1430
1432{
1433 m_pcmButton = aButton;
1434
1436}
1437
1438
1440{
1441 if( m_pcmButton )
1442 {
1443 if( m_pcmUpdateCount > 0 )
1444 {
1445 m_pcmButton->SetShowBadge( true );
1446 m_pcmButton->SetBadgeText( wxString::Format( "%d", m_pcmUpdateCount ) );
1447 }
1448 else
1449 {
1450 m_pcmButton->SetShowBadge( false );
1451 }
1452
1453 m_pcmButton->Refresh();
1454 }
1455}
1456
1457
1459{
1460 // No idea why, but the same mechanism used in EDA_DRAW_FRAME doesn't work here
1461 // the only thing that seems to work is to blow it all up and start from scratch.
1462 m_auimgr.DetachPane( m_tbLeft );
1463 delete m_tbLeft;
1464 m_tbLeft = nullptr;
1466 m_auimgr.AddPane( m_tbLeft, EDA_PANE().HToolbar().Name( "TopMainToolbar" ).Left().Layer( 2 ) );
1467
1468 m_auimgr.Update();
1469}
1470
1471
1473{
1474 wxAuiPaneInfo& pane = m_auimgr.GetPane( m_historyPane );
1475 bool show = !pane.IsShown();
1476 pane.Show( show );
1477
1478 if( show )
1479 m_historyPane->RefreshHistory( Prj().GetProjectPath() );
1480
1481 m_auimgr.Update();
1482}
1483
1484
1486{
1487 if( !Kiway().PlayersClose( true ) )
1488 return;
1489
1490 if( Kiway().LocalHistory().RestoreCommit( Prj().GetProjectPath(), aHash, this ) )
1491 {
1492 m_restoredFromHistory = true; // Mark editors dirty when they reopen
1493 }
1494
1495 m_projectTreePane->ReCreateTreePrj();
1496 m_openSavedWindows = true;
1497 m_historyPane->RefreshHistory( Prj().GetProjectPath() );
1498}
1499
1500
1502{
1503 return m_historyPane && m_auimgr.GetPane( m_historyPane ).IsShown();
1504}
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
EDA_BASE_FRAME(wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, KIWAY *aKiway, const EDA_IU_SCALE &aIuScale)
TOOLBAR_SETTINGS * m_toolbarSettings
virtual void configureToolbars()
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
virtual void OnDropFiles(wxDropFilesEvent &aEvent)
Handle event fired when a file is dropped to the window.
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)
wxString m_aboutTitle
bool m_isClosing
Set by the close window event handler after frames are asked if they can close.
void ReCreateMenuBar()
Recreate the menu bar.
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 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.
void OnImportPadsProjectFiles(wxCommandEvent &event)
Open dialog to import PADS Logic schematic and PCB files.
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 OnChangeWatchedPaths(wxCommandEvent &aEvent)
Called by sending a event with id = ID_INIT_WATCHED_PATHS rebuild the list of watched paths.
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 OnFileHistory(wxCommandEvent &event)
PROJECT_TREE_PANE * m_projectTreePane
void OnImportGedaFiles(wxCommandEvent &event)
Open dialog to import gEDA/gaf schematic and PCB files.
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;.
wxString GetCurrentFileName() const override
Get the full filename + path of the currently opened file in the frame.
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 LoadProject(const wxFileName &aProjectFileName)
Loads a new project.
bool m_restoredFromHistory
Set after restore to mark editors dirty.
void onNotebookPageCountChanged(wxAuiNotebookEvent &evt)
LOCAL_HISTORY_PANE * m_historyPane
void OnClearFileHistory(wxCommandEvent &aEvent)
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 KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition kiway.cpp:213
@ FACE_SCH
eeschema DSO
Definition kiway.h:302
@ FACE_PCB
pcbnew DSO
Definition kiway.h:303
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:407
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:541
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
Definition pgm_base.cpp:887
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:137
void UnregisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Unregister a status bar from receiving library load warning messages.
Definition pgm_base.cpp:979
bool m_Quitting
Definition pgm_base.h:394
void RegisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Register a status bar to receive library load warning messages.
Definition pgm_base.cpp:959
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
Definition pgm_base.h:142
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:131
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:455
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:171
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:177
void SaveToHistory(const wxString &aProjectPath, std::vector< wxString > &aFiles)
Save project files (.kicad_pro and .kicad_prl) to the .history directory.
Definition project.cpp:461
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 KICAD_MESSAGE_DIALOG
Definition confirm.h:52
#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 LockFileExtension
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string LegacyProjectFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string LockFilePrefix
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_FILEMAX
Definition id.h:60
@ 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_PADS_PROJECT
Definition kicad_id.h:44
@ ID_IMPORT_GEDA_PROJECT
Definition kicad_id.h:45
@ 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)
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:435
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)
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:156
virtual void PreloadLibraries(KIWAY *aKiway)
Definition kiway.h:259
virtual void CancelPreload(bool aBlock=true)
Definition kiway.h:261
#define ENVVARS_CHANGED
Definition of file extensions used in Kicad.