KiCad PCB EDA Suite
libarch.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) 2004 Jean-Pierre Charras, jp.charras ar wanadoo.fr
5 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2004-2021 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
31#include <confirm.h>
33
34#include <sch_edit_frame.h>
35#include <symbol_lib_table.h>
36#include <symbol_library.h>
37#include <sch_symbol.h>
38#include <sch_sheet.h>
39#include <schematic.h>
40
41
42bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename )
43{
44 wxFileName fn;
45
46 if( aUseCurrentSheetFilename )
47 fn = GetScreen()->GetFileName();
48 else
50
51 fn.SetName( fn.GetName() + wxS( "-cache" ) );
53
54 bool success = CreateArchiveLibrary( fn.GetFullPath() );
55
56 // Update the schematic symbol library links.
57 // because the lib cache has changed
58 SCH_SCREENS schematic( Schematic().Root() );
59 schematic.UpdateSymbolLinks();
60
61 return success;
62}
63
64
65bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
66{
67 wxString tmp;
68 wxString errorMsg;
69 SCH_SCREENS screens( Schematic().Root() );
70
71 // Create a new empty library to archive symbols:
72 std::unique_ptr<SYMBOL_LIB> archLib = std::make_unique<SYMBOL_LIB>( SCH_LIB_TYPE::LT_EESCHEMA,
73 aFileName );
74
75 // Save symbols to file only when the library will be fully filled
76 archLib->EnableBuffering();
77
78 /* Examine all screens (not hierarchical sheets) used in the schematic and build a
79 * library of unique symbols found in all screens. Complex hierarchies are not a
80 * problem because we just want to know the library symbols used in the schematic
81 * not their reference.
82 */
83 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
84 {
85
86 for( SCH_ITEM* aItem : screen->Items().OfType( SCH_SYMBOL_T ) )
87 {
88 LIB_SYMBOL* libSymbol = nullptr;
89 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
90
91 try
92 {
93 if( archLib->FindSymbol( symbol->GetLibId() ) )
94 continue;
95
96 libSymbol = GetLibSymbol( symbol->GetLibId(), true );
97 }
98 catch( const IO_ERROR& )
99 {
100 // Queue up error messages for later.
101 tmp.Printf( _( "Failed to add symbol %s to library file '%s'." ),
103 aFileName );
104
105 // Don't bail out here. Attempt to add as many of the symbols to the library
106 // as possible.
107 }
108 catch( ... )
109 {
110 tmp = _( "Unexpected exception occurred." );
111 }
112
113 if( libSymbol )
114 {
115 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
116
117 // Use the full LIB_ID as the symbol name to prevent symbol name collisions.
118 flattenedSymbol->SetName( symbol->GetLibId().GetUniStringLibId() );
119
120 // AddSymbol() does first clone the symbol before adding.
121 archLib->AddSymbol( flattenedSymbol.get() );
122 }
123 else
124 {
125 tmp.Printf( _( "Symbol %s not found in any library or cache." ),
126 symbol->GetLibId().GetUniStringLibId() );
127 }
128
129 if( !tmp.empty() && !errorMsg.Contains( symbol->GetLibId().GetUniStringLibId() ) )
130 {
131 if( errorMsg.empty() )
132 errorMsg += tmp;
133 else
134 errorMsg += wxS( "\n" ) + tmp;
135 }
136 }
137 }
138
139 if( !errorMsg.empty() )
140 {
141 tmp.Printf( _( "Errors occurred creating symbol library %s." ), aFileName );
142 DisplayErrorMessage( this, tmp, errorMsg );
143 }
144
145 archLib->EnableBuffering( false );
146
147 try
148 {
149 archLib->Save( false );
150 }
151 catch( const IO_ERROR& ioe )
152 {
153 errorMsg.Printf( _( "Failed to save symbol library file '%s'." ), aFileName );
154 DisplayErrorMessage( this, errorMsg, ioe.What() );
155 return false;
156 }
157 catch( std::exception& error )
158 {
159 errorMsg.Printf( _( "Failed to save symbol library file '%s'." ), aFileName );
160 DisplayErrorMessage( this, errorMsg, error.what() );
161 return false;
162 }
163
164 return true;
165}
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
wxString GetUniStringLibId() const
Definition: lib_id.h:148
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:112
Define a library symbol object.
Definition: lib_symbol.h:99
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:456
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:120
LIB_SYMBOL * GetLibSymbol(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCHEMATIC & Schematic() const
bool CreateArchiveLibrary(const wxString &aFileName)
Create a library aFileName that contains all symbols used in the current schematic.
Definition: libarch.cpp:65
bool CreateArchiveLibraryCacheFile(bool aUseCurrentSheetFilename=false)
Create a symbol library file with the name of the root document plus the '-cache' suffix,...
Definition: libarch.cpp:42
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:656
SCH_SCREEN * GetNext()
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
SCH_SCREEN * GetFirst()
const wxString & GetFileName() const
Definition: sch_screen.h:144
Schematic symbol object.
Definition: sch_symbol.h:81
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:175
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:325
This file is part of the common library.
#define _(s)
const std::string LegacySymbolLibFileExtension
Definition for symbol library class.
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
Definition of file extensions used in Kicad.