71#include <wx/filedlg.h>
73#include <wx/process.h>
74#include <wx/snglinst.h>
84#include <ApplicationServices/ApplicationServices.h>
93#define EDITORS_CAPTION _( "Editors" )
94#define PROJECT_FILES_CAPTION _( "Project Files" )
96#define ID_INIT_WATCHED_PATHS 52913
98#define SEP() wxFileName::GetPathSeparator()
133#include <wx/xml/xml.h>
136 const wxPoint& pos,
const wxSize& size ) :
139 m_active_project( false ),
140 m_leftWin( nullptr ),
141 m_launcher( nullptr ),
142 m_lastToolbarIconSize( 0 ),
143 m_pcmButton( nullptr ),
144 m_pcmUpdateCount( 0 )
146 const int defaultLeftWinWidth = FromDIP( 250 );
148 m_leftWinWidth = defaultLeftWinWidth;
149 m_aboutTitle =
"KiCad";
164 CreateStatusBar( 1 );
171 wxIconBundle icon_bundle;
176 icon_bundle.AddIcon( icon );
178 icon_bundle.AddIcon( icon );
180 icon_bundle.AddIcon( icon );
182 icon_bundle.AddIcon( icon );
184 icon_bundle.AddIcon( icon );
189 icon_bundle.AddIcon( icon );
191 icon_bundle.AddIcon( icon );
193 icon_bundle.AddIcon( icon );
195 icon_bundle.AddIcon( icon );
197 icon_bundle.AddIcon( icon );
200 SetIcons( icon_bundle );
216 m_auimgr.SetManagedWindow(
this );
217 m_auimgr.SetFlags( wxAUI_MGR_LIVE_RESIZE );
219 m_auimgr.AddPane( m_tbLeft,
EDA_PANE().VToolbar().Name(
"TopMainToolbar" ).Left().Layer( 2 ) );
226 m_auimgr.AddPane( m_leftWin,
EDA_PANE().Palette().Name(
"ProjectTree" ).Left().Layer( 1 )
228 .MinSize( m_leftWinWidth, -1 ).BestSize( m_leftWinWidth, -1 ) );
230 wxSize client_size = GetClientSize();
231 m_notebook =
new wxAuiNotebook(
this, wxID_ANY, wxPoint( client_size.x, client_size.y ),
232 FromDIP( wxSize( 700, 590 ) ),
233 wxAUI_NB_TOP | wxAUI_NB_CLOSE_ON_ALL_TABS | wxAUI_NB_TAB_MOVE
234 | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER );
240 m_notebook->Freeze();
241 m_launcher->SetClosable(
false );
243 m_notebook->SetTabCtrlHeight( 0 );
247 .PaneBorder(
false ).MinSize( m_notebook->GetBestSize() ) );
252 m_auimgr.GetPane( m_leftWin ).MinSize( defaultLeftWinWidth, -1 );
255 wxSizer* mainSizer = GetSizer();
258 if( mainSizer &&
config()->m_Window.state.size_x == 0 &&
config()->m_Window.state.size_y == 0 )
261 mainSizer->Fit(
this );
266 SetTitle( wxT(
"KiCad" ) );
271 m_leftWin->SetFocus();
283 DragAcceptFiles(
true );
288 Bind( wxEVT_DPI_CHANGED,
289 [&]( wxDPIChangedEvent& )
314 m_pcm->StopBackgroundUpdate();
340 wxAuiNotebook* notebook = (wxAuiNotebook*) evt.GetEventObject();
341 wxWindow* page = notebook->GetPage( evt.GetSelection() );
345 if( panel->GetClosable() )
347 if( !panel->GetCanClose() )
365 const wxString&
name )
377 m_pcm = std::make_shared<PLUGIN_CONTENT_MANAGER>(
378 [
this](
int aUpdateCount )
382 if( aUpdateCount > 0 )
386 _(
"PCM Updates Available" ),
387 wxString::Format(
_(
"%d package update(s) avaliable" ), aUpdateCount ),
440#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
443 activeProjectCond.
Enable( activeProject );
486 : wxString( wxEmptyString );
495 return fn.GetFullPath();
504 return fn.GetFullPath();
512 fn.SetExt( FILEEXT::PcbFileExtension );
513 return fn.GetFullPath();
522 return fn.GetFullPath();
567 wxString ext = fileName.GetExt();
571 wxString fn = fileName.GetFullPath();
579 wxString gerberFiles;
584 wxString ext = fileName.GetExt();
589 gerberFiles += wxT(
'\"' );
590 gerberFiles += fileName.GetFullPath() + wxT(
'\"' );
591 gerberFiles = gerberFiles.Pad( 1 );
595 wxString fn = fileName.GetFullPath();
601 if( !gerberFiles.IsEmpty() )
605 if( wxFileExists( fullEditorName ) )
607 wxString command = fullEditorName +
" " + gerberFiles;
619 for(
size_t i = 0; i <
m_notebook->GetPageCount(); i++ )
625 if( !panel->GetCanClose() )
635 aEvent.StopPropagation();
641 if( aEvent.CanVeto() )
659 static std::atomic<unsigned int> lock_close_event( 0 );
661 if( ++lock_close_event > 1 )
673 lock_close_event = 0;
687 for(
size_t i = 0; i <
m_notebook->GetPageCount(); i++ )
691 wxFileName jobsetFn(
jobset->GetFilePath() );
692 jobsetFn.MakeRelativeTo(
Prj().GetProjectPath() );
709 if( !
Kiway().PlayersClose(
false ) )
717 if(
Prj().GetLocalSettings().ShouldAutoSave() &&
Prj().GetProjectFile().ShouldAutoSave() )
732 for(
int i = (
int)
m_notebook->GetPageCount() - 1; i >= 0; i-- )
738 if( panel->GetProjectTied() )
751 bool aResaveProjectPreferences )
753 for(
size_t i = 0; i <
m_notebook->GetPageCount(); i++ )
757 if( aFileName.GetFullPath() == panel->GetFilePath() )
767 std::unique_ptr<JOBSET> jobsFile = std::make_unique<JOBSET>( aFileName.GetFullPath().ToStdString() );
769 jobsFile->LoadFromFile();
771 if( aCreate && !aFileName.FileExists() )
773 JOBSET_DESTINATION* dest = jobsFile->AddNewDestination( JOBSET_DESTINATION_T::FOLDER );
775 jobsFile->SaveToFile( wxEmptyString,
true );
781 m_notebook->AddPage( jobPanel, aFileName.GetFullName(),
true );
784 if( aResaveProjectPreferences )
797 if( !aProjectFileName.Exists() )
815 if( aProjectFileName.IsDirWritable() )
825 for(
const wxString&
jobset :
Prj().GetLocalSettings().m_OpenJobSets )
827 wxFileName jobsetFn(
jobset );
828 jobsetFn.MakeAbsolute(
Prj().GetProjectPath() );
830 if( jobsetFn.Exists() )
842 wxPostEvent(
this, cmd );
855 wxCHECK_RET( aProjectFileName.DirExists() && aProjectFileName.IsDirWritable(),
856 "Project folder must exist and be writable to create a new project." );
859 if( !aProjectFileName.FileExists() )
861 wxFileName legacyPro( aProjectFileName );
864 if( legacyPro.FileExists() )
869 wxRemoveFile( legacyPro.GetFullPath() );
874 wxString srcFileName =
sys_search().FindValidPath(
"kicad.kicad_pro" );
876 wxFileName destFileName( aProjectFileName );
880 if( !wxFileName::FileExists( srcFileName )
881 || !wxCopyFile( srcFileName, destFileName.GetFullPath() ) )
883 wxFFile file( destFileName.GetFullPath(),
"wb" );
885 if( file.IsOpened() )
886 file.Write( wxT(
"{\n}\n") );
896 if( aCreateStubFiles )
898 wxFileName fn( aProjectFileName.GetFullPath() );
903 if( !fn.FileExists() )
905 wxFFile file( fn.GetFullPath(),
"wb" );
907 if( file.IsOpened() )
909 file.Write( wxString::Format(
"(kicad_sch\n"
911 "\t(generator \"eeschema\")\n"
912 "\t(generator_version \"%s\")\n"
916 "\t(sheet_instances\n"
918 "\t\t\t(page \"1\")\n"
921 "\t(embedded_fonts no)\n"
924 KIID().AsString() ) );
933 wxFileName leg_fn( fn );
936 if( !fn.FileExists() && !leg_fn.FileExists() )
938 wxFFile file( fn.GetFullPath(),
"wb" );
940 if( file.IsOpened() )
943 file.Write( wxString::Format(
"(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n)",
967 wxFileDialog dlg(
this,
_(
"Edit File in Text Editor" ), default_dir, wxEmptyString, wildcard,
970 if( dlg.ShowModal() == wxID_CANCEL )
973 wxString filename = dlg.GetPath();
975 if( !dlg.GetPath().IsEmpty() && !
Pgm().GetTextEditor().IsEmpty() )
995 int id =
event.GetId();
1012 if( pageId != wxNOT_FOUND )
1029 m_pcm->ReadEnvVar();
1049 if( !
Prj().IsNullProject() &&
1050 Prj().GetProjectLock() ==
nullptr )
1060 if( !
Pgm().SingleInstance()->IsAnotherRunning() )
1066 if( !lockFile.
Valid() )
1069 msg.Printf(
_(
"Project '%s' is already open by '%s' at '%s'." ), file, lockFile.
GetUsername(),
1084 if( !file.IsEmpty() )
1086 wxFileName fn( file );
1088 title = fn.GetName();
1090 if(
Prj().IsReadOnly() )
1091 title += wxS(
" " ) +
_(
"[Read Only]" );
1095 title =
_(
"[no project loaded]" );
1099 title += wxT(
" \u2014 " ) + wxString( wxS(
"KiCad" ) );
1113 wxCHECK( settings, );
1125 wxCHECK( settings, );
1127 settings->m_LeftWinWidth =
m_leftWin->GetSize().x;
1138 wxString status = wxString::Format(
_(
"Project: %s" ),
Prj().GetProjectFullName() );
1162 if(
Pgm().GetCommonSettings()->m_Session.remember_open_files )
1164 int previousOpenCount =
1165 std::count_if(
Prj().GetLocalSettings().m_files.begin(),
1166 Prj().GetLocalSettings().m_files.end(),
1169 return !f.fileName.EndsWith( FILEEXT::ProjectFileExtension ) && f.open;
1172 if( previousOpenCount > 0 )
1175 previousOpenCount,
this );
1178 std::set<wxString> openedFiles;
1184 if( file.open && !openedFiles.count( file.fileName ) )
1186 progressReporter.
Update( i++, wxString::Format(
_(
"Restoring '%s'" ), file.fileName ) );
1188 openedFiles.insert( file.fileName );
1189 wxFileName fn( file.fileName );
1213 if( !
Pgm().GetCommonSettings()->m_DoNotShowAgain.update_check_prompt )
1216 prompt->ShowModal();
1227 m_pcm->RunBackgroundUpdate();
1230#ifdef KICAD_UPDATE_CHECK
constexpr EDA_IU_SCALE unityScale
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
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 saveAs
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.
Handle actions that are shared between different applications.
DO_NOT_SHOW_AGAIN m_DoNotShowAgain
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
virtual void RecreateToolbars()
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
ACTION_TOOLBAR * m_tbLeft
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associate file extensions with action to execute.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
void SetMruPath(const wxString &aPath)
bool m_isClosing
Set by the close window event handler after frames are asked if they can close.
Specialization of the wxAuiPaneInfo class for KiCad panels.
void SetOutputPath(const wxString &aPath)
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
Calls Store() and then writes the contents of the JSON document to a file.
static TOOL_ACTION viewDroppedGerbers
static TOOL_ACTION editPCB
static TOOL_ACTION loadProject
static TOOL_ACTION editSchematic
static TOOL_ACTION openTextEditor
static TOOL_ACTION archiveProject
static TOOL_ACTION closeProject
static TOOL_ACTION openJobsetFile
static TOOL_ACTION newJobsetFile
Handle actions in the kicad manager frame.
The main KiCad project manager frame.
std::shared_ptr< PLUGIN_CONTENT_MANAGER > m_pcm
void language_change(wxCommandEvent &event)
void SetPcmButton(BITMAP_BUTTON *aButton)
void doCloseWindow() override
void CreateNewProject(const wxFileName &aProjectFileName, bool aCreateStubFiles=true)
Creates a new project by setting up and initial project, schematic, and board files.
wxString m_FileWatcherInfo
const SEARCH_STACK & sys_search() override
Return a SEARCH_STACK pertaining to entire program.
void OnImportEasyEdaProFiles(wxCommandEvent &event)
Open dialog to import EasyEDA Pro schematic and board files.
void ProjectChanged() override
Notification event that the project has changed.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
const wxString SchLegacyFileName()
wxWindow * GetToolCanvas() const override
Canvas access.
void OnImportEasyEdaFiles(wxCommandEvent &event)
Open dialog to import EasyEDA Std schematic and board files.
PROJECT_TREE_PANE * m_leftWin
void OnImportAltiumProjectFiles(wxCommandEvent &event)
Open dialog to import Altium project files.
const wxString GetProjectFileName() const
void updatePcmButtonBadge()
KICAD_SETTINGS * kicadSettings() const
const wxString SchFileName()
void OnImportEagleFiles(wxCommandEvent &event)
Open dialog to import Eagle schematic and board files.
wxStatusBar * OnCreateStatusBar(int number, long style, wxWindowID id, const wxString &name) override
Create the status line (like a wxStatusBar).
void OnExit(wxCommandEvent &event)
void OpenJobsFile(const wxFileName &aFileName, bool aCreate=false, bool aResaveProjectPreferences=true)
void LoadProject(const wxFileName &aProjectFileName)
bool canCloseWindow(wxCloseEvent &aCloseEvent) override
void OnSize(wxSizeEvent &event) override
virtual void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void 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.
int m_lastToolbarIconSize
const wxString PcbLegacyFileName()
void OnEditAdvancedCfg(wxCommandEvent &event)
KICAD_MANAGER_FRAME(wxWindow *parent, const wxString &title, const wxPoint &pos, const wxSize &size)
bool CloseProject(bool aSave)
Closes the project, and saves it if aSave is true;.
void onNotebookPageCloseRequest(wxAuiNotebookEvent &evt)
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void OnIdle(wxIdleEvent &event)
void onToolbarSizeChanged()
void PrintPrjInfo()
Prints the current working directory name and the project name on the text panel.
void SaveOpenJobSetsToLocalSettings(bool aIsExplicitUserSave=false)
void onNotebookPageCountChanged(wxAuiNotebookEvent &evt)
void OnImportCadstarArchiveFiles(wxCommandEvent &event)
Open dialog to import CADSTAR Schematic and PCB Archive files.
void RefreshProjectTree()
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
const wxString PcbFileName()
std::unique_ptr< UPDATE_MANAGER > m_updateManager
wxAuiNotebook * m_notebook
std::vector< wxString > m_OpenProjects
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
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.
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
bool OverrideLock(bool aRemoveOnRelease=true)
Force the lock, overwriting the data that existed already.
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()
void SetClosable(bool aYes)
void SetProjectTied(bool aYes)
virtual COMMON_SETTINGS * GetCommonSettings() const
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
virtual SETTINGS_MANAGER & GetSettingsManager() const
wxString GetHelpFileName()
SEARCH_STACK & SysSearch()
APP_SETTINGS_BASE * PgmSettings()
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.
bool ShouldAutoSave() const
std::vector< wxString > m_OpenJobSets
PROJECT_TREE_PANE Window to display the tree files.
void SetProjectLock(LOCKFILE *aLockFile)
virtual void SetReadOnly(bool aReadOnly=true)
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
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.
bool AskOverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
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
const wxString GERBVIEW_EXE
wxString FindKicadFile(const wxString &shortname)
Search the executable file shortname in KiCad binary path and return full file name if found or short...
static const std::string LegacySchematicFileExtension
static const std::string GerberJobFileExtension
static const std::string GerberFileExtension
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string LegacyProjectFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string DrillFileExtension
static const std::string KiCadPcbFileExtension
static wxString AllFilesWildcard()
static bool IsGerberFileExtension(const wxString &ext)
@ ID_IMPORT_EAGLE_PROJECT
@ ID_IMPORT_EASYEDAPRO_PROJECT
@ ID_IMPORT_CADSTAR_ARCHIVE_PROJECT
@ ID_EDIT_LOCAL_FILE_IN_TEXT_EDITOR
@ ID_IMPORT_EASYEDA_PROJECT
@ ID_IMPORT_ALTIUM_PROJECT
#define ID_INIT_WATCHED_PATHS
#define PROJECT_FILES_CAPTION
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 SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
T * GetToolbarSettings(const wxString &aFilename)
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
ACTION_CONDITIONS & Enable(const SELECTION_CONDITION &aCondition)
std::shared_ptr< JOBS_OUTPUT_HANDLER > m_outputHandler
Definition of file extensions used in Kicad.