From e345e7d17a738224a9172b8b6f7178affd080a7b Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Mon, 21 Sep 2020 20:00:51 -0400 Subject: [PATCH] Allow creating an empty project when saving a board standalone --- pcbnew/files.cpp | 86 +++++++++++++++++++++++++++++++++++++---- pcbnew/pcb_edit_frame.h | 3 +- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index e5a9bbb291..d73cae4c8c 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -150,9 +150,42 @@ bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bo } +///> Helper widget to select whether a new project should be created for a file when saving +class CREATE_PROJECT_CHECKBOX : public wxPanel +{ +public: + CREATE_PROJECT_CHECKBOX( wxWindow* aParent ) + : wxPanel( aParent ) + { + m_cbCreateProject = new wxCheckBox( this, wxID_ANY, + _( "Create a new project for this board" ) ); + m_cbCreateProject->SetValue( false ); + m_cbCreateProject->SetToolTip( _( "Creating a project will enable features such as " + "design rules, net classes, and layer presets" ) ); + + wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL ); + sizer->Add( m_cbCreateProject, 0, wxALL, 8 ); + + SetSizerAndFit( sizer ); + } + + bool GetValue() const + { + return m_cbCreateProject->GetValue(); + } + + static wxWindow* Create( wxWindow* aParent ) + { + return new CREATE_PROJECT_CHECKBOX( aParent ); + } + +protected: + wxCheckBox* m_cbCreateProject; +}; + + /** - * Function AskSaveBoardFileName - * puts up a wxFileDialog asking for a BOARD filename to save. + * Puts up a wxFileDialog asking for a BOARD filename to save. * * @param aParent is a wxFrame passed to wxFileDialog. * @param aFileName on entry is a probable choice, on return is the @@ -160,7 +193,7 @@ bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bo * * @return bool - true if chosen, else false if user aborted. */ -bool AskSaveBoardFileName( wxWindow* aParent, wxString* aFileName ) +bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject ) { wxString wildcard = PcbFileWildcard(); wxFileName fn = *aFileName; @@ -175,6 +208,10 @@ bool AskSaveBoardFileName( wxWindow* aParent, wxString* aFileName ) wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + // Add a "Create a project" checkbox in standalone mode and one isn't loaded + if( Kiface().IsSingle() && aParent->Prj().IsNullProject() ) + dlg.SetExtraControlCreator( &CREATE_PROJECT_CHECKBOX::Create ); + if( dlg.ShowModal() != wxID_OK ) return false; @@ -183,7 +220,8 @@ bool AskSaveBoardFileName( wxWindow* aParent, wxString* aFileName ) // always enforce filename extension, user may not have entered it. fn.SetExt( KiCadPcbFileExtension ); - *aFileName = fn.GetFullPath(); + *aFileName = fn.GetFullPath(); + *aCreateProject = static_cast( dlg.GetExtraControl() )->GetValue(); return true; } @@ -339,12 +377,14 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id ) wxFileName fn( pro_dir, orig_name, KiCadPcbFileExtension ); wxString filename = fn.GetFullPath(); - if( AskSaveBoardFileName( this, &filename ) ) + bool createProject = false; + + if( AskSaveBoardFileName( this, &filename, &createProject ) ) { if( id == ID_COPY_BOARD_AS ) - return SavePcbCopy( filename ); + return SavePcbCopy( filename, createProject ); else - return SavePcbFile( filename, addToHistory, false ); + return SavePcbFile( filename, addToHistory, createProject ); } return false; } @@ -830,7 +870,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory, } -bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName ) +bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject ) { wxFileName pcbFileName = aFileName; @@ -872,6 +912,36 @@ bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName ) return false; } + if( aCreateProject ) + { + wxFileName projectFile( pcbFileName ); + projectFile.SetExt( ProjectFileExtension ); + + if( !projectFile.FileExists() ) + { + wxString currentProject = Prj().GetProjectFullName(); + + SETTINGS_MANAGER* mgr = GetSettingsManager(); + + GetBoard()->ClearProject(); + + mgr->SaveProject( currentProject ); + mgr->UnloadProject( &Prj() ); + + mgr->LoadProject( projectFile.GetFullPath() ); + mgr->SaveProject(); + + mgr->UnloadProject( &Prj() ); + mgr->LoadProject( currentProject ); + + // If no project to load then initialize project text vars with board properties + if( !mgr->LoadProject( currentProject ) ) + Prj().GetTextVars() = GetBoard()->GetProperties(); + + GetBoard()->SetProject( &Prj() ); + } + } + DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n\"%s\"" ), pcbFileName.GetFullPath() ) ); diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index a0e8878e41..0af05877f0 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -609,9 +609,10 @@ public: * * When not under a project mgr, the full SavePcbFile is used. * @param aFileName The file name to write. + * @param aCreateProject will create an empty project alongside the board file * @return True if file was saved successfully. */ - bool SavePcbCopy( const wxString& aFileName ); + bool SavePcbCopy( const wxString& aFileName, bool aCreateProject = false ); // BOARD handling