KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_api_save.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <api/sch_api_save.h>
21
22#include <base_screen.h>
23#include <kiplatform/io.h>
24#include <pgm_base.h>
25#include <project.h>
27#include <sch_io/sch_io.h>
28#include <sch_io/sch_io_mgr.h>
29#include <sch_screen.h>
30#include <sch_sheet.h>
31#include <sch_sheet_path.h>
32#include <schematic.h>
35
36#include <wx/filename.h>
37#include <wx/log.h>
38
39
40namespace SCH_API_SAVE
41{
42
43bool SaveSheetToFile( SCH_SHEET* aSheet, SCHEMATIC& aSchematic, const wxString& aPath )
44{
45 wxCHECK( aSheet, false );
46
47 if( aPath.IsEmpty() )
48 return false;
49
50 wxFileName schematicFileName( aPath );
51 schematicFileName.MakeAbsolute();
52
53 if( !schematicFileName.DirExists() && !wxMkdir( schematicFileName.GetPath() ) )
54 return false;
55
56 if( schematicFileName.FileExists() && !schematicFileName.IsFileWritable() )
57 return false;
58
59 if( schematicFileName.FileExists() )
60 KIPLATFORM::IO::MakeWriteable( schematicFileName.GetFullPath() );
61
62 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromSchPath( schematicFileName.GetFullPath() );
63
64 if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
65 pluginType = SCH_IO_MGR::SCH_KICAD;
66
67 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( pluginType ) );
68
69 try
70 {
71 pi->SaveSchematicFile( schematicFileName.GetFullPath(), aSheet, &aSchematic );
72 return true;
73 }
74 catch( const IO_ERROR& ioe )
75 {
76 wxLogTrace( wxS( "KI_TRACE_API" ), wxS( "SaveSheetToFile failed: %s" ), ioe.What() );
77 return false;
78 }
79}
80
81
82void UpdateProjectFile( SCHEMATIC& aSchematic, PROJECT& aProject )
83{
84 SCH_SCREEN* rootScreen = aSchematic.RootScreen();
85
86 if( !rootScreen )
87 return;
88
89 wxFileName projectFile( rootScreen->GetFileName() );
90 projectFile.SetExt( FILEEXT::ProjectFileExtension );
91
92 if( !projectFile.HasName() || !projectFile.IsOk() )
93 return;
94
95 aSchematic.RecordERCExclusions();
96
98
99 if( rootScreen )
100 {
102 }
103
104 const std::vector<SCH_SHEET*>& topLevelSheets = aSchematic.GetTopLevelSheets();
105
106 if( !topLevelSheets.empty() )
107 {
108 std::vector<TOP_LEVEL_SHEET_INFO>& projectSheets = aProject.GetProjectFile().GetTopLevelSheets();
109 projectSheets.clear();
110
111 wxString projectPath = aProject.GetProjectPath();
112
113 for( SCH_SHEET* sheet : topLevelSheets )
114 {
116 info.uuid = sheet->m_Uuid;
117 info.name = sheet->GetName();
118
119 wxString filename;
120
121 if( sheet->GetScreen() )
122 filename = sheet->GetScreen()->GetFileName();
123
124 wxFileName sheetFn( filename );
125
126 if( sheetFn.IsAbsolute() )
127 sheetFn.MakeRelativeTo( projectPath );
128
129 info.filename = sheetFn.GetFullPath();
130 projectSheets.push_back( std::move( info ) );
131 }
132 }
133
134 std::vector<FILE_INFO_PAIR>& sheets = aProject.GetProjectFile().GetSheets();
135 sheets.clear();
136
137 if( !aSchematic.HasHierarchy() )
138 aSchematic.RefreshHierarchy();
139
140 for( SCH_SHEET_PATH& sheetPath : aSchematic.Hierarchy() )
141 {
142 SCH_SHEET* sheet = sheetPath.Last();
143
144 wxCHECK2( sheet, continue );
145
146 if( !sheet->IsVirtualRootSheet() )
147 sheets.emplace_back( std::make_pair( sheet->m_Uuid, sheet->GetName() ) );
148 }
149
150 Pgm().GetSettingsManager().SaveProject( projectFile.GetFullPath() );
151}
152
153
154bool SaveSchematic( SCHEMATIC& aSchematic, PROJECT& aProject )
155{
156 SCH_SCREEN* rootScreen = aSchematic.RootScreen();
157
158 if( !rootScreen || rootScreen->GetFileName().IsEmpty() )
159 return false;
160
161 SCH_SCREENS screens( aSchematic.Root() );
162 screens.BuildClientSheetPathList();
163
164 bool success = true;
165
166 for( size_t i = 0; i < screens.GetCount(); i++ )
167 {
168 SCH_SCREEN* screen = screens.GetScreen( i );
169
170 wxCHECK2( screen, continue );
171
172 wxFileName fileName = screen->GetFileName();
173
174 if( !fileName.IsOk() )
175 continue;
176
177 std::vector<SCH_SHEET_PATH>& sheets = screen->GetClientSheetPaths();
178
179 if( sheets.size() == 1 )
180 screen->SetVirtualPageNumber( 1 );
181 else
182 screen->SetVirtualPageNumber( 0 );
183
184 success &= SaveSheetToFile( screens.GetSheet( i ), aSchematic, fileName.GetFullPath() );
185
186 if( success )
187 screen->SetContentModified( false );
188 }
189
190 if( success )
191 UpdateProjectFile( aSchematic, aProject );
192
193 return success;
194}
195
196
197bool SaveSchematicCopy( SCHEMATIC& aSchematic, PROJECT& aProject, const wxString& aFileName, bool aCreateProject )
198{
199 wxFileName schematicFileName( aFileName );
200 schematicFileName.MakeAbsolute();
201
202 if( !schematicFileName.IsOk() || !schematicFileName.IsDirWritable() )
203 return false;
204
205 SCH_SHEET* rootSheet = &aSchematic.Root();
206
207 if( schematicFileName.GetFullPath() == aSchematic.RootScreen()->GetFileName() )
208 return SaveSchematic( aSchematic, aProject );
209
210 if( !SaveSheetToFile( rootSheet, aSchematic, schematicFileName.GetFullPath() ) )
211 return false;
212
213 if( aCreateProject )
214 {
215 wxFileName projectFile( schematicFileName );
216 projectFile.SetExt( FILEEXT::ProjectFileExtension );
217
218 if( !projectFile.FileExists() )
219 Pgm().GetSettingsManager().SaveProjectCopy( projectFile.GetFullPath() );
220 }
221
222 return true;
223}
224
225} // namespace SCH_API_SAVE
BASE_SCREEN class implementation.
void SetVirtualPageNumber(int aPageNumber)
Definition base_screen.h:72
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
Definition base_screen.h:81
void SetContentModified(bool aModified=true)
Definition base_screen.h:55
const KIID m_Uuid
Definition eda_item.h:531
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:126
std::vector< FILE_INFO_PAIR > & GetSheets()
SCHEMATIC_SETTINGS * m_SchematicSettings
struct IP2581_BOM m_IP2581Bom
Layer pair list for the board.
std::vector< TOP_LEVEL_SHEET_INFO > & GetTopLevelSheets()
Container for project specific data.
Definition project.h:62
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:183
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:200
Holds all the data relating to one schematic.
Definition schematic.h:90
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
bool HasHierarchy() const
Check if the hierarchy has been built.
Definition schematic.h:124
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
SCH_SHEET & Root() const
Definition schematic.h:134
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
void RefreshHierarchy()
static SCH_FILE_T GuessPluginTypeFromSchPath(const wxString &aSchematicPath, int aCtl=0)
Return a plugin type given a schematic using the file extension of aSchematicPath.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition sch_screen.h:746
SCH_SCREEN * GetScreen(unsigned int aIndex) const
void BuildClientSheetPathList()
Build the list of sheet paths sharing a screen for each screen in use.
size_t GetCount() const
Definition sch_screen.h:751
SCH_SHEET * GetSheet(unsigned int aIndex) const
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition sch_screen.h:185
const wxString & GetFileName() const
Definition sch_screen.h:150
TITLE_BLOCK & GetTitleBlock()
Definition sch_screen.h:161
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
wxString GetName() const
Definition sch_sheet.h:136
bool IsVirtualRootSheet() const
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
bool SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Save a copy of the current project under the given path.
const wxString & GetRevision() const
Definition title_block.h:82
static const std::string ProjectFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
bool MakeWriteable(const wxString &aFilePath)
Ensures that a file has write permissions.
Definition unix/io.cpp:78
bool SaveSheetToFile(SCH_SHEET *aSheet, SCHEMATIC &aSchematic, const wxString &aPath)
Write a single sheet to disk via SCH_IO.
bool SaveSchematic(SCHEMATIC &aSchematic, PROJECT &aProject)
Save every screen in the hierarchy to its current path, then update the project file.
void UpdateProjectFile(SCHEMATIC &aSchematic, PROJECT &aProject)
Sync schematic metadata into the project file (.kicad_pro) and save it.
bool SaveSchematicCopy(SCHEMATIC &aSchematic, PROJECT &aProject, const wxString &aFileName, bool aCreateProject)
Save the root schematic to aFileName without changing the open document.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
wxString schRevision
Auto-propagated schematic title block revision.
Information about a top-level schematic sheet.
Definition of file extensions used in Kicad.