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